delorean_lang 0.5.1 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. checksums.yaml +5 -5
  2. data/.gitlab-ci.yml +1 -2
  3. data/.rubocop.yml +45 -5
  4. data/.rubocop_todo.yml +1 -634
  5. data/Gemfile +3 -1
  6. data/README.md +22 -0
  7. data/Rakefile +3 -1
  8. data/delorean.gemspec +18 -17
  9. data/lib/delorean/abstract_container.rb +4 -2
  10. data/lib/delorean/base.rb +30 -27
  11. data/lib/delorean/cache.rb +2 -0
  12. data/lib/delorean/cache/adapters.rb +2 -0
  13. data/lib/delorean/cache/adapters/base.rb +2 -0
  14. data/lib/delorean/cache/adapters/ruby_cache.rb +5 -0
  15. data/lib/delorean/const.rb +5 -3
  16. data/lib/delorean/debug.rb +6 -5
  17. data/lib/delorean/delorean.rb +466 -147
  18. data/lib/delorean/delorean.treetop +13 -1
  19. data/lib/delorean/engine.rb +61 -50
  20. data/lib/delorean/error.rb +2 -1
  21. data/lib/delorean/model.rb +12 -9
  22. data/lib/delorean/nodes.rb +130 -67
  23. data/lib/delorean/ruby.rb +2 -0
  24. data/lib/delorean/ruby/whitelists.rb +2 -0
  25. data/lib/delorean/ruby/whitelists/base.rb +7 -3
  26. data/lib/delorean/ruby/whitelists/default.rb +6 -6
  27. data/lib/delorean/ruby/whitelists/empty.rb +3 -2
  28. data/lib/delorean/ruby/whitelists/matchers.rb +2 -0
  29. data/lib/delorean/ruby/whitelists/matchers/arguments.rb +2 -0
  30. data/lib/delorean/ruby/whitelists/matchers/method.rb +5 -2
  31. data/lib/delorean/ruby/whitelists/whitelist_error.rb +2 -0
  32. data/lib/delorean/version.rb +3 -1
  33. data/lib/delorean_lang.rb +3 -1
  34. data/spec/cache_spec.rb +4 -2
  35. data/spec/dev_spec.rb +68 -69
  36. data/spec/eval_spec.rb +824 -729
  37. data/spec/func_spec.rb +172 -176
  38. data/spec/parse_spec.rb +516 -522
  39. data/spec/ruby/whitelist_spec.rb +6 -3
  40. data/spec/spec_helper.rb +26 -23
  41. metadata +27 -27
@@ -1,838 +1,832 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
4
 
3
- describe "Delorean" do
4
- let(:sset) {
5
+ describe 'Delorean' do
6
+ let(:sset) do
5
7
  TestContainer.new(
6
- "AAA" =>
7
- defn("X:",
8
- " a = 123",
9
- " b = a",
10
- )
11
- )
12
- }
8
+ 'AAA' =>
9
+ defn('X:',
10
+ ' a = 123',
11
+ ' b = a',
12
+ )
13
+ )
14
+ end
13
15
 
14
- let(:engine) {
15
- Delorean::Engine.new "YYY", sset
16
- }
16
+ let(:engine) do
17
+ Delorean::Engine.new 'YYY', sset
18
+ end
17
19
 
18
- it "can parse very simple calls" do
19
- engine.parse defn("X:",
20
- " a = 123",
21
- " b = a",
22
- )
20
+ it 'can parse very simple calls' do
21
+ engine.parse defn('X:',
22
+ ' a = 123',
23
+ ' b = a',
24
+ )
23
25
  end
24
26
 
25
- it "can parse simple expressions - 1" do
26
- engine.parse defn("A:",
27
- " a = 123",
28
- " x = -(a*2)",
29
- " b = -(a + 1)",
30
- )
27
+ it 'can parse simple expressions - 1' do
28
+ engine.parse defn('A:',
29
+ ' a = 123',
30
+ ' x = -(a*2)',
31
+ ' b = -(a + 1)',
32
+ )
31
33
  end
32
34
 
33
- it "can parse simple expressions - 2" do
34
- engine.parse defn("A:",
35
- " a = 1 + 2 * -3 - -4",
36
- )
35
+ it 'can parse simple expressions - 2' do
36
+ engine.parse defn('A:',
37
+ ' a = 1 + 2 * -3 - -4',
38
+ )
37
39
  end
38
40
 
39
- it "can parse params" do
40
- engine.parse defn("A:",
41
- " a =?",
42
- " b =? a*2",
43
- )
41
+ it 'can parse params' do
42
+ engine.parse defn('A:',
43
+ ' a =?',
44
+ ' b =? a*2',
45
+ )
44
46
  end
45
47
 
46
- it "can parse indexing" do
47
- engine.parse defn("A:",
48
- " b = [1,2,3][1]",
49
- )
48
+ it 'can parse indexing' do
49
+ engine.parse defn('A:',
50
+ ' b = [1,2,3][1]',
51
+ )
50
52
  end
51
53
 
52
- it "can parse indexing with getattr" do
53
- engine.parse defn("A:",
54
+ it 'can parse indexing with getattr' do
55
+ engine.parse defn('A:',
54
56
  " a = {'x': [1,2,3]}",
55
- " b = a.x[1]",
56
- )
57
+ ' b = a.x[1]',
58
+ )
57
59
  end
58
60
 
59
- it "should accept default param definitions" do
61
+ it 'should accept default param definitions' do
60
62
  lambda {
61
- engine.parse defn("A:",
62
- " a =? 0.0123",
63
- " b =? 0",
64
- " c =? -1.1",
65
- " d = b + c",
66
- )
63
+ engine.parse defn('A:',
64
+ ' a =? 0.0123',
65
+ ' b =? 0',
66
+ ' c =? -1.1',
67
+ ' d = b + c',
68
+ )
67
69
  }.should_not raise_error
