Skip to content

Commit c773b92

Browse files
authored
Merge pull request #25 from Terran-One/feat/transactional
Transactional Storage
2 parents c6c2b41 + a6048e1 commit c773b92

File tree

7 files changed

+610
-398
lines changed

7 files changed

+610
-398
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@terran-one/cw-simulate",
3-
"version": "2.6.2",
3+
"version": "2.7.0",
44
"description": "Mock blockchain environment for simulating CosmWasm interactions",
55
"main": "dist/index.js",
66
"typings": "dist/index.d.ts",

src/CWSimulateApp.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,23 @@ import { Err, Result } from 'ts-results';
44
import { WasmModule, WasmQuery } from './modules/wasm';
55
import { BankModule, BankQuery } from './modules/bank';
66
import { AppResponse, Binary } from './types';
7+
import { Transactional, TransactionalLens } from './store/transactional';
78

89
export interface CWSimulateAppOptions {
910
chainId: string;
1011
bech32Prefix: string;
1112
}
1213

14+
export type ChainData = {
15+
height: number;
16+
time: number;
17+
}
18+
1319
export class CWSimulateApp {
1420
public chainId: string;
1521
public bech32Prefix: string;
1622

17-
public store: Map<string, any>;
18-
public height: number;
19-
public time: number;
23+
public store: TransactionalLens<ChainData>;
2024

2125
public wasm: WasmModule;
2226
public bank: BankModule;
@@ -25,9 +29,10 @@ export class CWSimulateApp {
2529
constructor(options: CWSimulateAppOptions) {
2630
this.chainId = options.chainId;
2731
this.bech32Prefix = options.bech32Prefix;
28-
this.store = Map<string, any>();
29-
this.height = 1;
30-
this.time = 0;
32+
this.store = new Transactional().lens<ChainData>().initialize({
33+
height: 1,
34+
time: 0,
35+
});
3136

3237
this.wasm = new WasmModule(this);
3338
this.bank = new BankModule(this);
@@ -47,6 +52,9 @@ export class CWSimulateApp {
4752
return Err(`unknown message: ${JSON.stringify(msg)}`);
4853
}
4954
}
55+
56+
get height() { return this.store.get('height') }
57+
get time() { return this.store.get('time') }
5058
}
5159

5260
export type QueryMessage =

src/modules/bank.spec.ts

Lines changed: 51 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { Map } from 'immutable';
1+
import { fromJS } from 'immutable';
22
import { cmd, exec, TestContract } from '../../testing/wasm-util';
33
import { CWSimulateApp } from '../CWSimulateApp';
44
import { fromBinary } from '../util';
5-
import { BankMessage, BankQuery, ParsedCoin } from './bank';
5+
import { BankMessage, BankQuery } from './bank';
66

77
type WrappedBankMessage = {
88
bank: BankMessage;
@@ -27,43 +27,43 @@ describe('BankModule', () => {
2727
bank.send('alice', 'bob', [{denom: 'foo', amount: '100'}]).unwrap();
2828

2929
// Assert
30-
expect(bank.getBalance('alice')).toEqual([new ParsedCoin('foo', BigInt(900))]);
31-
expect(bank.getBalance('bob')).toEqual([new ParsedCoin('foo', BigInt(100))]);
32-
expect(bank.getBalances()).toEqual(Map([
33-
['alice', [{denom: 'foo', amount: '900'}]],
34-
['bob', [{denom: 'foo', amount: '100'}]],
35-
]));
30+
expect(bank.getBalance('alice')).toEqual([coin('foo', 900)]);
31+
expect(bank.getBalance('bob')).toEqual([coin('foo', 100)]);
32+
expect(bank.getBalances()).toEqual(fromJS({
33+
alice: [coin('foo', 900)],
34+
bob: [coin('foo', 100)],
35+
}));
3636
});
3737

3838
it('handle send failure', () => {
3939
// Arrange
4040
const bank = chain.bank;
41-
bank.setBalance('alice', [{denom: 'foo', amount: '100'}]);
41+
bank.setBalance('alice', [coin('foo', 100)]);
4242

4343
// Act
44-
const res = bank.send('alice', 'bob', [{denom: 'foo', amount: '1000'}]);
44+
const res = bank.send('alice', 'bob', [coin('foo', 1000)]);
4545

4646
// Assert
4747
expect(res.err).toBeDefined();
48-
expect(bank.getBalances()).toEqual(Map([
49-
['alice', [{denom: 'foo', amount: '100'}]],
50-
]));
51-
expect(bank.getBalance('alice')).toEqual([new ParsedCoin('foo', BigInt(100))]);
48+
expect(bank.getBalances()).toEqual(fromJS({
49+
alice: [coin('foo', 100)],
50+
}));
51+
expect(bank.getBalance('alice')).toEqual([coin('foo', 100)]);
5252
});
5353

5454
it('handle burn', () => {
5555
// Arrange
5656
const bank = chain.bank;
57-
bank.setBalance('alice', [{denom: 'foo', amount: '1000'}]);
57+
bank.setBalance('alice', [coin('foo', 1000)]);
5858

5959
// Act
60-
bank.burn('alice', [{denom: 'foo', amount: '100'}]);
60+
bank.burn('alice', [coin('foo', 100)]);
6161

6262
// Assert
63-
expect(bank.getBalance('alice')).toEqual([new ParsedCoin('foo', BigInt(900))]);
64-
expect(bank.getBalances()).toEqual(Map([
65-
['alice', [{denom: 'foo', amount: '900'}]],
66-
]));
63+
expect(bank.getBalance('alice')).toEqual([coin('foo', 900)]);
64+
expect(bank.getBalances()).toEqual(fromJS({
65+
alice: [coin('foo', 900)],
66+
}));
6767
});
6868

6969
it('handle burn failure', () => {
@@ -76,16 +76,16 @@ describe('BankModule', () => {
7676

7777
// Assert
7878
expect(res.err).toBeDefined()
79-
expect(bank.getBalance('alice')).toEqual([new ParsedCoin('foo', BigInt(100))]);
80-
expect(bank.getBalances()).toEqual(Map([
81-
['alice', [{denom: 'foo', amount: '100'}]],
82-
]));
79+
expect(bank.getBalance('alice')).toEqual([coin('foo', 100)]);
80+
expect(bank.getBalances()).toEqual(fromJS({
81+
alice: [coin('foo', 100)],
82+
}));
8383
});
8484

8585
it('handle msg', () => {
8686
// Arrange
8787
const bank = chain.bank;
88-
bank.setBalance('alice', [{denom: 'foo', amount: '1000'}]);
88+
bank.setBalance('alice', [coin('foo', 1000)]);
8989

9090
// Act
9191
let msg: WrappedBankMessage = {
@@ -99,10 +99,10 @@ describe('BankModule', () => {
9999
chain.handleMsg('alice', msg);
100100

101101
// Assert
102-
expect(bank.getBalances()).toEqual(Map([
103-
['alice', [{denom: 'foo', amount: '900'}]],
104-
['bob', [{denom: 'foo', amount: '100'}]],
105-
]));
102+
expect(bank.getBalances()).toEqual(fromJS({
103+
alice: [coin('foo', 900)],
104+
bob: [coin('foo', 100)],
105+
}));
106106
});
107107

108108
it('contract integration', async () => {
@@ -116,30 +116,30 @@ describe('BankModule', () => {
116116
cmd.bank({
117117
send: {
118118
to_address: 'alice',
119-
amount: [{denom: 'foo', amount: '100'}],
119+
amount: [coin('foo', 100)],
120120
},
121121
}),
122122
cmd.bank({
123123
send: {
124124
to_address: 'bob',
125-
amount: [{denom: 'foo', amount: '100'}],
125+
amount: [coin('foo', 100)],
126126
},
127127
}),
128128
cmd.bank({
129129
burn: {
130-
amount: [{denom: 'foo', amount: '100'}],
130+
amount: [coin('foo', 100)],
131131
},
132132
}),
133133
);
134134
const res = await contract.execute('alice', msg);
135135

136136
// Assert
137137
expect(res.ok).toBeTruthy();
138-
expect(bank.getBalances()).toEqual(Map([
139-
[contract.address, [{denom: 'foo', amount: '700'}]],
140-
['alice', [{denom: 'foo', amount: '100'}]],
141-
['bob', [{denom: 'foo', amount: '100'}]],
142-
]));
138+
expect(bank.getBalances()).toEqual(fromJS({
139+
[contract.address]: [coin('foo', 700)],
140+
alice: [coin('foo', 100)],
141+
bob: [coin('foo', 100)],
142+
}));
143143
});
144144

145145
it('querier integration', () => {
@@ -159,28 +159,29 @@ describe('BankModule', () => {
159159
};
160160

161161
bank.setBalance('alice', [
162-
{ denom: 'foo', amount: '100' },
163-
{ denom: 'bar', amount: '200' },
162+
coin('foo', 100),
163+
coin('bar', 200),
164164
]);
165165
bank.setBalance('bob', [
166-
{ denom: 'foo', amount: '200' },
167-
{ denom: 'bar', amount: '200' },
166+
coin('foo', 200),
167+
coin('bar', 200),
168168
]);
169169

170170
let res = chain.querier.handleQuery({ bank: queryBalance });
171171
expect(res.ok).toBeTruthy();
172-
expect(fromBinary(res.val)).toEqual({ amount: { denom: 'foo', amount: '100' }});
172+
expect(fromBinary(res.val)).toEqual({ amount: coin('foo', 100)});
173173

174174
res = chain.querier.handleQuery({ bank: queryAllBalances });
175175
expect(res.ok).toBeTruthy();
176176
expect(fromBinary(res.val)).toEqual({
177177
amount: [
178-
{ denom: 'foo', amount: '200' },
179-
{ denom: 'bar', amount: '200' },
178+
coin('foo', 200),
179+
coin('bar', 200),
180180
],
181181
});
182182
});
183-
it('handle delete', () => {
183+
184+
it('handle delete', () => {
184185
// Arrange
185186
const bank = chain.bank;
186187
bank.setBalance('alice', [{denom: 'foo', amount: '1000'}]);
@@ -191,8 +192,10 @@ describe('BankModule', () => {
191192

192193
// Assert
193194
expect(bank.getBalance('alice')).toBeDefined();
194-
expect(bank.getBalances()).toEqual(Map([
195-
['alice', [{denom: 'foo', amount: '1000'}]]
196-
]));
195+
expect(bank.getBalances()).toEqual(fromJS({
196+
alice: [{denom: 'foo', amount: '1000'}],
197+
}));
197198
});
198199
});
200+
201+
const coin = (denom: string, amount: string | number) => ({ denom, amount: `${amount}` });

0 commit comments

Comments
 (0)