code-ruby 0.15.16 → 1.1.0
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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +3 -3
- data/.prettierignore +2 -0
- data/.rubocop.yml +121 -5
- data/Gemfile +9 -1
- data/Gemfile.lock +30 -22
- data/VERSION +1 -1
- data/bin/bundle +123 -0
- data/bin/code +8 -10
- data/code-ruby.gemspec +3 -1
- data/lib/code/node/dictionary.rb +1 -3
- data/lib/code/node/if.rb +20 -15
- data/lib/code/node/left_operation.rb +1 -3
- data/lib/code/node/right_operation.rb +6 -6
- data/lib/code/node/while.rb +6 -6
- data/lib/code/object/boolean.rb +1 -1
- data/lib/code/object/class.rb +1 -1
- data/lib/code/object/code.rb +1 -1
- data/lib/code/object/context.rb +1 -1
- data/lib/code/object/date.rb +1 -1
- data/lib/code/object/decimal.rb +2 -2
- data/lib/code/object/dictionary.rb +12 -34
- data/lib/code/object/duration.rb +1 -1
- data/lib/code/object/function.rb +1 -1
- data/lib/code/object/global.rb +1 -1
- data/lib/code/object/html.rb +1 -1
- data/lib/code/object/integer.rb +2 -2
- data/lib/code/object/json.rb +2 -4
- data/lib/code/object/list.rb +3 -5
- data/lib/code/object/nothing.rb +1 -1
- data/lib/code/object/parameter.rb +1 -5
- data/lib/code/object/range.rb +1 -1
- data/lib/code/object/string.rb +1 -1
- data/lib/code/object/time.rb +1 -1
- data/lib/code/object.rb +7 -13
- data/lib/code/parser/string.rb +7 -7
- data/lib/code/type/repeat.rb +1 -1
- data/lib/code/version.rb +1 -1
- data/lib/code-ruby.rb +1 -1
- data/package-lock.json +14 -0
- data/package.json +0 -1
- data/spec/code/node/call_spec.rb +0 -34
- data/spec/code/parser_spec.rb +2 -2
- data/spec/code/type_spec.rb +1 -1
- data/spec/code_spec.rb +78 -79
- metadata +14 -12
- data/bin/console +0 -6
- data/yarn.lock +0 -4
- /data/spec/code/parser/{chained_call.rb → chained_call_spec.rb} +0 -0
@@ -3,7 +3,7 @@
|
|
3
3
|
class Code
|
4
4
|
class Object
|
5
5
|
class Dictionary < ::Code::Object
|
6
|
-
def initialize(*args, **kargs, &
|
6
|
+
def initialize(*args, **kargs, &)
|
7
7
|
@raw = args.map(&:to_h).reduce({}, &:merge).merge(kargs)
|
8
8
|
end
|
9
9
|
|
@@ -298,9 +298,7 @@ class Code
|
|
298
298
|
self
|
299
299
|
end
|
300
300
|
|
301
|
-
|
302
|
-
code_size.code_eight?
|
303
|
-
end
|
301
|
+
delegate :code_eight?, to: :code_size
|
304
302
|
|
305
303
|
def code_empty?
|
306
304
|
Boolean.new(raw.empty?)
|
@@ -355,18 +353,14 @@ class Code
|
|
355
353
|
List.new(raw.fetch_values(*))
|
356
354
|
end
|
357
355
|
|
358
|
-
|
359
|
-
code_size.code_five?
|
360
|
-
end
|
356
|
+
delegate :code_five?, to: :code_size
|
361
357
|
|
362
358
|
def code_flatten(level = nil)
|
363
359
|
level = Integer.new(-1) if level.nil? || level.falsy?
|
364
360
|
code_to_list.code_flatten(level)
|
365
361
|
end
|
366
362
|
|
367
|
-
|
368
|
-
code_size.code_four?
|
369
|
-
end
|
363
|
+
delegate :code_four?, to: :code_size
|
370
364
|
|
371
365
|
def code_get(key)
|
372
366
|
raw[key] || Nothing.new
|
@@ -507,13 +501,9 @@ class Code
|
|
507
501
|
self
|
508
502
|
end
|
509
503
|
|
510
|
-
|
511
|
-
code_size.code_nine?
|
512
|
-
end
|
504
|
+
delegate :code_nine?, to: :code_size
|
513
505
|
|
514
|
-
|
515
|
-
code_size.code_one?
|
516
|
-
end
|
506
|
+
delegate :code_one?, to: :code_size
|
517
507
|
|
518
508
|
def code_select!(argument, **globals)
|
519
509
|
if argument.is_a?(Class)
|
@@ -554,13 +544,9 @@ class Code
|
|
554
544
|
value
|
555
545
|
end
|
556
546
|
|
557
|
-
|
558
|
-
code_size.code_seven?
|
559
|
-
end
|
547
|
+
delegate :code_seven?, to: :code_size
|
560
548
|
|
561
|
-
|
562
|
-
code_size.code_six?
|
563
|
-
end
|
549
|
+
delegate :code_six?, to: :code_size
|
564
550
|
|
565
551
|
def code_size
|
566
552
|
Integer.new(raw.size)
|
@@ -574,13 +560,9 @@ class Code
|
|
574
560
|
Boolean.new(raw >= other.raw)
|
575
561
|
end
|
576
562
|
|
577
|
-
|
578
|
-
code_size.code_ten?
|
579
|
-
end
|
563
|
+
delegate :code_ten?, to: :code_size
|
580
564
|
|
581
|
-
|
582
|
-
code_size.code_three?
|
583
|
-
end
|
565
|
+
delegate :code_three?, to: :code_size
|
584
566
|
|
585
567
|
def code_to_context
|
586
568
|
Context.new(raw)
|
@@ -607,17 +589,13 @@ class Code
|
|
607
589
|
)
|
608
590
|
end
|
609
591
|
|
610
|
-
|
611
|
-
code_size.code_two?
|
612
|
-
end
|
592
|
+
delegate :code_two?, to: :code_size
|
613
593
|
|
614
594
|
def code_values
|
615
595
|
List.new(raw.values)
|
616
596
|
end
|
617
597
|
|
618
|
-
|
619
|
-
code_size.code_zero?
|
620
|
-
end
|
598
|
+
delegate :code_zero?, to: :code_size
|
621
599
|
end
|
622
600
|
end
|
623
601
|
end
|
data/lib/code/object/duration.rb
CHANGED
data/lib/code/object/function.rb
CHANGED
@@ -5,7 +5,7 @@ class Code
|
|
5
5
|
class Function < Object
|
6
6
|
attr_reader :parameters, :body
|
7
7
|
|
8
|
-
def initialize(*args, **_kargs, &
|
8
|
+
def initialize(*args, **_kargs, &)
|
9
9
|
@parameters = List.new(args.first.presence || [])
|
10
10
|
@parameters.raw.map! { |parameter| Parameter.new(parameter) }
|
11
11
|
@body = Code.new(args.second.presence || Nothing.new)
|
data/lib/code/object/global.rb
CHANGED
@@ -70,7 +70,7 @@ class Code
|
|
70
70
|
arguments.any? ? String.new(*arguments.raw) : Class.new(String)
|
71
71
|
when "Time"
|
72
72
|
sig(args) { Object.repeat }
|
73
|
-
arguments.any? ? Time.
|
73
|
+
arguments.any? ? Time.zone.local(*arguments.raw) : Class.new(Time)
|
74
74
|
when "Context"
|
75
75
|
sig(args) { Object.repeat }
|
76
76
|
arguments.any? ? Context.new(*arguments.raw) : Class.new(Context)
|
data/lib/code/object/html.rb
CHANGED
data/lib/code/object/integer.rb
CHANGED
@@ -3,12 +3,12 @@
|
|
3
3
|
class Code
|
4
4
|
class Object
|
5
5
|
class Integer < Object
|
6
|
-
def initialize(*args, **_kargs, &
|
6
|
+
def initialize(*args, **_kargs, &)
|
7
7
|
whole = args.first || 0
|
8
8
|
exponent = args.second || 0
|
9
9
|
whole = whole.raw if whole.is_an?(Object)
|
10
10
|
exponent = exponent.raw if exponent.is_an?(Object)
|
11
|
-
@raw = whole.to_i * 10**exponent
|
11
|
+
@raw = whole.to_i * (10**exponent)
|
12
12
|
rescue FloatDomainError
|
13
13
|
raise Error, "#{decimal.inspect} * 10**#{exponent.inspect} is invalid"
|
14
14
|
end
|
data/lib/code/object/json.rb
CHANGED
@@ -20,14 +20,12 @@ class Code
|
|
20
20
|
Decimal.new(json)
|
21
21
|
elsif json.is_an?(::Integer)
|
22
22
|
Integer.new(json)
|
23
|
-
elsif json.is_a?(::TrueClass)
|
24
|
-
Boolean.new(json)
|
25
|
-
elsif json.is_a?(::FalseClass)
|
23
|
+
elsif json.is_a?(::TrueClass) || json.is_a?(::FalseClass)
|
26
24
|
Boolean.new(json)
|
27
25
|
elsif json.is_a?(::NilClass)
|
28
26
|
Nothing.new(json)
|
29
27
|
else
|
30
|
-
|
28
|
+
raise Error, "#{json.inspect} not supported"
|
31
29
|
end
|
32
30
|
end
|
33
31
|
end
|
data/lib/code/object/list.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
class Code
|
4
4
|
class Object
|
5
5
|
class List < Object
|
6
|
-
def initialize(*args, **_kargs, &
|
6
|
+
def initialize(*args, **_kargs, &)
|
7
7
|
raw = args.first
|
8
8
|
raw = raw.raw if raw.is_an?(Object)
|
9
9
|
@raw = raw.to_a
|
@@ -305,7 +305,7 @@ class Code
|
|
305
305
|
end
|
306
306
|
|
307
307
|
def code_join(separator = nil)
|
308
|
-
separator ||=
|
308
|
+
separator ||= +""
|
309
309
|
|
310
310
|
String.new(raw.join(separator.raw))
|
311
311
|
end
|
@@ -326,9 +326,7 @@ class Code
|
|
326
326
|
raw.inject(&:code_plus) || Nothing.new
|
327
327
|
end
|
328
328
|
|
329
|
-
|
330
|
-
raw.any?
|
331
|
-
end
|
329
|
+
delegate :any?, to: :raw
|
332
330
|
end
|
333
331
|
end
|
334
332
|
end
|
data/lib/code/object/nothing.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
class Code
|
4
4
|
class Object
|
5
5
|
class Parameter < Object
|
6
|
-
def initialize(*args, **_kargs, &
|
6
|
+
def initialize(*args, **_kargs, &)
|
7
7
|
@raw = Dictionary.new(args.first.presence || {})
|
8
8
|
end
|
9
9
|
|
@@ -19,10 +19,6 @@ class Code
|
|
19
19
|
Boolean.new(raw.code_get(String.new(:keyword?)))
|
20
20
|
end
|
21
21
|
|
22
|
-
def code_keyword?
|
23
|
-
Boolean.new(raw.code_get(String.new(:keyword?)))
|
24
|
-
end
|
25
|
-
|
26
22
|
def code_regular_splat?
|
27
23
|
Boolean.new(raw.code_get(String.new(:regular_splat?)))
|
28
24
|
end
|
data/lib/code/object/range.rb
CHANGED
@@ -5,7 +5,7 @@ class Code
|
|
5
5
|
class Range < Object
|
6
6
|
attr_reader :left, :right, :options, :exclude_end
|
7
7
|
|
8
|
-
def initialize(*args, **_kargs, &
|
8
|
+
def initialize(*args, **_kargs, &)
|
9
9
|
@left = args.first.presence || Integer.new(0)
|
10
10
|
@right = args.second.presence || Integer.new(0)
|
11
11
|
@options = Dictionary.new(args.third.presence || {})
|
data/lib/code/object/string.rb
CHANGED
data/lib/code/object/time.rb
CHANGED
data/lib/code/object.rb
CHANGED
@@ -104,7 +104,7 @@ class Code
|
|
104
104
|
String.new(self)
|
105
105
|
when "to_time"
|
106
106
|
sig(args)
|
107
|
-
Time.
|
107
|
+
Time.zone.local(self)
|
108
108
|
when "as_json"
|
109
109
|
sig(args)
|
110
110
|
code_as_json
|
@@ -187,7 +187,7 @@ class Code
|
|
187
187
|
end
|
188
188
|
|
189
189
|
def self.multi_fetch(hash, *keys)
|
190
|
-
keys.
|
190
|
+
keys.to_h { |key| [key, hash.fetch(key)] }
|
191
191
|
end
|
192
192
|
|
193
193
|
def self.sig(args, &)
|
@@ -200,7 +200,7 @@ class Code
|
|
200
200
|
end
|
201
201
|
|
202
202
|
def self.inspect
|
203
|
-
|
203
|
+
name
|
204
204
|
end
|
205
205
|
|
206
206
|
def self.truthy?
|
@@ -242,7 +242,7 @@ class Code
|
|
242
242
|
other == self
|
243
243
|
end
|
244
244
|
end
|
245
|
-
|
245
|
+
alias eql? ==
|
246
246
|
|
247
247
|
def call(**args)
|
248
248
|
operator = args.fetch(:operator, nil)
|
@@ -318,7 +318,7 @@ class Code
|
|
318
318
|
String.new(self)
|
319
319
|
when "to_time"
|
320
320
|
sig(args)
|
321
|
-
Time.
|
321
|
+
Time.zone.local(self)
|
322
322
|
when "as_json"
|
323
323
|
sig(args)
|
324
324
|
code_as_json
|
@@ -409,7 +409,7 @@ class Code
|
|
409
409
|
end
|
410
410
|
|
411
411
|
def multi_fetch(hash, *keys)
|
412
|
-
keys.
|
412
|
+
keys.to_h { |key| [key, hash.fetch(key)] }
|
413
413
|
end
|
414
414
|
|
415
415
|
def sig(args, &)
|
@@ -417,13 +417,7 @@ class Code
|
|
417
417
|
nil
|
418
418
|
end
|
419
419
|
|
420
|
-
|
421
|
-
raw.to_s
|
422
|
-
end
|
423
|
-
|
424
|
-
def inspect
|
425
|
-
to_s
|
426
|
-
end
|
420
|
+
delegate :to_s, :inspect, to: :raw
|
427
421
|
|
428
422
|
def truthy?
|
429
423
|
true
|
data/lib/code/parser/string.rb
CHANGED
@@ -20,7 +20,7 @@ class Code
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def backslash
|
23
|
-
str(
|
23
|
+
str('\\')
|
24
24
|
end
|
25
25
|
|
26
26
|
def opening_curly_bracket
|
@@ -41,17 +41,17 @@ class Code
|
|
41
41
|
|
42
42
|
def single_quoted_text_part
|
43
43
|
(
|
44
|
-
backslash.ignore << opening_curly_bracket |
|
45
|
-
backslash.ignore << single_quote |
|
46
|
-
single_quote.absent << opening_curly_bracket.absent << any
|
44
|
+
(backslash.ignore << opening_curly_bracket) |
|
45
|
+
(backslash.ignore << single_quote) |
|
46
|
+
(single_quote.absent << opening_curly_bracket.absent << any)
|
47
47
|
).repeat(1)
|
48
48
|
end
|
49
49
|
|
50
50
|
def double_quoted_text_part
|
51
51
|
(
|
52
|
-
backslash.ignore << opening_curly_bracket |
|
53
|
-
backslash.ignore << double_quote |
|
54
|
-
double_quote.absent << opening_curly_bracket.absent << any
|
52
|
+
(backslash.ignore << opening_curly_bracket) |
|
53
|
+
(backslash.ignore << double_quote) |
|
54
|
+
(double_quote.absent << opening_curly_bracket.absent << any)
|
55
55
|
).repeat(1)
|
56
56
|
end
|
57
57
|
|
data/lib/code/type/repeat.rb
CHANGED
data/lib/code/version.rb
CHANGED
data/lib/code-ruby.rb
CHANGED
data/package-lock.json
ADDED
data/package.json
CHANGED
data/spec/code/node/call_spec.rb
CHANGED
@@ -1,37 +1,3 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "spec_helper"
|
4
|
-
|
5
|
-
RSpec.describe Code::Node::Call do
|
6
|
-
# let(:context) { <<~CONTEXT }
|
7
|
-
# render = (*args, **kargs, &block) => {
|
8
|
-
# [args, kargs, block&.call(:dorian)]
|
9
|
-
# }
|
10
|
-
#
|
11
|
-
# { render:, user: { name: :Dorian } }"
|
12
|
-
# CONTEXT
|
13
|
-
#
|
14
|
-
# [
|
15
|
-
# ["render", "[[], {}, nothing]"],
|
16
|
-
# ["render()", "[[], {}, nothing]"],
|
17
|
-
# ["render(user)", "[[user], {}, nothing]"],
|
18
|
-
# [
|
19
|
-
# "render(user, first_name: :Dorian)",
|
20
|
-
# "[[user], { first_name: :Dorian }, nothing]"
|
21
|
-
# ],
|
22
|
-
# ["render { }", "[[], {}, nothing]"],
|
23
|
-
# ["render do end", "[[], {}, nothing]"],
|
24
|
-
# ["render { |name| name.upcase }", "[[], {}, :Dorian]"],
|
25
|
-
# ["render(user) { |name| name.upcase }", "[[user], {}, :Dorian]"],
|
26
|
-
# ["render(user) do |name| name.upcase end", "[[user], {}, :Dorian]"],
|
27
|
-
# ["render { :Dorian }", "[[], {}, :Dorian]"],
|
28
|
-
# ["render(user) { :Dorian }", "[[user], {}, :Dorian]"],
|
29
|
-
# ["render(user) do :Dorian end", "[[user], {}, :Dorian]"]
|
30
|
-
# ].each do |input, expected|
|
31
|
-
# it "#{input} == #{expected}" do
|
32
|
-
# expect(Code.evaluate(input, context)).to eq(
|
33
|
-
# Code.evaluate(expected, context)
|
34
|
-
# )
|
35
|
-
# end
|
36
|
-
# end
|
37
|
-
end
|
data/spec/code/parser_spec.rb
CHANGED
@@ -17,13 +17,13 @@ RSpec.describe Code::Parser do
|
|
17
17
|
"nothing nothing nothing"
|
18
18
|
].each do |input, _output|
|
19
19
|
it input.inspect do
|
20
|
-
|
20
|
+
described_class.parse(input)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
Dir["spec/fixtures/code/parser/**/*.code"].each do |filename|
|
25
25
|
it "parses #{filename}" do
|
26
|
-
|
26
|
+
described_class.parse(File.read(filename))
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
data/spec/code/type_spec.rb
CHANGED
data/spec/code_spec.rb
CHANGED
@@ -3,81 +3,79 @@
|
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
5
|
RSpec.describe Code do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
it(input) { Code.evaluate(input) }
|
80
|
-
end
|
6
|
+
(
|
7
|
+
%w[
|
8
|
+
1.day.ago
|
9
|
+
1.day.from_now
|
10
|
+
1.hour.ago
|
11
|
+
1.hour.from_now
|
12
|
+
2.days.ago
|
13
|
+
2.days.from_now
|
14
|
+
2.hours.ago
|
15
|
+
2.hours.ago.hour
|
16
|
+
2.hours.from_now
|
17
|
+
2.hours.from_now.hour
|
18
|
+
Time.hour
|
19
|
+
Date.hour
|
20
|
+
Boolean.new
|
21
|
+
Boolean.new(true)
|
22
|
+
Boolean.new(false)
|
23
|
+
Class.new
|
24
|
+
Class.new(Boolean)
|
25
|
+
Class.new(Class)
|
26
|
+
Context.new
|
27
|
+
Context.new(a:1)
|
28
|
+
Date.new
|
29
|
+
Date.new.hour
|
30
|
+
Date.new("2024-03-05")
|
31
|
+
Date.new("2024-03-05").hour
|
32
|
+
Date.today
|
33
|
+
Date.yesterday
|
34
|
+
Date.tomorrow
|
35
|
+
Date.tomorrow.hour
|
36
|
+
Decimal.new
|
37
|
+
Decimal.new(0)
|
38
|
+
Decimal.new(1.2)
|
39
|
+
Dictionary.new
|
40
|
+
Dictionary.new(a:1)
|
41
|
+
Duration.new
|
42
|
+
Duration.new(1.day)
|
43
|
+
Duration.new("P1D")
|
44
|
+
Function.new
|
45
|
+
Integer.new
|
46
|
+
Integer.new(0)
|
47
|
+
Integer.new(1)
|
48
|
+
Integer.new(1.2)
|
49
|
+
List.new
|
50
|
+
List.new([])
|
51
|
+
List.new([1,2])
|
52
|
+
Nothing.new
|
53
|
+
Nothing.new(1)
|
54
|
+
Object.new
|
55
|
+
Object.new(1)
|
56
|
+
Range.new
|
57
|
+
Range.new(1,2)
|
58
|
+
Range.new(-1)
|
59
|
+
Range.new(1,2,exclude_end:false)
|
60
|
+
Range.new(1,2,exclude_end:true)
|
61
|
+
String.new
|
62
|
+
String.new(:hello)
|
63
|
+
Time.new
|
64
|
+
Time.new("2024-03-05.06:10:59.UTC")
|
65
|
+
Time.now
|
66
|
+
Time.tomorrow
|
67
|
+
Time.yesterday
|
68
|
+
Time.tomorrow
|
69
|
+
Code.new
|
70
|
+
Parameter.new
|
71
|
+
IdentifierList.new
|
72
|
+
IdentifierList.new([])
|
73
|
+
Time.new(nothing).before?
|
74
|
+
Html.link_to
|
75
|
+
Html.link_to('/')
|
76
|
+
Html.link_to('Home','/')
|
77
|
+
] + ["Time.hour >= 6 and Time.hour <= 23"]
|
78
|
+
).each { |input| it(input) { described_class.evaluate(input) } }
|
81
79
|
|
82
80
|
[
|
83
81
|
[
|
@@ -317,11 +315,12 @@ RSpec.describe Code do
|
|
317
315
|
].each do |input, expected|
|
318
316
|
it "#{input} == #{expected}" do
|
319
317
|
output = StringIO.new
|
320
|
-
input =
|
321
|
-
expected =
|
318
|
+
input = described_class.evaluate(input, output:)
|
319
|
+
expected = described_class.evaluate(expected)
|
322
320
|
expect(input).to eq(expected)
|
323
321
|
expect(output.string).to eq("")
|
324
322
|
next if input.is_a?(Code::Object::Decimal)
|
323
|
+
|
325
324
|
expect(input.to_json).to eq(expected.to_json)
|
326
325
|
end
|
327
326
|
end
|
@@ -329,13 +328,13 @@ RSpec.describe Code do
|
|
329
328
|
[["puts(true)", "true\n"], %w[print(false) false]].each do |input, expected|
|
330
329
|
it "#{input} prints #{expected}" do
|
331
330
|
output = StringIO.new
|
332
|
-
|
331
|
+
described_class.evaluate(input, output:)
|
333
332
|
expect(output.string).to eq(expected)
|
334
333
|
end
|
335
334
|
end
|
336
335
|
|
337
336
|
it "doesn't crash with dictionnary as parameter" do
|
338
|
-
|
337
|
+
described_class.evaluate(<<~INPUT)
|
339
338
|
[
|
340
339
|
{
|
341
340
|
videos: [{}]
|