68
70
  end
69
71
 
70
- it "gives errors with attrs not in node" do
72
+ it 'gives errors with attrs not in node' do
71
73
  lambda {
72
- engine.parse defn("a = 123",
73
- "b = a * 2",
74
- )
74
+ engine.parse defn('a = 123',
75
+ 'b = a * 2',
76
+ )
75
77
  }.should raise_error(Delorean::ParseError)
76
78
  end
77
79
 
78
- it "should disallow .<digits> literals" do
80
+ it 'should disallow .<digits> literals' do
79
81
  lambda {
80
- engine.parse defn("A:",
81
- " a = .123",
82
- )
82
+ engine.parse defn('A:',
83
+ ' a = .123',
84
+ )
83
85
  }.should raise_error(Delorean::ParseError)
84
86
  end
85
87
 
86
- it "should disallow leading 0s in numbers" do
88
+ it 'should disallow leading 0s in numbers' do
87
89
  lambda {
88
- engine.parse defn("A:",
89
- " a = 00.123",
90
- )
90
+ engine.parse defn('A:',
91
+ ' a = 00.123',
92
+ )
91
93
  }.should raise_error(Delorean::ParseError)
92
94
  end
93
95
 
94
- it "should disallow leading 0s in numbers (2)" do
96
+ it 'should disallow leading 0s in numbers (2)' do
95
97
  lambda {
96
- engine.parse defn("A:",
97
- " a = 0123",
98
- )
98
+ engine.parse defn('A:',
99
+ ' a = 0123',
100
+ )
99
101
  }.should raise_error(Delorean::ParseError)
100
102
  end
101
103
 
102
- it "should disallow bad attr names" do
104
+ it 'should disallow bad attr names' do
103
105
  lambda {
104
- engine.parse defn("A:",
105
- " B = 1",
106
- )
106
+ engine.parse defn('A:',
107
+ ' B = 1',
108
+ )
107
109
  }.should raise_error(Delorean::ParseError)
108
110
 
109
111
  engine.reset
110
112
 
111
113
  lambda {
112
- engine.parse defn("A:",
113
- " _b = 1",
114
- )
114
+ engine.parse defn('A:',
115
+ ' _b = 1',
116
+ )
115
117
  }.should raise_error(Delorean::ParseError)
116
118
  end
117
119
 
118
- it "should disallow bad node names" do
120
+ it 'should disallow bad node names' do
119
121
  lambda {
120
- engine.parse defn("a:",
121
- )
122
+ engine.parse defn('a:',
123
+ )
122
124
  }.should raise_error(Delorean::ParseError)
123
125
 
124
126
  engine.reset
125
127
 
126
128
  lambda {
127
- engine.parse defn("_A:",
128
- )
129
+ engine.parse defn('_A:',
130
+ )
129
131
  }.should raise_error(Delorean::ParseError)
130
132
  end
131
133
 
132
- it "should disallow recursion" do
134
+ it 'should disallow recursion' do
133
135
  lambda {
134
- engine.parse defn("A:",
135
- " a = 1",
136
- "B: A",
137
- " a = a + 1",
138
- )
136
+ engine.parse defn('A:',
137
+ ' a = 1',
138
+ 'B: A',
139
+ ' a = a + 1',
140
+ )
139
141
  }.should raise_error(Delorean::RecursionError)
140
142
 
141
143
  engine.reset
142
144
 
143
145
  lambda {
144
- engine.parse defn("A:",
145
- " a = 1",
146
- "B: A",
147
- " b = a",
148
- " a = b",
149
- )
146
+ engine.parse defn('A:',
147
+ ' a = 1',
148
+ 'B: A',
149
+ ' b = a',
150
+ ' a = b',
151
+ )
150
152
  }.should raise_error(Delorean::RecursionError)
151
-
152
153
  end
153
154
 
154
- it "should allow getattr in expressions" do
155
- engine.parse defn("A:",
156
- " a = 1",
157
- " b = A.a * A.a - A.a",
158
- )
155
+ it 'should allow getattr in expressions' do
156
+ engine.parse defn('A:',
157
+ ' a = 1',
158
+ ' b = A.a * A.a - A.a',
159
+ )
159
160
  end
160
161
 
161
- it "should allow in expressions" do
162
- engine.parse defn("A:",
163
- " int =? 1",
164
- " a = if int>1 then int*2 else int/2",
165
- " b = int in [1,2,3]",
166
- )
162
+ it 'should allow in expressions' do
163
+ engine.parse defn('A:',
164
+ ' int =? 1',
165
+ ' a = if int>1 then int*2 else int/2',
166
+ ' b = int in [1,2,3]',
167
+ )
167
168
  end
168
169
 
169
- it "should allow non-recursive code 1" do
170
+ it 'should allow non-recursive code 1' do
170
171
  # this is not a recursion error
