• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

source-academy / js-slang / 5711447058

pending completion
5711447058

push

github

web-flow
Enable source module imports in stepper (#1453)

* Enable source module imports in stepper

* remove use of eta-reduction and fix object representation

* add test cases

---------

Co-authored-by: Martin Henz <henz@comp.nus.edu.sg>

3603 of 4773 branches covered (75.49%)

Branch coverage included in aggregate %.

183 of 183 new or added lines in 5 files covered. (100.0%)

10736 of 12526 relevant lines covered (85.71%)

101536.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.18
/src/utils/astCreator.ts
1
import * as es from 'estree'
2

3
import { AllowedDeclarations, BlockExpression, FunctionDeclarationExpression } from '../types'
4

5
export const getVariableDecarationName = (decl: es.VariableDeclaration) =>
68✔
6
  (decl.declarations[0].id as es.Identifier).name
17,649✔
7

8
export const locationDummyNode = (line: number, column: number, source: string | null) =>
68✔
9
  literal('Dummy', { start: { line, column }, end: { line, column }, source })
42,737,969✔
10

11
export const identifier = (name: string, loc?: es.SourceLocation | null): es.Identifier => ({
713,102✔
12
  type: 'Identifier',
13
  name,
14
  loc
15
})
16

17
export const literal = (
68✔
18
  value: string | number | boolean | null,
19
  loc?: es.SourceLocation | null
20
): es.Literal => ({
43,906,949✔
21
  type: 'Literal',
22
  value,
23
  loc
24
})
25

26
export const memberExpression = (
68✔
27
  object: es.Expression,
28
  property: string | number
29
): es.MemberExpression => ({
211,939✔
30
  type: 'MemberExpression',
31
  object,
32
  computed: typeof property === 'number',
33
  optional: false,
34
  property: typeof property === 'number' ? literal(property) : identifier(property)
211,939✔
35
})
36

37
export const declaration = (
68✔
38
  name: string,
39
  kind: AllowedDeclarations,
40
  init: es.Expression,
41
  loc?: es.SourceLocation | null
42
): es.VariableDeclaration => ({
107,733✔
43
  type: 'VariableDeclaration',
44
  declarations: [
45
    {
46
      type: 'VariableDeclarator',
47
      id: identifier(name),
48
      init
49
    }
50
  ],
51
  kind,
52
  loc
53
})
54

55
export const constantDeclaration = (
68✔
56
  name: string,
57
  init: es.Expression,
58
  loc?: es.SourceLocation | null
59
) => declaration(name, 'const', init, loc)
12,529✔
60

61
export const callExpression = (
68✔
62
  callee: es.Expression,
63
  args: es.Expression[],
64
  loc?: es.SourceLocation | null
65
): es.CallExpression => ({
211,214✔
66
  type: 'CallExpression',
67
  callee,
68
  arguments: args,
69
  optional: false,
70
  loc
71
})
72

73
export const expressionStatement = (expression: es.Expression): es.ExpressionStatement => ({
11,193✔
74
  type: 'ExpressionStatement',
75
  expression
76
})
77

78
export const blockArrowFunction = (
68✔
79
  params: es.Identifier[],
80
  body: es.Statement[] | es.BlockStatement | es.Expression,
81
  loc?: es.SourceLocation | null
82
): es.ArrowFunctionExpression => ({
17,463✔
83
  type: 'ArrowFunctionExpression',
84
  expression: false,
85
  generator: false,
86
  params,
87
  body: Array.isArray(body) ? blockStatement(body) : body,
17,463!
88
  loc
89
})
90

91
export const functionExpression = (
68✔
92
  params: es.Pattern[],
93
  body: es.Statement[] | es.BlockStatement,
94
  loc?: es.SourceLocation | null,
95
  id?: es.Identifier
96
): es.FunctionExpression => ({
×
97
  type: 'FunctionExpression',
98
  id: id ?? null,
×
99
  async: false,
100
  generator: false,
101
  params,
102
  body: Array.isArray(body) ? blockStatement(body) : body,
×
103
  loc
104
})
105

106
export const blockStatement = (
68✔
107
  body: es.Statement[],
108
  loc?: es.SourceLocation | null
109
): es.BlockStatement => ({
14,458✔
110
  type: 'BlockStatement',
111
  body,
112
  loc
113
})
114

115
export const program = (body: es.Statement[]): es.Program => ({
6,338✔
116
  type: 'Program',
117
  sourceType: 'module',
118
  body
119
})
120

121
export const returnStatement = (
68✔
122
  argument: es.Expression,
123
  loc?: es.SourceLocation | null
124
): es.ReturnStatement => ({
9,516✔
125
  type: 'ReturnStatement',
126
  argument,
127
  loc
128
})
129

130
export const property = (key: string, value: es.Expression): es.Property => ({
180,203✔
131
  type: 'Property',
132
  method: false,
133
  shorthand: false,
134
  computed: false,
135
  key: identifier(key),
136
  value,
137
  kind: 'init'
138
})
139

140
export const objectExpression = (properties: es.Property[]): es.ObjectExpression => ({
35,439✔
141
  type: 'ObjectExpression',
142
  properties
143
})
144

145
export const mutateToCallExpression = (
68✔
146
  node: es.Node,
147
  callee: es.Expression,
148
  args: es.Expression[]
149
) => {
150
  node.type = 'CallExpression'
52,349✔
151
  node = node as es.CallExpression
52,349✔
152
  node.callee = callee
52,349✔
153
  node.arguments = args
52,349✔
154
}
155

156
export const mutateToAssignmentExpression = (
68✔
157
  node: es.Node,
158
  left: es.Pattern,
159
  right: es.Expression
160
) => {
161
  node.type = 'AssignmentExpression'
×
162
  node = node as es.AssignmentExpression
×
163
  node.operator = '='
×
164
  node.left = left
×
165
  node.right = right
×
166
}
167

168
export const mutateToExpressionStatement = (node: es.Node, expr: es.Expression) => {
68✔
169
  node.type = 'ExpressionStatement'
17✔
170
  node = node as es.ExpressionStatement
17✔
171
  node.expression = expr
17✔
172
}
173

174
export const mutateToReturnStatement = (node: es.Node, expr: es.Expression) => {
68✔
175
  node.type = 'ReturnStatement'
523✔
176
  node = node as es.ReturnStatement
523✔
177
  node.argument = expr
523✔
178
}
179

180
export const mutateToMemberExpression = (
68✔
181
  node: es.Node,
182
  obj: es.Expression,
183
  prop: es.Expression
184
) => {
185
  node.type = 'MemberExpression'
×
186
  node = node as es.MemberExpression
×
187
  node.object = obj
×
188
  node.property = prop
×
189
  node.computed = false
×
190
}
191

192
export const logicalExpression = (
68✔
193
  operator: es.LogicalOperator,
194
  left: es.Expression,
195
  right: es.Expression,
196
  loc?: es.SourceLocation | null
197
): es.LogicalExpression => ({
2,610✔
198
  type: 'LogicalExpression',
199
  operator,
200
  left,
201
  right,
202
  loc
203
})
204

205
export const mutateToConditionalExpression = (
68✔
206
  node: es.Node,
207
  test: es.Expression,
208
  consequent: es.Expression,
209
  alternate: es.Expression
210
) => {
211
  node.type = 'ConditionalExpression'
377✔
212
  node = node as es.ConditionalExpression
377✔
213
  node.test = test
377✔
214
  node.consequent = consequent
377✔
215
  node.alternate = alternate
377✔
216
}
217

218
export const conditionalExpression = (
68✔
219
  test: es.Expression,
220
  consequent: es.Expression,
221
  alternate: es.Expression,
222
  loc?: es.SourceLocation | null
223
): es.ConditionalExpression => ({
36,953✔
224
  type: 'ConditionalExpression',
225
  test,
226
  consequent,
227
  alternate,
228
  loc
229
})
230

231
export const arrayExpression = (elements: es.Expression[]): es.ArrayExpression => ({
36,802✔
232
  type: 'ArrayExpression',
233
  elements
234
})
235

236
export const assignmentExpression = (
68✔
237
  left: es.Identifier | es.MemberExpression,
238
  right: es.Expression,
239
  loc?: es.SourceLocation | null
240
): es.AssignmentExpression => ({
1,402✔
241
  type: 'AssignmentExpression',
242
  operator: '=',
243
  left,
244
  right,
245
  loc
246
})
247

248
export const binaryExpression = (
68✔
249
  operator: es.BinaryOperator,
250
  left: es.Expression,
251
  right: es.Expression,
252
  loc?: es.SourceLocation | null
253
): es.BinaryExpression => ({
136,400✔
254
  type: 'BinaryExpression',
255
  operator,
256
  left,
257
  right,
258
  loc
259
})
260

261
export const unaryExpression = (
68✔
262
  operator: es.UnaryOperator,
263
  argument: es.Expression,
264
  loc?: es.SourceLocation | null
265
): es.UnaryExpression => ({
102✔
266
  type: 'UnaryExpression',
267
  operator,
268
  prefix: true,
269
  argument,
270
  loc
271
})
272

273
// primitive: undefined is a possible value
274
export const primitive = (value: any): es.Expression => {
68✔
275
  return value === undefined ? identifier('undefined') : literal(value)
527,069✔
276
}
277

278
export const functionDeclarationExpression = (
68✔
279
  id: es.Identifier,
280
  params: es.Pattern[],
281
  body: es.BlockStatement,
282
  loc?: es.SourceLocation | null
283
): FunctionDeclarationExpression => ({
1,903✔
284
  type: 'FunctionExpression',
285
  id,
286
  params,
287
  body,
288
  loc
289
})
290

291
export const functionDeclaration = (
68✔
292
  id: es.Identifier | null,
293
  params: es.Pattern[],
294
  body: es.BlockStatement,
295
  loc?: es.SourceLocation | null
296
): es.FunctionDeclaration => ({
4,347✔
297
  type: 'FunctionDeclaration',
298
  id,
299
  params,
300
  body,
301
  loc
302
})
303

304
export const blockExpression = (
68✔
305
  body: es.Statement[],
306
  loc?: es.SourceLocation | null
307
): BlockExpression => ({
307✔
308
  type: 'BlockExpression',
309
  body,
310
  loc
311
})
312

313
export const arrowFunctionExpression = (
68✔
314
  params: es.Pattern[],
315
  body: es.Expression | es.BlockStatement,
316
  loc?: es.SourceLocation | null
317
): es.ArrowFunctionExpression => ({
22,066✔
318
  type: 'ArrowFunctionExpression',
319
  expression: body.type !== 'BlockStatement',
320
  generator: false,
321
  params,
322
  body,
323
  loc
324
})
325

326
export const variableDeclaration = (
68✔
327
  declarations: es.VariableDeclarator[],
328
  loc?: es.SourceLocation | null
329
): es.VariableDeclaration => ({
3,085✔
330
  type: 'VariableDeclaration',
331
  kind: 'const',
332
  declarations,
333
  loc
334
})
335

336
export const variableDeclarator = (
68✔
337
  id: es.Pattern,
338
  init: es.Expression,
339
  loc?: es.SourceLocation | null
340
): es.VariableDeclarator => ({
3,086✔
341
  type: 'VariableDeclarator',
342
  id,
343
  init,
344
  loc
345
})
346

347
export const ifStatement = (
68✔
348
  test: es.Expression,
349
  consequent: es.BlockStatement,
350
  alternate: es.Statement,
351
  loc?: es.SourceLocation | null
352
): es.IfStatement => ({
883✔
353
  type: 'IfStatement',
354
  test,
355
  consequent,
356
  alternate,
357
  loc
358
})
359

360
export const whileStatement = (
68✔
361
  body: es.BlockStatement,
362
  test: es.Expression,
363
  loc?: es.SourceLocation | null
364
): es.WhileStatement => ({
9✔
365
  type: 'WhileStatement',
366
  test,
367
  body,
368
  loc
369
})
370

371
export const forStatement = (
68✔
372
  init: es.VariableDeclaration | es.Expression,
373
  test: es.Expression,
374
  update: es.Expression,
375
  body: es.Statement,
376
  loc?: es.SourceLocation | null
377
): es.ForStatement => ({
5✔
378
  type: 'ForStatement',
379
  init,
380
  test,
381
  update,
382
  body,
383
  loc
384
})
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc