1
1
import { Annotation , CodeGroup , Defn , Expr , FunctionArg , MatchPattern , Path , Rust , Type , Val } from '../../src/rust' ;
2
2
import { cws } from '../../testHelpers/cws' ;
3
- import { CWScriptCodegen } from '../../src/codegen/codegen' ;
3
+ import { CWScriptCodegen , Source } from '../../src/codegen/codegen' ;
4
+ import { ContractDefn , Ident , InstantiateDefn , List , SourceFile } from '../../src/ast/nodes' ;
5
+
6
+ expect . extend ( {
7
+ toContainRust ( received : Rust [ ] , prop : any , value : String ) {
8
+ if ( ! received . find ( x => x [ prop ] === value ) ) {
9
+ return {
10
+ pass : false ,
11
+ message : ( ) => `Node did not contain item with property ${ prop } and value ${ value } `
12
+ } ;
13
+ }
14
+ return {
15
+ pass : true ,
16
+ message : ( ) => `Node contains item with property ${ prop } and value ${ value } `
17
+ } ;
18
+ } ,
19
+ toContainUse ( received , value ) {
20
+ if ( getItemsOfType ( received . items , 'Use' ) . find ( x => x [ 'path' ] === value ) ) {
21
+ return {
22
+ pass : true ,
23
+ message : ( ) => `Found 'Use' with value ${ value } `
24
+ } ;
25
+ }
26
+ return {
27
+ pass : false ,
28
+ message : ( ) => `Did not find 'Use' with value ${ value } `
29
+ }
30
+ } ,
31
+ toContainAnnotation ( received , value ) {
32
+ if ( getItemsOfType ( received . annotations , 'Annotation' ) . find ( x => x [ 'value' ] === value ) ) {
33
+ return {
34
+ pass : true ,
35
+ message : ( ) => `Found 'Annotation' with value ${ value } `
36
+ } ;
37
+ }
38
+ return {
39
+ pass : false ,
40
+ message : ( ) => `Did not find 'Annotation' with value ${ value } `
41
+ }
42
+ }
43
+ } ) ;
44
+
45
+ function getItemsOfType ( received : Rust [ ] , type : string ) {
46
+ return received . filter ( x => x . constructor . name === type ) ;
47
+ }
48
+
49
+ function findItem < T extends Rust > ( items : Rust [ ] , prop : string , value : string ) {
50
+ return items . find ( x => x [ prop ] === value ) as T ;
51
+ }
4
52
5
53
describe ( 'ast compiler' , ( ) => {
6
54
it ( 'compiles an empty contract with empty instantiate' , ( ) => {
7
55
// arrange
8
- const ast = cws `
9
- contract CWTemplate {
10
- instantiate() {}
11
- }` ;
56
+ const ast = new SourceFile (
57
+ undefined ,
58
+ undefined ,
59
+ new List (
60
+ undefined ,
61
+ [ new ContractDefn (
62
+ undefined ,
63
+ undefined ,
64
+ new Ident ( undefined , 'CWTemplate' ) ,
65
+ new List ( undefined , [ new InstantiateDefn ( undefined , undefined , new Ident ( undefined , 'instantiate' ) , new List ( undefined , [ ] ) , undefined , new List ( undefined , [ ] ) ) ] ) ,
66
+ undefined ,
67
+ undefined
68
+ ) ]
69
+ )
70
+ ) ;
71
+ const codegen = new CWScriptCodegen ( [ { file : '/dev/null' , ast } ] ) ;
12
72
13
73
// act
14
- const codegen = new CWScriptCodegen ( [ { file : '/dev/null' , ast } ] ) ;
15
74
const rust = codegen . generateContract ( 'CWTemplate' , '/dev/null' ) ;
16
75
17
76
// assert
18
- const msg = findItem < CodeGroup > ( rust . items , 'name' , 'msg' ) ;
19
- expect ( msg ) . toBeDefined ( ) ;
20
- expect ( msg . items ) . toHaveLength ( 5 ) ;
21
-
22
- const msg_use1 = findItem < Defn . Use > ( msg . items , 'path' , 'schemars::JsonSchema' ) ;
23
- expect ( msg_use1 ) . toBeDefined ( ) ;
24
- expect ( msg_use1 . annotations ) . toHaveLength ( 0 ) ;
25
77
26
- const msg_use2 = findItem < Defn . Use > ( msg . items , 'path' , 'serde::{Serialize, Deserialize}' ) ;
27
- expect ( msg_use2 ) . toBeDefined ( ) ;
28
- expect ( msg_use2 . annotations ) . toHaveLength ( 0 ) ;
78
+ /*
79
+
80
+ {
81
+ "codeGroup": [{
82
+ name: "msg",
83
+ uses:[
84
+ { path: "schemars::JsonSchema" },
85
+ { path: "serde::{Serialize, Deserialize}'" }
86
+ ],
87
+ structs: [
88
+ {
89
+ name: "InstantiateMsg",
90
+ annotations: [
91
+ { value: "derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)"}
92
+ ]
93
+ }
94
+ ]
95
+ }]
96
+ }
97
+
98
+
99
+ */
100
+
101
+ console . log ( rust . toRustString ( ) )
102
+
103
+
104
+ // // -- begin contract CWTemplate
105
+ // pub mod types { use schemars::JsonSchema;
106
+ // use serde::{Serialize, Deserialize}; }
107
+ const types = findItem < CodeGroup > ( rust . items , 'name' , 'types' ) ;
108
+ expect ( types ) . toContainUse ( 'schemars::JsonSchema' ) ;
109
+ expect ( types ) . toContainUse ( 'serde::{Serialize, Deserialize}' ) ;
110
+
111
+ // pub mod error { #[derive(thiserror::Error, Debug)] pub enum ContractError { #[error("{0}")] Std(#[from] cosmwasm_std::StdError) } }
112
+ const error = findItem < CodeGroup > ( rust . items , 'name' , 'error' ) ;
113
+ expect ( error . items ) . toHaveLength ( 1 ) ;
114
+
115
+ // pub mod state { }
116
+ const state = findItem < CodeGroup > ( rust . items , 'name' , 'state' ) ;
117
+ expect ( state . items ) . toHaveLength ( 0 ) ;
118
+
119
+ // pub mod msg { use schemars::JsonSchema;
120
+ // use serde::{Serialize, Deserialize};
121
+ const msg = findItem < CodeGroup > ( rust . items , 'name' , 'msg' ) ;
122
+ expect ( msg ) . toContainUse ( 'schemars::JsonSchema' ) ;
123
+ expect ( msg ) . toContainUse ( 'serde::{Serialize, Deserialize}' ) ;
29
124
125
+ // #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
126
+ // pub struct InstantiateMsg { }
30
127
const msg_struct = findItem < Defn . Struct > ( msg . items , 'name' , 'InstantiateMsg' ) ;
31
- expect ( msg_struct ) . toBeDefined ( ) ;
32
- expect ( msg_struct . members ) . toHaveLength ( 0 ) ;
33
- expect ( msg_struct . annotations ) . toHaveLength ( 1 ) ;
34
- expectToFind < Annotation > ( msg_struct . annotations , 'value' , 'derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)' ) ;
128
+ expect ( msg_struct ) . toContainAnnotation ( 'derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)' ) ;
35
129
36
130
const msg_executeMsg = findItem < Defn . Enum > ( msg . items , 'name' , 'ExecuteMsg' ) ;
37
- expect ( msg_executeMsg ) . toBeDefined ( ) ;
38
- expect ( msg_executeMsg . annotations ) . toHaveLength ( 2 ) ;
39
- expectToFind < Annotation > ( msg_executeMsg . annotations , 'value' , 'derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)' ) ;
40
- expectToFind < Annotation > ( msg_executeMsg . annotations , 'value' , 'serde(rename_all = "snake_case")' ) ;
41
- expect ( msg_executeMsg . variants ) . toHaveLength ( 0 ) ;
131
+ expect ( msg_executeMsg ) . toContainAnnotation ( 'derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)' ) ;
132
+ expect ( msg_executeMsg ) . toContainAnnotation ( 'serde(rename_all = "snake_case")' ) ;
133
+
134
+ const msg_queryMsg = findItem < Defn . Enum > ( msg . items , 'name' , 'ExecuteMsg' ) ;
135
+ expect ( msg_queryMsg ) . toContainAnnotation ( 'derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)' ) ;
136
+ expect ( msg_queryMsg ) . toContainAnnotation ( 'serde(rename_all = "snake_case")' ) ;
42
137
43
138
const contract = findItem < CodeGroup > ( rust . items , 'name' , 'contract' ) ;
44
- expect ( contract ) . toBeDefined ( ) ;
45
- expect ( contract . items ) . toHaveLength ( 7 ) ;
139
+ expect ( contract ) . toContainUse ( 'crate::error::ContractError' ) ;
140
+ expect ( contract . items . length ) . toBeGreaterThanOrEqual ( 7 ) ;
46
141
47
- const contract_use1 = findItem < Defn . Use > ( contract . items , 'path' , 'crate::error::ContractError' ) ;
48
- expect ( contract_use1 ) . toBeDefined ( ) ;
49
- expect ( contract_use1 . annotations ) . toHaveLength ( 0 ) ;
50
142
51
143
const contract_use2 = findItem < Defn . Use > ( contract . items , 'path' , 'cosmwasm_std::entry_point' ) ;
52
- expect ( contract_use2 ) . toBeDefined ( ) ;
53
- expect ( contract_use2 . annotations ) . toHaveLength ( 1 ) ;
54
- expectToFind < Annotation > ( contract_use2 . annotations , 'value' , 'cfg(not(feature = "library"))' ) ;
144
+ expect ( contract_use2 ) . toContainAnnotation ( 'cfg(not(feature = "library"))' ) ;
55
145
56
- const contract_use3 = findItem < Defn . Use > ( contract . items , 'path' , 'cosmwasm_std::{to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}' ) ;
57
- expect ( contract_use3 ) . toBeDefined ( ) ;
58
- expect ( contract_use3 . annotations ) . toHaveLength ( 0 ) ;
146
+ expect ( contract ) . toContainUse ( 'cosmwasm_std::{to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}' ) ;
59
147
60
148
const contract_instantiate = findItem < Defn . Function > ( contract . items , 'name' , 'instantiate' ) ;
61
- expect ( contract_instantiate ) . toBeDefined ( ) ;
62
- expectToFind < Annotation > ( contract_instantiate . annotations , 'value' , `cfg_attr(not(feature = "library"), entry_point)` ) ;
149
+ expect ( contract_instantiate ) . toContainAnnotation ( `cfg_attr(not(feature = "library"), entry_point)` ) ;
63
150
expect ( contract_instantiate . body ) . toBeDefined ( ) ;
64
151
expect ( contract_instantiate . args ) . toBeDefined ( ) ;
65
152
expect ( contract_instantiate . args ) . toHaveLength ( 4 ) ;
66
153
67
154
const contract_instantiate_depsArg = contract_instantiate . args . find ( ( x : FunctionArg ) => x . name === '__deps' ) ;
68
- expect ( contract_instantiate_depsArg ) . toBeDefined ( ) ;
69
155
expect ( contract_instantiate_depsArg . type . path ) . toBe ( 'cosmwasm_std::DepsMut' ) ;
70
156
71
157
const contract_instantiate_envArg = contract_instantiate . args . find ( ( x : FunctionArg ) => x . name === '__env' ) ;
72
- expect ( contract_instantiate_envArg ) . toBeDefined ( ) ;
73
158
expect ( contract_instantiate_envArg . type . path ) . toBe ( 'cosmwasm_std::Env' ) ;
74
159
75
160
const contract_instantiate_infoArg = contract_instantiate . args . find ( ( x : FunctionArg ) => x . name === '__info' ) ;
76
- expect ( contract_instantiate_infoArg ) . toBeDefined ( ) ;
77
161
expect ( contract_instantiate_infoArg . type . path ) . toBe ( 'cosmwasm_std::MessageInfo' ) ;
78
162
79
163
const contract_instantiate_msgArg = contract_instantiate . args . find ( ( x : FunctionArg ) => x . name === '__msg' ) ;
80
- expect ( contract_instantiate_msgArg ) . toBeDefined ( ) ;
81
164
expect ( contract_instantiate_msgArg . type . path ) . toBe ( 'crate::msg::InstantiateMsg' ) ;
82
165
83
166
const contract_Instantiate_ReturnType = contract_instantiate . returnType ;
84
- expect ( contract_Instantiate_ReturnType ) . toBeDefined ( ) ;
85
167
expect ( contract_Instantiate_ReturnType . path ) . toBe ( '::std::result::Result' ) ;
86
- expectToFind < Type > ( contract_Instantiate_ReturnType . typeParams , 'path' , 'cosmwasm_std::Response' ) ;
87
- expectToFind < Type > ( contract_Instantiate_ReturnType . typeParams , 'path' , 'crate::error::ContractError' ) ;
168
+ expect ( contract_Instantiate_ReturnType . typeParams ) . toContainRust ( 'path' , 'cosmwasm_std::Response' ) ;
169
+ expect ( contract_Instantiate_ReturnType . typeParams ) . toContainRust ( 'path' , 'crate::error::ContractError' ) ;
88
170
89
171
const contract_instantiate_fnCall = findItem < Expr . FnCall > ( contract_instantiate . body , 'path' , 'instantiate_impl' ) ;
90
172
expect ( contract_instantiate_fnCall ) . toBeDefined ( ) ;
91
173
expect ( contract_instantiate_fnCall . typeParams ) . toHaveLength ( 0 ) ;
92
174
expect ( contract_instantiate_fnCall . args ) . toHaveLength ( 3 ) ;
93
- expectToFind < Path > ( contract_instantiate_fnCall . args , 'path' , '__deps' ) ;
94
- expectToFind < Path > ( contract_instantiate_fnCall . args , 'path' , '__env' ) ;
95
- expectToFind < Path > ( contract_instantiate_fnCall . args , 'path' , '__info' ) ;
175
+ expect ( contract_instantiate_fnCall . args ) . toContainRust ( 'path' , '__deps' ) ;
176
+ expect ( contract_instantiate_fnCall . args ) . toContainRust ( 'path' , '__env' ) ;
177
+ expect ( contract_instantiate_fnCall . args ) . toContainRust ( 'path' , '__info' ) ;
96
178
97
179
const contract_instantiateImpl = findItem < Defn . Function > ( contract . items , 'name' , 'instantiate_impl' ) ;
98
180
expect ( contract_instantiateImpl ) . toBeDefined ( ) ;
@@ -111,10 +193,6 @@ describe('ast compiler', () => {
111
193
const contract_instantiateImpl_infoArg = contract_instantiateImpl . args . find ( ( x : FunctionArg ) => x . name === '__info' ) ;
112
194
expect ( contract_instantiateImpl_infoArg ) . toBeDefined ( ) ;
113
195
expect ( contract_instantiateImpl_infoArg . type . path ) . toBe ( 'cosmwasm_std::MessageInfo' ) ;
114
-
115
- // ToDo: rest of instantiate_impl stuff
116
-
117
- // ToDo: execute, query
118
196
} ) ;
119
197
120
198
it ( 'compiles a contract with an execute message' , ( ) => {
@@ -160,8 +238,8 @@ describe('ast compiler', () => {
160
238
const msg_executeMsg_bazStruct_queryMsg = findItem < Defn . Enum > ( msg . items , 'name' , 'QueryMsg' ) ;
161
239
expect ( msg_executeMsg_bazStruct_queryMsg ) . toBeDefined ( ) ;
162
240
expect ( msg_executeMsg_bazStruct_queryMsg . annotations ) . toHaveLength ( 2 ) ;
163
- expectToFind < Annotation > ( msg_executeMsg_bazStruct_queryMsg . annotations , 'value' , 'derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)' ) ;
164
- expectToFind < Annotation > ( msg_executeMsg_bazStruct_queryMsg . annotations , 'value' , 'serde(rename_all = "snake_case")' ) ;
241
+ expect ( msg_executeMsg_bazStruct_queryMsg . annotations ) . toContainRust ( 'value' , 'derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)' ) ;
242
+ expect ( msg_executeMsg_bazStruct_queryMsg . annotations ) . toContainRust ( 'value' , 'serde(rename_all = "snake_case")' ) ;
165
243
expect ( msg_executeMsg_bazStruct_queryMsg . variants ) . toHaveLength ( 0 ) ;
166
244
167
245
const contract = findItem < CodeGroup > ( rust . items , 'name' , 'contract' ) ;
@@ -170,7 +248,7 @@ describe('ast compiler', () => {
170
248
171
249
const contract_execute = findItem < Defn . Function > ( contract . items , 'name' , 'execute' ) ;
172
250
expect ( contract_execute ) . toBeDefined ( ) ;
173
- expectToFind < Annotation > ( contract_execute . annotations , 'value' , `cfg_attr(not(feature = "library"), entry_point)` ) ;
251
+ expect ( contract_execute . annotations ) . toContainRust ( 'value' , `cfg_attr(not(feature = "library"), entry_point)` ) ;
174
252
expect ( contract_execute . body ) . toBeDefined ( ) ;
175
253
expect ( contract_execute . body ) . toHaveLength ( 1 ) ;
176
254
expect ( contract_execute . args ) . toBeDefined ( ) ;
@@ -195,8 +273,8 @@ describe('ast compiler', () => {
195
273
const contract_execute_ReturnType = contract_execute . returnType ;
196
274
expect ( contract_execute_ReturnType ) . toBeDefined ( ) ;
197
275
expect ( contract_execute_ReturnType . path ) . toBe ( '::std::result::Result' ) ;
198
- expectToFind < Type > ( contract_execute_ReturnType . typeParams , 'path' , 'cosmwasm_std::Response' ) ;
199
- expectToFind < Type > ( contract_execute_ReturnType . typeParams , 'path' , 'crate::error::ContractError' ) ;
276
+ expect ( contract_execute_ReturnType . typeParams ) . toContainRust ( 'path' , 'cosmwasm_std::Response' ) ;
277
+ expect ( contract_execute_ReturnType . typeParams ) . toContainRust ( 'path' , 'crate::error::ContractError' ) ;
200
278
201
279
const contract_execute_match = contract_execute . body [ 0 ] as Expr . Match ;
202
280
expect ( contract_execute_match ) . toBeDefined ( ) ;
@@ -215,10 +293,10 @@ describe('ast compiler', () => {
215
293
expect ( contract_execute_match_pattern_expr . typeParams ) . toHaveLength ( 0 ) ;
216
294
expect ( contract_execute_match_pattern_expr . path ) . toBe ( 'exec_baz' ) ;
217
295
expect ( contract_execute_match_pattern_expr . args ) . toHaveLength ( 4 ) ;
218
- expectToFind < Path > ( contract_execute_match_pattern_expr . args , 'path' , '__deps' ) ;
219
- expectToFind < Path > ( contract_execute_match_pattern_expr . args , 'path' , '__env' ) ;
220
- expectToFind < Path > ( contract_execute_match_pattern_expr . args , 'path' , '__info' ) ;
221
- expectToFind < Path > ( contract_execute_match_pattern_expr . args , 'path' , 'remote_contract' ) ;
296
+ expect ( contract_execute_match_pattern_expr . args ) . toContainRust ( 'path' , '__deps' ) ;
297
+ expect ( contract_execute_match_pattern_expr . args ) . toContainRust ( 'path' , '__env' ) ;
298
+ expect ( contract_execute_match_pattern_expr . args ) . toContainRust ( 'path' , '__info' ) ;
299
+ expect ( contract_execute_match_pattern_expr . args ) . toContainRust ( 'path' , 'remote_contract' ) ;
222
300
223
301
const contract_execBaz = findItem < Defn . Function > ( contract . items , 'name' , 'exec_baz' ) ;
224
302
expect ( contract_execBaz ) . toBeDefined ( ) ;
@@ -247,8 +325,8 @@ describe('ast compiler', () => {
247
325
const contract_execBaz_ReturnType = contract_execBaz . returnType ;
248
326
expect ( contract_execBaz_ReturnType ) . toBeDefined ( ) ;
249
327
expect ( contract_execBaz_ReturnType . path ) . toBe ( '::std::result::Result' ) ;
250
- expectToFind < Type > ( contract_execBaz_ReturnType . typeParams , 'path' , 'cosmwasm_std::Response' ) ;
251
- expectToFind < Type > ( contract_execBaz_ReturnType . typeParams , 'path' , 'crate::error::ContractError' ) ;
328
+ expect ( contract_execBaz_ReturnType . typeParams ) . toContainRust ( 'path' , 'cosmwasm_std::Response' ) ;
329
+ expect ( contract_execBaz_ReturnType . typeParams ) . toContainRust ( 'path' , 'crate::error::ContractError' ) ;
252
330
253
331
const contract_execBaz_EventsLet = findItem < Defn . Let > ( contract_execBaz . body , 'ident' , '__events' ) ;
254
332
expect ( contract_execBaz_EventsLet ) . toBeDefined ( ) ;
@@ -272,13 +350,7 @@ describe('ast compiler', () => {
272
350
// ...
273
351
// Temp log statements
274
352
console . log ( contract_execBaz ) ;
275
- } ) ;
353
+ } ) ;
276
354
277
- function findItem < T extends Rust > ( items : Rust [ ] , prop : string , value : string ) {
278
- return items . find ( x => x [ prop ] === value ) as T ;
279
- }
280
355
281
- function expectToFind < T extends Rust > ( items : Rust [ ] , prop : string , value : string ) {
282
- expect ( findItem < T > ( items , prop , value ) ) . toBeDefined ( ) ;
283
- }
284
356
} ) ;
0 commit comments