171
- engine.parse defn("A:",
172
- " a = 1",
173
- " b = 2",
174
- "B: A",
175
- " a = A.b",
176
- " b = a",
177
- )
178
-
179
- end
180
-
181
- it "should allow non-recursive code 2" do
182
- engine.parse defn("A:",
183
- " a = 1",
184
- " b = 2",
185
- "B: A",
186
- " a = A.b",
187
- " b = A.b + B.a",
188
- )
189
- end
190
-
191
- it "should allow non-recursive code 3" do
192
- engine.parse defn("A:",
193
- " b = 2",
194
- " a = A.b + A.b",
195
- " c = a + b + a + b",
196
- )
197
- end
198
-
199
- it "should check for recursion with default params 1" do
200
- lambda {
201
- engine.parse defn("A:",
202
- " a =? a",
203
- )
172
+ engine.parse defn('A:',
173
+ ' a = 1',
174
+ ' b = 2',
175
+ 'B: A',
176
+ ' a = A.b',
177
+ ' b = a',
178
+ )
179
+ end
180
+
181
+ it 'should allow non-recursive code 2' do
182
+ engine.parse defn('A:',
183
+ ' a = 1',
184
+ ' b = 2',
185
+ 'B: A',
186
+ ' a = A.b',
187
+ ' b = A.b + B.a',
188
+ )
189
+ end
190
+
191
+ it 'should allow non-recursive code 3' do
192
+ engine.parse defn('A:',
193
+ ' b = 2',
194
+ ' a = A.b + A.b',
195
+ ' c = a + b + a + b',
196
+ )
197
+ end
198
+
199
+ it 'should check for recursion with default params 1' do
200
+ lambda {
201
+ engine.parse defn('A:',
202
+ ' a =? a',
203
+ )
204
204
  }.should raise_error(Delorean::UndefinedError)
205
205
  end
206
206
 
207
- it "should check for recursion with default params 2" do
207
+ it 'should check for recursion with default params 2' do
208
208
  lambda {
209
- engine.parse defn("A:",
210
- " a = 1",
211
- "B: A",
212
- " b =? a",
213
- " a =? b",
214
- )
209
+ engine.parse defn('A:',
210
+ ' a = 1',
211
+ 'B: A',
212
+ ' b =? a',
213
+ ' a =? b',
214
+ )
215
215
  }.should raise_error(Delorean::RecursionError)
216
216
  end
217
217
 
218
- it "gives errors for attrs defined more than once in a node" do
218
+ it 'gives errors for attrs defined more than once in a node' do
219
219
  lambda {
220
- engine.parse defn("B:",
221
- " b = 1 + 1",
222
- " b = 123",
223
- )
220
+ engine.parse defn('B:',
221
+ ' b = 1 + 1',
222
+ ' b = 123',
223
+ )
224
224
  }.should raise_error(Delorean::RedefinedError)
225
225
 
226
226
  engine.reset
227
227
 
228
228
  lambda {
229
- engine.parse defn("B:",
230
- " b =?",
231
- " b = 123",
232
- )
229
+ engine.parse defn('B:',
230
+ ' b =?',
231
+ ' b = 123',
232
+ )
233
233
  }.should raise_error(Delorean::RedefinedError)
234
234
 
235
235
  engine.reset
236
236
 
237
237
  lambda {
238
- engine.parse defn("B:",
239
- " b =? 22",
240
- " b = 123",
241
- )
238
+ engine.parse defn('B:',
239
+ ' b =? 22',
240
+ ' b = 123',
241
+ )
242
242
  }.should raise_error(Delorean::RedefinedError)
243
243
  end
244
244
 
245
- it "should raise error for nodes defined more than once" do
245
+ it 'should raise error for nodes defined more than once' do
246
246
  lambda {
247
- engine.parse defn("B:",
248
- " b =?",
249
- "B:",
250
- )
247
+ engine.parse defn('B:',
248
+ ' b =?',
249
+ 'B:',
250
+ )
251
251
  }.should raise_error(Delorean::RedefinedError)
252
252
 
253
253
  engine.reset
254
254
 
255
255
  lambda {
256
- engine.parse defn("B:",
257
- "A:",
258
- "B:",
259
- )
256
+ engine.parse defn('B:',
257
+ 'A:',
258
+ 'B:',
259
+ )
260
260
  }.should raise_error(Delorean::RedefinedError)
261
261
  end
262
262
 
263
- it "should not be valid to derive from undefined nodes" do
263
+ it 'should not be valid to derive from undefined nodes' do
264
264
  lambda {
265
- engine.parse defn("A: B",
266
- " a = 456 * 123",
267
- )
265
+ engine.parse defn('A: B',
266
+ ' a = 456 * 123',
267
+ )
268
268
  }.should raise_error(Delorean::UndefinedError)
269
269
  end
270
270
 
271
- it "should not be valid to use an undefined attr" do
271
+ it 'should not be valid to use an undefined attr' do
272
272
  lambda {
273
- engine.parse defn("A:",
274
- " a = 456 * 123",
275
- "B: A",
276
- " b = a",
277
- " c = d",
278
- )
273
+ engine.parse defn('A:',
274
+ ' a = 456 * 123',
275
+ 'B: A',
276
+ ' b = a',
277
+ ' c = d',
278
+ )
279
279
  }.should raise_error(Delorean::UndefinedError)
280
280
  end
281
281
 
282
- it "should not be possible to use a forward definition in hash" do
282
+ it 'should not be possible to use a forward definition in hash' do
283
283
  lambda {
284
- engine.parse defn("A:",
284
+ engine.parse defn('A:',
285
285
  " c = {'b': 1, 'd' : d}",
286
- " d = 789",
287
- )
286
+ ' d = 789',
287
+ )
288
288
  }.should raise_error(Delorean::UndefinedError)
289
289
  end
290
290
 
291
- it "should not be possible to use a forward definition in node call" do
291
+ it 'should not be possible to use a forward definition in node call' do
292
292
  lambda {
293
- engine.parse defn("A:",
294
- " c = A(b=1, d=d)",
295
- " d = 789",
296
- )
293
+ engine.parse defn('A:',
294
+ ' c = A(b=1, d=d)',
295
+ ' d = 789',
296
+ )
297
297
  }.should raise_error(Delorean::UndefinedError)
298
298
  end
299
299
 
300
- it "should not be possible to use a forward definition in array" do
300
+ it 'should not be possible to use a forward definition in array' do
301
301
  lambda {
302
- engine.parse defn("A:",
303
- " c = [123, 456, d]",
304
- " d = 789",
305
- )
302
+ engine.parse defn('A:',
303
+ ' c = [123, 456, d]',
304
+ ' d = 789',
305
+ )
306
306
  }.should raise_error(Delorean::UndefinedError)
307
307
  end
308
308
 
309
- it "should be able to use ruby keywords as identifier" do
309
+ it 'should be able to use ruby keywords as identifier' do
310
310
  lambda {
311
- engine.parse defn("A:",
312
- " in = 123",
313
- )
311
+ engine.parse defn('A:',
312
+ ' in = 123',
313
+ )
314
314
  }.should_not raise_error
315
315
 
316
316
  engine.reset
317
317
 
318
318
  lambda {
319
- engine.parse defn("B:",
320
- " in1 = 123",
321
- )
319
+ engine.parse defn('B:',
320
+ ' in1 = 123',
321
+ )
322
322
  }.should_not raise_error
323
323
 
324
324
  engine.reset
325
325
 
326
326
  lambda {
327
- engine.parse defn("C:",
328
- " ifx = 123",
329
- " elsey = ifx + 1",
330
- )
327
+ engine.parse defn('C:',
328
+ ' ifx = 123',
329
+ ' elsey = ifx + 1',
330
+ )
331
331
  }.should_not raise_error
332
332
 
333
333
  engine.reset
334
334
 
335
335
  lambda {
336
- engine.parse defn("D:",
337
- " true = false",
338
- )
336
+ engine.parse defn('D:',
337
+ ' true = false',
338
+ )
339
339
  }.should_not raise_error
340
340
 
341
341
  engine.reset
342
342
 
343
343
  lambda {
344
- engine.parse defn("E:",
345
- " a = 1",
346
- " return=a",
347
- )
344
+ engine.parse defn('E:',
345
+ ' a = 1',
346
+ ' return=a',
347
+ )
348
348
  }.should_not raise_error
349
349
 
350
350
  engine.reset
351
351
 
352
- skip "need to fix"
352
+ skip 'need to fix'
353
353
 
354
354
  lambda {
355
- engine.parse defn("D:",
356
- " true_1 = false",
357
- " false_1 = true_1",
358
- " nil_1 = false_1",
359
- )
355
+ engine.parse defn('D:',
356
+ ' true_1 = false',
357
+ ' false_1 = true_1',
358
+ ' nil_1 = false_1',
359
+ )
360
360
  }.should_not raise_error
361
361
 
362
362
  engine.reset
363
363
  end
364
364
 
365
- it "should parse calls followed by getattr" do
365
+ it 'should parse calls followed by getattr' do
366
366
  lambda {
367
- engine.parse defn("A:",
368
- " a = -1",
369
- " b = A().a",
370
- )
367
+ engine.parse defn('A:',
368
+ ' a = -1',
369
+ ' b = A().a',
370
+ )
371
371
  }.should_not raise_error
372
372
  end
373
373
 
374
- it "should be able to chain method calls on model functions" do
374
+ it 'should be able to chain method calls on model functions' do
375
375
  lambda {
376
- engine.parse defn("A:",
376
+ engine.parse defn('A:',
377
377
  " b = Dummy.i_just_met_you('CRJ', 123).name"
378
- )
378
+ )
379
379
  }.should_not raise_error
380
380
  end
381
381
 
382
- it "should be able to pass model class to model functions" do
382
+ it 'should be able to pass model class to model functions' do
383
383
  lambda {
384
- engine.parse defn("A:",
385
- " b = Dummy.i_just_met_you(Dummy, 1)"
386
- )
384
+ engine.parse defn('A:',
385
+ ' b = Dummy.i_just_met_you(Dummy, 1)'
386
+ )
387
387
  }.should_not raise_error
388
388
  end
389
389
 
390
- it "should be able to call class methods on ActiveRecord classes" do
391
- engine.parse defn("A:",
392
- " b = Dummy.call_me_maybe()",
393
- )
390
+ it 'should be able to call class methods on ActiveRecord classes' do
391
+ engine.parse defn('A:',
392
+ ' b = Dummy.call_me_maybe()',
393
+ )
394
394
  end
395
395
 
396
- it "should get exception on arg count to class method call" do
396
+ it 'should get exception on arg count to class method call' do
397
397
  lambda {
398
- engine.parse defn("A:",
398
+ engine.parse defn('A:',
399
399
  ' b = Dummy.i_just_met_you(1, 2, 3)',
400
- )
400
+ )
401
401
  }.should raise_error(Delorean::BadCallError)
402
402
  end
403
403
 
404
404
  it "shouldn't be able to call ActiveRecord methods without signature" do
405
405
  lambda {
406
- engine.parse defn("A:",
407
- " b = Dummy.this_is_crazy()",
408
- )
406
+ engine.parse defn('A:',
407
+ ' b = Dummy.this_is_crazy()',
408
+ )
409
409
  }.should raise_error(Delorean::UndefinedFunctionError)
410
410
  end
411
411
 
412
- it "should be able to call class methods on ActiveRecord classes in modules" do
413
- engine.parse defn("A:",
414
- " b = M::LittleDummy.heres_my_number(867, 5309)",
415
- )
412
+ it 'should be able to call class methods on ActiveRecord classes in modules' do
413
+ engine.parse defn('A:',
414
+ ' b = M::LittleDummy.heres_my_number(867, 5309)',
415
+ )
416
416
  end
417
417
 
418
- it "should be able to override parameters with attribute definitions" do
419
- engine.parse defn("A:",
420
- " b =? 22",
421
- "B: A",
422
- " b = 123",
423
- "C: B",
424
- " b =? 11",
425
- )
418
+ it 'should be able to override parameters with attribute definitions' do
419
+ engine.parse defn('A:',
420
+ ' b =? 22',
421
+ 'B: A',
422
+ ' b = 123',
423
+ 'C: B',
424
+ ' b =? 11',
425
+ )
426
426
  end
427
427
 
428
- it "should be able to access derived attrs" do
429
- engine.parse defn("A:",
430
- " b =? 22",
431
- "B: A",
432
- " c = b * 123",
433
- "C: B",
434
- " d =? c * b + 11",
435
- )
428
+ it 'should be able to access derived attrs' do
429
+ engine.parse defn('A:',
430
+ ' b =? 22',
431
+ 'B: A',
432
+ ' c = b * 123',
433
+ 'C: B',
434
+ ' d =? c * b + 11',
435
+ )
436
436
  end
437
437
 
438
- it "should not be able to access attrs not defined in ancestors" do
438
+ it 'should not be able to access attrs not defined in ancestors' do
439
439
  lambda {
440
- engine.parse defn("A:",
441
- " b =? 22",
442
- "B: A",
443
- " c = b * 123",
444
- "C: A",
445
- " d =? c * b + 11",
446
- )
440
+ engine.parse defn('A:',
441
+ ' b =? 22',
442
+ 'B: A',
443
+ ' c = b * 123',
444
+ 'C: A',
445
+ ' d =? c * b + 11',
446
+ )
447
447
  }.should raise_error(Delorean::UndefinedError)
448
448
  end
449
449
 
450
- it "should be able to access specific node attrs " do
451
- engine.parse defn("A:",
452
- " b = 123",
453
- " c = A.b",
454
- )
450
+ it 'should be able to access specific node attrs ' do
451
+ engine.parse defn('A:',
452
+ ' b = 123',
453
+ ' c = A.b',
454
+ )
455
455
 
456
456
  engine.reset
457
457
 
458
- engine.parse defn("A:",
459
- " b = 123",
460
- "B: A",
461
- " b = 111",
462
- " c = A.b * 123",
463
- " d = B.b",
464
- )
458
+ engine.parse defn('A:',
459
+ ' b = 123',
460
+ 'B: A',
461
+ ' b = 111',
462
+ ' c = A.b * 123',
463
+ ' d = B.b',
464
+ )
465
465
  end
466
466
 
467
- it "should be able to perform arbitrary getattr" do
468
- engine.parse defn("A:",
469
- " b = 22",
470
- " c = b.x.y.z",
471
- )
467
+ it 'should be able to perform arbitrary getattr' do
468
+ engine.parse defn('A:',
469
+ ' b = 22',
470
+ ' c = b.x.y.z',
471
+ )
472
472
 
473
473
  engine.reset
474
474
 
475
475
  lambda {
476
- engine.parse defn("B:",
477
- " c = b.x.y.z",
478
- )
476
+ engine.parse defn('B:',
477
+ ' c = b.x.y.z',
478
+ )
479
479
  }.should raise_error(Delorean::UndefinedError)
480
-
481
480
  end
482
481
 
483
- it "should handle lines with comments" do
484
- engine.parse defn("A: # kaka",
485
- " b = 22 # testing #",
486
- " c = b",
487
- )
482
+ it 'should handle lines with comments' do
483
+ engine.parse defn('A: # kaka',
484
+ ' b = 22 # testing #',
485
+ ' c = b',
486
+ )
488
487
  end
489
488
 
490
- it "should be able to report error line during parse" do
489
+ it 'should be able to report error line during parse' do
491
490
  begin
492
- engine.parse defn("A:",
493
- " b = 123",
494
- "B: .A",
495
- )
496
- rescue => exc
491
+ engine.parse defn('A:',
492
+ ' b = 123',
493
+ 'B: .A',
494
+ )
495
+ rescue StandardError => exc
497
496
  end
498
497
 
499
- exc.module_name.should == "YYY"
498
+ exc.module_name.should == 'YYY'
500
499
  exc.line.should == 3
501
500
 
502
501
  engine.reset
503
502
 
504
503
  begin
505
- engine.parse defn("A:",
506
- " b = 3 % b",
507
- )
508
- rescue => exc
504
+ engine.parse defn('A:',
505
+ ' b = 3 % b',
506
+ )
507
+ rescue StandardError => exc
509
508
  end
510
509
 
511
- exc.module_name.should == "YYY"
510
+ exc.module_name.should == 'YYY'
512
511
  exc.line.should == 2
513
512
  end
514
513
 
515
- it "correctly report error line during parse" do
514
+ it 'correctly report error line during parse' do
516
515
  begin
517
- engine.parse defn("A:",
518
- " b = [yyy",
519
- " ]",
520
- "B:",
521
- )
522
- rescue => exc
516
+ engine.parse defn('A:',
517
+ ' b = [yyy',
518
+ ' ]',
519
+ 'B:',
520
+ )
521
+ rescue StandardError => exc
523
522
  end
524
523
 
525
- exc.module_name.should == "YYY"
524
+ exc.module_name.should == 'YYY'
526
525
  exc.line.should == 2
527
526
  end
528
527
 
529
- it "should raise error on malformed string" do
528
+ it 'should raise error on malformed string' do
530
529
  lambda {
531
- engine.parse defn("A:",
530
+ engine.parse defn('A:',
532
531
  ' d = "testing"" ',
533
- )
532
+ )
534
533
  }.should raise_error(Delorean::ParseError)
535
534
  end
536
535
 
537
- it "should not allow inherited ruby methods as attrs" do
536
+ it 'should not allow inherited ruby methods as attrs' do
538
537
  lambda {
539
- engine.parse defn("A:",
540
- " a = name",
541
- )
538
+ engine.parse defn('A:',
539
+ ' a = name',
540
+ )
542
541
  }.should raise_error(Delorean::UndefinedError)
543
542
 
544
543
  engine.reset
545
544
 
546
545
  lambda {
547
- engine.parse defn("A:",
548
- " a = new",
549
- )
546
+ engine.parse defn('A:',
547
+ ' a = new',
548
+ )
550
549
  }.should raise_error(Delorean::UndefinedError)
551
550
  end
552
551
 
553
- it "should be able to parse lists" do
554
- engine.parse defn("A:",
555
- " b = []",
556
- " c = [1,2,3]",
552
+ it 'should be able to parse lists' do
553
+ engine.parse defn('A:',
554
+ ' b = []',
555
+ ' c = [1,2,3]',
557
556
  " d = [b, c, b, c, 1, 2, '123', 1.1]",
558
- " e = [1, 1+1, 1+1+1]",
559
- )
557
+ ' e = [1, 1+1, 1+1+1]',
558
+ )
560
559
 
561
560
  engine.reset
562
561
 
563
562
  lambda {
564
- engine.parse defn("A:",
565
- " a = [",
566
- )
563
+ engine.parse defn('A:',
564
+ ' a = [',
565
+ )
567
566
  }.should raise_error(Delorean::ParseError)
568
567
 
569
568
  engine.reset
570
569
 
571
570
  lambda {
572
- engine.parse defn("A:",
573
- " a = []-",
574
- )
571
+ engine.parse defn('A:',
572
+ ' a = []-',
573
+ )
575
574
  }.should raise_error(Delorean::ParseError)
576
-
577
575
  end
578
576
 
579
577
  it "should handle trailing ',' with lists" do
580
- engine.parse defn("A:",
581
- " b = [1,2,3,]",
582
- )
578
+ engine.parse defn('A:',
579
+ ' b = [1,2,3,]',
580
+ )
583
581
 
584
582
  engine.reset
585
583
 
586
584
  lambda {
587
- engine.parse defn("A:",
588
- " a = [,]",
589
- )
585
+ engine.parse defn('A:',
586
+ ' a = [,]',
587
+ )
590
588
  }.should raise_error(Delorean::ParseError)
591
589
 
592
590
  engine.reset
593
591
 
594
592
  lambda {
595
- engine.parse defn("A:",
596
- " a = [1,2,,]",
597
- )
593
+ engine.parse defn('A:',
594
+ ' a = [1,2,,]',
595
+ )
598
596
  }.should raise_error(Delorean::ParseError)
599
597
  end
600
598
 
601
- it "should be able to parse hashes" do
602
- engine.parse defn("A:",
603
- " b = {}",
599
+ it 'should be able to parse hashes' do
600
+ engine.parse defn('A:',
601
+ ' b = {}',
604
602
  " c = {'a':1, 'b': 2, 'c':-3}",
605
- " d = [{1:11}, {2: 22}]",
606
- )
603
+ ' d = [{1:11}, {2: 22}]',
604
+ )
607
605
 
608
606
  engine.reset
609
607
 
610
608
  lambda {
611
- engine.parse defn("A:",
612
- " a = {",
613
- )
609
+ engine.parse defn('A:',
610
+ ' a = {',
611
+ )
614
612
  }.should raise_error(Delorean::ParseError)
615
613
 
616
614
  engine.reset
617
615
 
618
616
  lambda {
619
- engine.parse defn("A:",
620
- " a = {}+",
621
- )
617
+ engine.parse defn('A:',
618
+ ' a = {}+',
619
+ )
622
620
  }.should raise_error(Delorean::ParseError)
623
621
  end
624
622
 
625
- it "should be able to parse conditional hash literals" do
626
- engine.parse defn("A:",
627
- " a = {}",
623
+ it 'should be able to parse conditional hash literals' do
624
+ engine.parse defn('A:',
625
+ ' a = {}',
628
626
  " c = {'a':a if a, 'b': 2, 'c':-3 if 123}",
629
- )
627
+ )
630
628
  end
631
629
 
632
630
  it "should handle trailing ',' with hashes" do
633
- engine.parse defn("A:",
634
- " b = {-1:1,}",
635
- )
631
+ engine.parse defn('A:',
632
+ ' b = {-1:1,}',
633
+ )
636
634
 
637
635
  engine.reset
638
636
 
639
637
  lambda {
640
- engine.parse defn("A:",
641
- " a = {,}",
642
- )
638
+ engine.parse defn('A:',
639
+ ' a = {,}',
640
+ )
643
641
  }.should raise_error(Delorean::ParseError)
644
642
 
645
643
  engine.reset
646
644
 
647
645
  lambda {
648
- engine.parse defn("A:",
649
- " a = {-1:1,,}",
650
- )
646
+ engine.parse defn('A:',
647
+ ' a = {-1:1,,}',
648
+ )
651
649
  }.should raise_error(Delorean::ParseError)
652
650
  end
653
651
 
654
- it "should be able to parse list operations " do
655
- engine.parse defn("A:",
656
- " b = [] + []",
657
- )
652
+ it 'should be able to parse list operations ' do
653
+ engine.parse defn('A:',
654
+ ' b = [] + []',
655
+ )
658
656
  end
659
657
 
660
- it "should parse list comprehension" do
661
- engine.parse defn("A:",
662
- " b = [123 for i in 123]",
663
- )
664
-
658
+ it 'should parse list comprehension' do
659
+ engine.parse defn('A:',
660
+ ' b = [123 for i in 123]',
661
+ )
665
662
  end
666
663
 
667
- it "should parse list comprehension (2)" do
668
- engine.parse defn("A:",
669
- " b = [i+1 for i in [1,2,3]]",
670
- )
671
-
664
+ it 'should parse list comprehension (2)' do
665
+ engine.parse defn('A:',
666
+ ' b = [i+1 for i in [1,2,3]]',
667
+ )
672
668
  end
673
669
 
674
- it "should parse nested list comprehension" do
675
- engine.parse defn("A:",
676
- " b = [[a+c for c in [4,5]] for a in [1,2,3]]",
677
- )
678
-
670
+ it 'should parse nested list comprehension' do
671
+ engine.parse defn('A:',
672
+ ' b = [[a+c for c in [4,5]] for a in [1,2,3]]',
673
+ )
679
674
  end
680
675
 
681
- xit "should parse cross list comprehension" do
682
- engine.parse defn("A:",
683
- " b = [a+c for c in [4,5] for a in [1,2,3]]",
684
- )
685
-
676
+ xit 'should parse cross list comprehension' do
677
+ engine.parse defn('A:',
678
+ ' b = [a+c for c in [4,5] for a in [1,2,3]]',
679
+ )
686
680
  end
687
681
 
688
- it "should accept list comprehension variable override" do
689
- engine.parse defn("A:",
690
- " b = [b+1 for b in [1,2,3]]",
691
- )
682
+ it 'should accept list comprehension variable override' do
683
+ engine.parse defn('A:',
684
+ ' b = [b+1 for b in [1,2,3]]',
685
+ )
692
686
  end
693
687
 
694
- it "should accept list comprehension variable override (2)" do
695
- engine.parse defn("A:",
696
- " a = 1",
697
- " b = [a+1 for a in [1,2,3]]",
698
- )
688
+ it 'should accept list comprehension variable override (2)' do
689
+ engine.parse defn('A:',
690
+ ' a = 1',
691
+ ' b = [a+1 for a in [1,2,3]]',
692
+ )
699
693
  end
700
694
 
701
- it "errors out on bad list comprehension" do
695
+ it 'errors out on bad list comprehension' do
702
696
  lambda {
703
- engine.parse defn("A:",
704
- " b = [i+1 for x in [1,2,3]]",
705
- )
697
+ engine.parse defn('A:',
698
+ ' b = [i+1 for x in [1,2,3]]',
699
+ )
706
700
  }.should raise_error(Delorean::UndefinedError)
707
701
  engine.reset
708
702
 
709
703
  lambda {
710
- engine.parse defn("A:",
711
- " a = [123 for b in b]",
712
- )
704
+ engine.parse defn('A:',
705
+ ' a = [123 for b in b]',
706
+ )
713
707
  }.should raise_error(Delorean::UndefinedError)
714
708
  engine.reset
715
709
 
716
710
  # disallow nested comprehension var reuse
717
711
  lambda {
718
- engine.parse defn("A:",
719
- " b = [[a+1 for a in [4,5]] for a in [1,2,3]]",
720
- )
712
+ engine.parse defn('A:',
713
+ ' b = [[a+1 for a in [4,5]] for a in [1,2,3]]',
714
+ )
721
715
  }.should raise_error(Delorean::RedefinedError)
722
716
  engine.reset
723
717
  end
724
718
 
725
- it "should handle nested comprehension variables" do
726
- engine.parse defn("A:",
727
- " b = [ a+b for a, b in [] ]",
728
- )
719
+ it 'should handle nested comprehension variables' do
720
+ engine.parse defn('A:',
721
+ ' b = [ a+b for a, b in [] ]',
722
+ )
729
723
  end
730
724
 
731
- it "should allow nodes as values" do
732
- engine.parse defn("A:",
733
- " a = 123",
734
- "B:",
735
- " a = A",
736
- )
725
+ it 'should allow nodes as values' do
726
+ engine.parse defn('A:',
727
+ ' a = 123',
728
+ 'B:',
729
+ ' a = A',
730
+ )
737
731
  end
738
732
 
739
- it "should parse module calls" do
740
- engine.parse defn("A:",
741
- " a = 123",
742
- " b = 456 + a",
733
+ it 'should parse module calls' do
734
+ engine.parse defn('A:',
735
+ ' a = 123',
736
+ ' b = 456 + a',
743
737
  " n = 'A'",
744
- " c = nil(x = 123, y = 456)",
745
- " d = n(x = 123,",
746
- " y = 456,",
747
- " )",
748
- )
738
+ ' c = nil(x = 123, y = 456)',
739
+ ' d = n(x = 123,',
740
+ ' y = 456,',
741
+ ' )',
742
+ )
749
743
  end
750
744
 
751
- it "should parse module calls by node name" do
752
- engine.parse defn("A:",
753
- " a = 123",
754
- " d = A()",
755
- )
745
+ it 'should parse module calls by node name' do
746
+ engine.parse defn('A:',
747
+ ' a = 123',
748
+ ' d = A()',
749
+ )
756
750
  end
757
751
 
758
- it "should allow positional args to node calls" do
759
- engine.parse defn("A:",
760
- " d = A(1, 2, 3, a=123, b=456)",
761
- )
752
+ it 'should allow positional args to node calls' do
753
+ engine.parse defn('A:',
754
+ ' d = A(1, 2, 3, a=123, b=456)',
755
+ )
762
756
  end
763
757
 
764
- it "should allow node calls to attrs" do
765
- engine.parse defn("A:",
766
- " x=?",
767
- " a = A(x=123)",
768
- " d = a(x=456).x",
769
- )
758
+ it 'should allow node calls to attrs' do
759
+ engine.parse defn('A:',
760
+ ' x=?',
761
+ ' a = A(x=123)',
762
+ ' d = a(x=456).x',
763
+ )
770
764
  end
771
765
 
772
- it "allow conditional args to node calls" do
773
- engine.parse defn("A:",
774
- " d = A(a=1, b=4 if true, c=4 if false)",
775
- )
766
+ it 'allow conditional args to node calls' do
767
+ engine.parse defn('A:',
768
+ ' d = A(a=1, b=4 if true, c=4 if false)',
769
+ )
776
770
  end
777
771
 
778
- it "allow double splats in node calls" do
779
- engine.parse defn("A:",
780
- " a =?",
781
- " d = A(**a, **(a+a), a=123, b=456)",
782
- )
772
+ it 'allow double splats in node calls' do
773
+ engine.parse defn('A:',
774
+ ' a =?',
775
+ ' d = A(**a, **(a+a), a=123, b=456)',
776
+ )
783
777
  end
784
778
 
785
- it "allow double splats in literal hashes" do
786
- engine.parse defn("A:",
787
- " a =?",
779
+ it 'allow double splats in literal hashes' do
780
+ engine.parse defn('A:',
781
+ ' a =?',
788
782
  " d = {'a':1, 2:2, **a, **(a+a)}",
789
- )
783
+ )
790
784
  end
791
785
 
792
- it "should parse instance calls" do
793
- engine.parse defn("A:",
794
- " a = [1,2,[4]].flatten(1)",
795
- )
786
+ it 'should parse instance calls' do
787
+ engine.parse defn('A:',
788
+ ' a = [1,2,[4]].flatten(1)',
789
+ )
796
790
  end
797
791
 
798
- it "should parse multiline attr defs" do
799
- engine.parse defn("A:",
800
- " a = [1,",
801
- " 2,",
802
- " 3]",
803
- " b = 456",
804
- )
792
+ it 'should parse multiline attr defs' do
793
+ engine.parse defn('A:',
794
+ ' a = [1,',
795
+ ' 2,',
796
+ ' 3]',
797
+ ' b = 456',
798
+ )
805
799
  end
806
800
 
807
- xit "should parse multiline empty list" do
808
- engine.parse defn("A:",
809
- " a = [",
810
- " ]",
811
- )
801
+ xit 'should parse multiline empty list' do
802
+ engine.parse defn('A:',
803
+ ' a = [',
804
+ ' ]',
805
+ )
812
806
  end
813
807
 
814
- it "should give proper errors on parse multiline attr defs" do
808
+ it 'should give proper errors on parse multiline attr defs' do
815
809
  begin
816
- engine.parse defn("A:",
817
- " a = [1,",
818
- " 2,",
819
- " 3];",
820
- " b = 456",
821
- )
822
- fail
810
+ engine.parse defn('A:',
811
+ ' a = [1,',
812
+ ' 2,',
813
+ ' 3];',
814
+ ' b = 456',
815
+ )
816
+ raise
823
817
  rescue Delorean::ParseError => exc
824
818
  exc.line.should == 2
825
819
  end
826
820
  end
827
821
 
828
- it "should give proper errors when multiline error falls off the end" do
822
+ it 'should give proper errors when multiline error falls off the end' do
829
823
  begin
830
- engine.parse defn("A:",
831
- " x = 123",
832
- " a = 1 +",
833
- " 2 +",
834
- )
835
- fail
824
+ engine.parse defn('A:',
825
+ ' x = 123',
826
+ ' a = 1 +',
827
+ ' 2 +',
828
+ )
829
+ raise
836
830
  rescue Delorean::ParseError => exc
837
831
  exc.line.should == 3
838
832
  end
@@ -840,69 +834,69 @@ describe "Delorean" do
840
834
 
841
835
  it "should give proper errors when multiline doesn't end properly" do
842
836
  begin
843
- engine.parse defn("A:",
844
- " a = 1",
845
- " b = [a+1",
846
- " for a in [1,2,3]",
847
- "B:",
848
- )
849
- fail
837
+ engine.parse defn('A:',
838
+ ' a = 1',
839
+ ' b = [a+1',
840
+ ' for a in [1,2,3]',
841
+ 'B:',
842
+ )
843
+ raise
850
844
  rescue Delorean::ParseError => exc
851
845
  exc.line.should == 3
852
846
  end
853
847
  end
854
848
 
855
- it "should error on multiline not properly spaced" do
849
+ it 'should error on multiline not properly spaced' do
856
850
  begin
857
- engine.parse defn("A:",
858
- " a = [1,",
859
- " 2]",
860
- " b = 456",
861
- )
862
- fail
851
+ engine.parse defn('A:',
852
+ ' a = [1,',
853
+ ' 2]',
854
+ ' b = 456',
855
+ )
856
+ raise
863
857
  rescue Delorean::ParseError => exc
864
858
  exc.line.should == 2
865
859
  end
866
860
  end
867
861
 
868
862
  # this is a parsing limitation which should go away
869
- it "should not parse interpolated strings" do
863
+ it 'should not parse interpolated strings' do
870
864
  begin
871
- engine.parse defn("A:",
865
+ engine.parse defn('A:',
872
866
  ' d = "#{this is a test}"',
873
- )
874
- fail
867
+ )
868
+ raise
875
869
  rescue Delorean::ParseError => exc
876
870
  exc.line.should == 2
877
871
  end
878
872
  end
879
873
 
880
- it "should parse imports" do
881
- engine.parse defn("import AAA",
882
- "A:",
883
- " b = 456",
884
- "B: AAA::X",
885
- )
874
+ it 'should parse imports' do
875
+ engine.parse defn('import AAA',
876
+ 'A:',
877
+ ' b = 456',
878
+ 'B: AAA::X',
879
+ )
886
880
  end
887
881
 
888
- xit "should parse ERR()" do
882
+ xit 'should parse ERR()' do
889
883
  # pending ... wrapping with parens -- (ERR()) works
890
- engine.parse defn("A:",
891
- " b = ERR() && 123",
892
- )
884
+ engine.parse defn('A:',
885
+ ' b = ERR() && 123',
886
+ )
893
887
  end
894
888
 
895
- it "should disallow import loops" do
889
+ it 'should disallow import loops' do
896
890
  skip 'not implemented yet'
897
891
  sset.merge(
898
- "BBB" =>
899
- defn("import AAA",
900
- "import CCC",
901
- ),
902
- "CCC" =>
903
- defn("import BBB",
904
- ),
905
- )
906
- sset.get_engine("CCC")
892
+ 'BBB' =>
893
+ defn('import AAA',
894
+ 'import CCC',
895
+ ),
896
+ 'CCC' =>
897
+ defn('import BBB',
898
+ ),
899
+ )
900
+ sset.get_engine('CCC')
907
901
  end
908
902
  end