template-ruby 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.editorconfig +9 -0
- data/.gitignore +1 -0
- data/.prettierrc +3 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile.lock +1 -1
- data/README.md +10 -0
- data/bin/template +39 -0
- data/docs/euler/1.template +14 -0
- data/docs/euler/2.template +16 -0
- data/docs/euler/3.template +16 -0
- data/docs/euler/4.template +11 -0
- data/docs/euler/5.template +14 -0
- data/docs/precedence.template +94 -0
- data/lib/code/error.rb +15 -0
- data/lib/code/node/base_10_decimal.rb +12 -7
- data/lib/code/node/base_10_integer.rb +13 -4
- data/lib/code/node/base_10_number.rb +3 -3
- data/lib/code/node/base_16_number.rb +2 -2
- data/lib/code/node/base_2_number.rb +2 -2
- data/lib/code/node/base_8_number.rb +2 -2
- data/lib/code/node/block.rb +17 -0
- data/lib/code/node/boolean.rb +13 -4
- data/lib/code/node/call.rb +40 -8
- data/lib/code/node/call_argument.rb +37 -0
- data/lib/code/node/chained_call.rb +38 -0
- data/lib/code/node/code.rb +4 -7
- data/lib/code/node/defined.rb +19 -0
- data/lib/code/node/dictionnary.rb +11 -7
- data/lib/code/node/dictionnary_key_value.rb +3 -3
- data/lib/code/node/equal.rb +36 -0
- data/lib/code/node/function.rb +17 -0
- data/lib/code/node/function_argument.rb +45 -0
- data/lib/code/node/group.rb +13 -0
- data/lib/code/node/if.rb +55 -0
- data/lib/code/node/if_modifier.rb +48 -0
- data/lib/code/node/keyword_call_argument.rb +30 -0
- data/lib/code/node/keyword_function_argument.rb +33 -0
- data/lib/code/node/list.rb +10 -4
- data/lib/code/node/name.rb +37 -4
- data/lib/code/node/negation.rb +33 -0
- data/lib/code/node/not_keyword.rb +13 -0
- data/lib/code/node/nothing.rb +2 -2
- data/lib/code/node/number.rb +3 -3
- data/lib/code/node/operation.rb +33 -0
- data/lib/code/node/or_keyword.rb +34 -0
- data/lib/code/node/power.rb +16 -0
- data/lib/code/node/range.rb +31 -0
- data/lib/code/node/regular_call_argument.rb +34 -0
- data/lib/code/node/regular_function_argument.rb +36 -0
- data/lib/code/node/rescue.rb +16 -0
- data/lib/code/node/statement.rb +53 -3
- data/lib/code/node/string.rb +2 -2
- data/lib/code/node/ternary.rb +26 -0
- data/lib/code/node/unary_minus.rb +22 -0
- data/lib/code/node/while.rb +42 -0
- data/lib/code/node.rb +10 -0
- data/lib/code/object/argument.rb +41 -0
- data/lib/code/object/boolean.rb +8 -9
- data/lib/code/object/decimal.rb +32 -9
- data/lib/code/object/dictionnary.rb +33 -10
- data/lib/code/object/function.rb +64 -0
- data/lib/code/object/integer.rb +94 -7
- data/lib/code/object/list.rb +190 -10
- data/lib/code/object/nothing.rb +10 -9
- data/lib/code/object/number.rb +6 -0
- data/lib/code/object/range.rb +158 -0
- data/lib/code/object/string.rb +37 -7
- data/lib/code/object.rb +129 -2
- data/lib/code/parser/addition.rb +29 -0
- data/lib/code/parser/and_operator.rb +28 -0
- data/lib/code/parser/bitwise_and.rb +28 -0
- data/lib/code/parser/bitwise_or.rb +29 -0
- data/lib/code/parser/call.rb +77 -3
- data/lib/code/parser/defined.rb +20 -0
- data/lib/code/parser/equal.rb +42 -0
- data/lib/code/parser/equality.rb +36 -0
- data/lib/code/parser/function.rb +57 -0
- data/lib/code/parser/greater_than.rb +33 -0
- data/lib/code/parser/group.rb +17 -0
- data/lib/code/parser/if.rb +33 -0
- data/lib/code/parser/if_modifier.rb +28 -0
- data/lib/code/parser/multiplication.rb +30 -0
- data/lib/code/parser/name.rb +44 -4
- data/lib/code/parser/negation.rb +19 -0
- data/lib/code/parser/not_keyword.rb +21 -0
- data/lib/code/parser/nothing.rb +2 -2
- data/lib/code/parser/or_keyword.rb +29 -0
- data/lib/code/parser/or_operator.rb +28 -0
- data/lib/code/parser/power.rb +25 -0
- data/lib/code/parser/range.rb +25 -0
- data/lib/code/parser/rescue.rb +23 -0
- data/lib/code/parser/shift.rb +31 -0
- data/lib/code/parser/statement.rb +1 -4
- data/lib/code/parser/string.rb +7 -1
- data/lib/code/parser/ternary.rb +25 -0
- data/lib/code/parser/unary_minus.rb +13 -0
- data/lib/code/parser/while.rb +25 -0
- data/lib/code.rb +5 -7
- data/lib/template/node/code_part.rb +2 -2
- data/lib/template/node/part.rb +2 -2
- data/lib/template/node/template.rb +4 -2
- data/lib/template/node/text_part.rb +1 -1
- data/lib/template-ruby.rb +4 -0
- data/lib/template.rb +9 -4
- data/spec/call_spec.rb +22 -0
- data/spec/code/error/type_error_spec.rb +65 -0
- data/spec/code/parser/boolean_spec.rb +1 -1
- data/spec/code/parser/call_spec.rb +40 -11
- data/spec/code/parser/dictionnary_spec.rb +11 -11
- data/spec/code/parser/function_spec.rb +32 -0
- data/spec/code/parser/list_spec.rb +5 -5
- data/spec/code/parser/nothing_spec.rb +1 -1
- data/spec/code/parser/number_spec.rb +35 -35
- data/spec/code/parser/string_spec.rb +3 -2
- data/spec/code_spec.rb +75 -3
- data/spec/function_spec.rb +26 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/template/parser/template_spec.rb +1 -1
- data/spec/template_spec.rb +6 -6
- data/template-ruby.gemspec +6 -3
- metadata +76 -4
@@ -0,0 +1,23 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class Rescue < Parslet::Parser
|
4
|
+
rule(:ternary) { ::Code::Parser::Ternary.new }
|
5
|
+
|
6
|
+
rule(:rescue_keyword) { str("rescue") }
|
7
|
+
|
8
|
+
rule(:space) { str(" ") }
|
9
|
+
rule(:newline) { str("\n") }
|
10
|
+
rule(:whitespace) { (space | newline).repeat(1) }
|
11
|
+
rule(:whitespace?) { whitespace.maybe }
|
12
|
+
|
13
|
+
rule(:rescue) do
|
14
|
+
(
|
15
|
+
ternary.as(:left) >> whitespace? >> rescue_keyword >> whitespace? >>
|
16
|
+
ternary.as(:right)
|
17
|
+
).as(:rescue) | ternary
|
18
|
+
end
|
19
|
+
|
20
|
+
root(:rescue)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class Shift < Parslet::Parser
|
4
|
+
rule(:addition) { ::Code::Parser::Addition.new }
|
5
|
+
|
6
|
+
rule(:right_caret) { str(">") }
|
7
|
+
rule(:left_caret) { str("<") }
|
8
|
+
|
9
|
+
rule(:operator) do
|
10
|
+
(left_caret >> left_caret) | (right_caret >> right_caret)
|
11
|
+
end
|
12
|
+
|
13
|
+
rule(:space) { str(" ") }
|
14
|
+
rule(:newline) { str("\n") }
|
15
|
+
rule(:whitespace) { (space | newline).repeat(1) }
|
16
|
+
rule(:whitespace?) { whitespace.maybe }
|
17
|
+
|
18
|
+
rule(:shift) do
|
19
|
+
(
|
20
|
+
addition.as(:first) >>
|
21
|
+
(
|
22
|
+
whitespace? >> operator.as(:operator) >> whitespace? >>
|
23
|
+
addition.as(:statement)
|
24
|
+
).repeat(1).as(:rest)
|
25
|
+
).as(:shift) | addition
|
26
|
+
end
|
27
|
+
|
28
|
+
root(:shift)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/code/parser/string.rb
CHANGED
@@ -2,10 +2,13 @@ class Code
|
|
2
2
|
class Parser
|
3
3
|
class String < Parslet::Parser
|
4
4
|
rule(:number) { ::Code::Parser::Number.new }
|
5
|
+
rule(:name) { ::Code::Parser::Name.new.name }
|
5
6
|
|
6
7
|
rule(:single_quote) { str("'") }
|
7
8
|
rule(:double_quote) { str('"') }
|
8
9
|
rule(:backslash) { str("\\") }
|
10
|
+
rule(:colon) { str(":") }
|
11
|
+
|
9
12
|
rule(:zero) { str("0") }
|
10
13
|
rule(:one) { str("1") }
|
11
14
|
rule(:two) { str("2") }
|
@@ -56,8 +59,11 @@ class Code
|
|
56
59
|
double_quote.ignore
|
57
60
|
end
|
58
61
|
|
62
|
+
rule(:symbol) { colon.ignore >> name }
|
63
|
+
|
59
64
|
rule(:string) do
|
60
|
-
(single_quoted_string | double_quoted_string).as(:string) |
|
65
|
+
(single_quoted_string | double_quoted_string | symbol).as(:string) |
|
66
|
+
number
|
61
67
|
end
|
62
68
|
|
63
69
|
root(:string)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class Ternary < Parslet::Parser
|
4
|
+
rule(:range) { ::Code::Parser::Range.new }
|
5
|
+
|
6
|
+
rule(:question_mark) { str("?") }
|
7
|
+
rule(:colon) { str(":") }
|
8
|
+
|
9
|
+
rule(:space) { str(" ") }
|
10
|
+
rule(:newline) { str("\n") }
|
11
|
+
rule(:whitespace) { (space | newline).repeat(1) }
|
12
|
+
rule(:whitespace?) { whitespace.maybe }
|
13
|
+
|
14
|
+
rule(:ternary) do
|
15
|
+
(
|
16
|
+
range.as(:left) >> whitespace >> question_mark >> whitespace? >>
|
17
|
+
ternary.as(:middle) >>
|
18
|
+
(whitespace? >> colon >> whitespace? >> ternary.as(:right)).maybe
|
19
|
+
).as(:ternary) | range
|
20
|
+
end
|
21
|
+
|
22
|
+
root(:ternary)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class UnaryMinus < Parslet::Parser
|
4
|
+
rule(:power) { ::Code::Parser::Power.new }
|
5
|
+
|
6
|
+
rule(:minus) { str("-") }
|
7
|
+
|
8
|
+
rule(:unary_minus) { (minus >> unary_minus).as(:unary_minus) | power }
|
9
|
+
|
10
|
+
root(:unary_minus)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class While < Parslet::Parser
|
4
|
+
rule(:if_rule) { ::Code::Parser::If.new }
|
5
|
+
rule(:code) { ::Code::Parser::Code.new }
|
6
|
+
|
7
|
+
rule(:while_keyword) { str("while") }
|
8
|
+
rule(:until_keyword) { str("until") }
|
9
|
+
rule(:end_keyword) { str("end") }
|
10
|
+
|
11
|
+
rule(:space) { str(" ") }
|
12
|
+
rule(:newline) { str("\n") }
|
13
|
+
rule(:whitespace) { (space | newline).repeat(1) }
|
14
|
+
|
15
|
+
rule(:while_rule) do
|
16
|
+
(
|
17
|
+
(while_keyword | until_keyword).as(:operator) >> whitespace >>
|
18
|
+
if_rule.as(:statement) >> code.as(:body) >> end_keyword
|
19
|
+
).as(:while) | if_rule
|
20
|
+
end
|
21
|
+
|
22
|
+
root(:while_rule)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/code.rb
CHANGED
@@ -1,14 +1,12 @@
|
|
1
|
-
require "active_support"
|
2
|
-
require "active_support/core_ext/object/blank"
|
3
|
-
|
4
1
|
class Code
|
5
|
-
def initialize(input)
|
2
|
+
def initialize(input, io: $stdout)
|
6
3
|
@input = input
|
7
4
|
@parsed = ::Code::Parser::Code.new.parse(@input)
|
5
|
+
@io = io
|
8
6
|
end
|
9
7
|
|
10
|
-
def self.evaluate(input, context = "")
|
11
|
-
new(input).evaluate(context)
|
8
|
+
def self.evaluate(input, context = "", io: $stdout)
|
9
|
+
new(input, io: io).evaluate(context)
|
12
10
|
end
|
13
11
|
|
14
12
|
def evaluate(context = "")
|
@@ -18,7 +16,7 @@ class Code
|
|
18
16
|
context = ::Code::Object::Dictionnary.new
|
19
17
|
end
|
20
18
|
|
21
|
-
::Code::Node::Code.new(parsed).evaluate(context)
|
19
|
+
::Code::Node::Code.new(parsed).evaluate(context: context, io: @io)
|
22
20
|
end
|
23
21
|
|
24
22
|
private
|
data/lib/template/node/part.rb
CHANGED
@@ -5,8 +5,10 @@ class Template
|
|
5
5
|
@parts = parts.map { |part| ::Template::Node::Part.new(part) }
|
6
6
|
end
|
7
7
|
|
8
|
-
def evaluate(
|
9
|
-
|
8
|
+
def evaluate(**args)
|
9
|
+
io = args.fetch(:io)
|
10
|
+
|
11
|
+
@parts.each { |part| io.print(part.evaluate(**args)) }
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
data/lib/template-ruby.rb
CHANGED
data/lib/template.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
class Template
|
2
|
-
|
2
|
+
VERSION = Gem::Version.new("0.2.0")
|
3
|
+
|
4
|
+
def initialize(input, io: StringIO.new)
|
3
5
|
@input = input
|
4
6
|
@parsed = ::Template::Parser::Template.new.parse(@input)
|
7
|
+
@io = io
|
5
8
|
end
|
6
9
|
|
7
|
-
def self.render(input, context = "")
|
8
|
-
new(input).render(context)
|
10
|
+
def self.render(input, context = "", io: StringIO.new)
|
11
|
+
new(input, io: io).render(context)
|
9
12
|
end
|
10
13
|
|
11
14
|
def render(context = "")
|
@@ -15,6 +18,8 @@ class Template
|
|
15
18
|
context = ::Code::Object::Dictionnary.new
|
16
19
|
end
|
17
20
|
|
18
|
-
::Template::Node::Template.new(@parsed).evaluate(context)
|
21
|
+
::Template::Node::Template.new(@parsed).evaluate(context: context, io: @io)
|
22
|
+
|
23
|
+
@io.is_a?(StringIO) ? @io.string : nil
|
19
24
|
end
|
20
25
|
end
|
data/spec/call_spec.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe Code do
|
4
|
+
subject { described_class.evaluate(input).to_s }
|
5
|
+
|
6
|
+
[
|
7
|
+
%w[(1..2).any?(&:even?) true],
|
8
|
+
%w[(1..1).any?(&:even?) false],
|
9
|
+
%w[(3..3).any?(&:even?) false],
|
10
|
+
%w[(2..5).any?(&:even?) true],
|
11
|
+
["(2..5).any? { |n| n.even? }", "true"],
|
12
|
+
["(2..5).select { |i| i.even? }.any? { |n| n.even? }", "true"],
|
13
|
+
].each do |(input, expected)|
|
14
|
+
context input.inspect do
|
15
|
+
let(:input) { input }
|
16
|
+
|
17
|
+
it "succeeds" do
|
18
|
+
expect(subject).to eq(expected)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe ::Code::Error::TypeError do
|
4
|
+
describe "Integer" do
|
5
|
+
context "creating an integer with a non-number exponent" do
|
6
|
+
it "raises" do
|
7
|
+
expect { ::Code::Object::Integer.new(1, exponent: "2") }.to raise_error(
|
8
|
+
described_class,
|
9
|
+
)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
[
|
14
|
+
'1 / ""',
|
15
|
+
'1 ** ""',
|
16
|
+
'1 % ""',
|
17
|
+
'1 + ""',
|
18
|
+
'1 - ""',
|
19
|
+
'1 << ""',
|
20
|
+
'1 >> ""',
|
21
|
+
'1 & ""',
|
22
|
+
'1 | ""',
|
23
|
+
'1 ^ ""',
|
24
|
+
'1 > ""',
|
25
|
+
'1 >= ""',
|
26
|
+
'1 < ""',
|
27
|
+
'1 <= ""',
|
28
|
+
].each do |input|
|
29
|
+
context input.inspect do
|
30
|
+
it "raises" do
|
31
|
+
expect { ::Code.evaluate(input) }.to raise_error(described_class)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "Decimal" do
|
38
|
+
context "creating an integer with a non-number exponent" do
|
39
|
+
it "raises" do
|
40
|
+
expect { ::Code::Object::Decimal.new(1, exponent: "2") }.to raise_error(
|
41
|
+
described_class,
|
42
|
+
)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
[
|
47
|
+
'1.0 / ""',
|
48
|
+
'1.0 ** ""',
|
49
|
+
'1.0 * ""',
|
50
|
+
'1.0 % ""',
|
51
|
+
'1.0 + ""',
|
52
|
+
'1.0 - ""',
|
53
|
+
'1.0 > ""',
|
54
|
+
'1.0 >= ""',
|
55
|
+
'1.0 < ""',
|
56
|
+
'1.0 <= ""',
|
57
|
+
].each do |input|
|
58
|
+
context input.inspect do
|
59
|
+
it "raises" do
|
60
|
+
expect { ::Code.evaluate(input) }.to raise_error(described_class)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -6,7 +6,7 @@ RSpec.describe Code::Parser::Call do
|
|
6
6
|
[
|
7
7
|
[
|
8
8
|
"user.first_name",
|
9
|
-
{ call: { left: { name: "user" }, right: { name: "first_name" } } }
|
9
|
+
{ call: { left: { name: "user" }, right: [{ name: "first_name" }] } },
|
10
10
|
],
|
11
11
|
[
|
12
12
|
"3.times",
|
@@ -16,17 +16,17 @@ RSpec.describe Code::Parser::Call do
|
|
16
16
|
number: {
|
17
17
|
base_10: {
|
18
18
|
integer: {
|
19
|
-
whole: "3"
|
20
|
-
}
|
21
|
-
}
|
22
|
-
}
|
19
|
+
whole: "3",
|
20
|
+
},
|
21
|
+
},
|
22
|
+
},
|
23
23
|
},
|
24
|
-
right: {
|
25
|
-
name: "times"
|
26
|
-
}
|
27
|
-
}
|
28
|
-
}
|
29
|
-
]
|
24
|
+
right: [{
|
25
|
+
name: "times",
|
26
|
+
}],
|
27
|
+
},
|
28
|
+
},
|
29
|
+
],
|
30
30
|
].each do |(input, expected)|
|
31
31
|
context input.inspect do
|
32
32
|
let(:input) { input }
|
@@ -36,4 +36,33 @@ RSpec.describe Code::Parser::Call do
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
39
|
+
|
40
|
+
[
|
41
|
+
"User.first",
|
42
|
+
"User.first(10)",
|
43
|
+
'User.find_by(name: "Dorian")',
|
44
|
+
"User.update_all(**attributes)",
|
45
|
+
"User.each(&block)",
|
46
|
+
"user.update(*args)",
|
47
|
+
"sort([1, 2, 3], :asc)",
|
48
|
+
"render()",
|
49
|
+
"render(item)",
|
50
|
+
"Renderer.render(item)",
|
51
|
+
"render(item) { 'Hello' }",
|
52
|
+
"render(item) { |item| item * 2 }",
|
53
|
+
"render(item) { |item1, item2| item1 + item2 }",
|
54
|
+
"render(item) do 'Hello' end",
|
55
|
+
"render(item) do |item| item * 2 end",
|
56
|
+
"render(item) do |item1, item2| item1 + item2 end",
|
57
|
+
"(1..2).any?(&:even?)",
|
58
|
+
"(2..5).select { |i| i.even? }.any? { |n| n.even? }",
|
59
|
+
].each do |input|
|
60
|
+
context input.inspect do
|
61
|
+
let(:input) { input }
|
62
|
+
|
63
|
+
it "succeeds" do
|
64
|
+
expect { subject }.to_not raise_error
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
39
68
|
end
|
@@ -7,17 +7,17 @@ RSpec.describe Code::Parser::Dictionnary do
|
|
7
7
|
[
|
8
8
|
'{name: "Dorian"}',
|
9
9
|
{
|
10
|
-
dictionnary: [{ key: { name: "name" }, value: [{ string: "Dorian" }] }]
|
11
|
-
}
|
10
|
+
dictionnary: [{ key: { name: "name" }, value: [{ string: "Dorian" }] }],
|
11
|
+
},
|
12
12
|
],
|
13
13
|
[
|
14
14
|
'{a: true, "b": false}',
|
15
15
|
{
|
16
16
|
dictionnary: [
|
17
17
|
{ key: { name: "a" }, value: [{ boolean: "true" }] },
|
18
|
-
{ key: { string: "b" }, value: [{ boolean: "false" }] }
|
19
|
-
]
|
20
|
-
}
|
18
|
+
{ key: { string: "b" }, value: [{ boolean: "false" }] },
|
19
|
+
],
|
20
|
+
},
|
21
21
|
],
|
22
22
|
[
|
23
23
|
"{ true => 1, false => 2}",
|
@@ -25,15 +25,15 @@ RSpec.describe Code::Parser::Dictionnary do
|
|
25
25
|
dictionnary: [
|
26
26
|
{
|
27
27
|
key: [{ boolean: "true" }],
|
28
|
-
value: [{ number: { base_10: { integer: { whole: "1" } } } }]
|
28
|
+
value: [{ number: { base_10: { integer: { whole: "1" } } } }],
|
29
29
|
},
|
30
30
|
{
|
31
31
|
key: [{ boolean: "false" }],
|
32
|
-
value: [{ number: { base_10: { integer: { whole: "2" } } } }]
|
33
|
-
}
|
34
|
-
]
|
35
|
-
}
|
36
|
-
]
|
32
|
+
value: [{ number: { base_10: { integer: { whole: "2" } } } }],
|
33
|
+
},
|
34
|
+
],
|
35
|
+
},
|
36
|
+
],
|
37
37
|
].each do |(input, expected)|
|
38
38
|
context input.inspect do
|
39
39
|
let(:input) { input }
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe Code::Parser::Function do
|
4
|
+
subject { described_class.new.parse(input) }
|
5
|
+
|
6
|
+
[
|
7
|
+
"() => {}",
|
8
|
+
'() => { "Hello" }',
|
9
|
+
"(a) => { }",
|
10
|
+
"(a = 1)=> {}",
|
11
|
+
"(a, b) =>{}",
|
12
|
+
"(a, b = 2, c = b)=>{}",
|
13
|
+
"(a:)=>{}",
|
14
|
+
"(a:, b:)=>{}",
|
15
|
+
"(a, b:, c)=>{}",
|
16
|
+
"(a:, b: 1)=>{}",
|
17
|
+
"(a, b: 1, c)=>{}",
|
18
|
+
"(*args)=>{}",
|
19
|
+
"(*args, **kargs)=>{}",
|
20
|
+
"(&block)=>{}",
|
21
|
+
"(a = b = 1 + 1 b)=>{}",
|
22
|
+
"(a: b = 1 + 1 b)=>{}",
|
23
|
+
].each do |input|
|
24
|
+
context input.inspect do
|
25
|
+
let(:input) { input }
|
26
|
+
|
27
|
+
it "succeeds" do
|
28
|
+
expect { subject }.to_not raise_error
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -9,14 +9,14 @@ RSpec.describe Code::Parser::List do
|
|
9
9
|
{
|
10
10
|
list: [
|
11
11
|
{ code: [{ boolean: "true" }] },
|
12
|
-
{ code: [{ boolean: "false" }] }
|
13
|
-
]
|
14
|
-
}
|
12
|
+
{ code: [{ boolean: "false" }] },
|
13
|
+
],
|
14
|
+
},
|
15
15
|
],
|
16
16
|
[
|
17
17
|
"[nothing, a]",
|
18
|
-
{ list: [{ code: [{ nothing: "nothing" }] }, { code: [{ name: "a" }] }] }
|
19
|
-
]
|
18
|
+
{ list: [{ code: [{ nothing: "nothing" }] }, { code: [{ name: "a" }] }] },
|
19
|
+
],
|
20
20
|
].each do |(input, expected)|
|
21
21
|
context input.inspect do
|
22
22
|
let(:input) { input }
|
@@ -15,11 +15,11 @@ RSpec.describe Code::Parser::Number do
|
|
15
15
|
decimal: {
|
16
16
|
sign: "-",
|
17
17
|
whole: "1",
|
18
|
-
decimal: "0"
|
19
|
-
}
|
20
|
-
}
|
21
|
-
}
|
22
|
-
}
|
18
|
+
decimal: "0",
|
19
|
+
},
|
20
|
+
},
|
21
|
+
},
|
22
|
+
},
|
23
23
|
],
|
24
24
|
[
|
25
25
|
"+1.0",
|
@@ -29,11 +29,11 @@ RSpec.describe Code::Parser::Number do
|
|
29
29
|
decimal: {
|
30
30
|
sign: "+",
|
31
31
|
whole: "1",
|
32
|
-
decimal: "0"
|
33
|
-
}
|
34
|
-
}
|
35
|
-
}
|
36
|
-
}
|
32
|
+
decimal: "0",
|
33
|
+
},
|
34
|
+
},
|
35
|
+
},
|
36
|
+
},
|
37
37
|
],
|
38
38
|
["0", { number: { base_10: { integer: { whole: "0" } } } }],
|
39
39
|
["+0", { number: { base_10: { integer: { sign: "+", whole: "0" } } } }],
|
@@ -42,7 +42,7 @@ RSpec.describe Code::Parser::Number do
|
|
42
42
|
["0o01234567", { number: { base_8: "01234567" } }],
|
43
43
|
[
|
44
44
|
"0x0123456789aAbBcCdDeEfF",
|
45
|
-
{ number: { base_16: "0123456789aAbBcCdDeEfF" } }
|
45
|
+
{ number: { base_16: "0123456789aAbBcCdDeEfF" } },
|
46
46
|
],
|
47
47
|
[
|
48
48
|
"10e20",
|
@@ -53,13 +53,13 @@ RSpec.describe Code::Parser::Number do
|
|
53
53
|
whole: "10",
|
54
54
|
exponent: {
|
55
55
|
integer: {
|
56
|
-
whole: "20"
|
57
|
-
}
|
58
|
-
}
|
59
|
-
}
|
60
|
-
}
|
61
|
-
}
|
62
|
-
}
|
56
|
+
whole: "20",
|
57
|
+
},
|
58
|
+
},
|
59
|
+
},
|
60
|
+
},
|
61
|
+
},
|
62
|
+
},
|
63
63
|
],
|
64
64
|
[
|
65
65
|
"10.34e23.45",
|
@@ -72,13 +72,13 @@ RSpec.describe Code::Parser::Number do
|
|
72
72
|
exponent: {
|
73
73
|
decimal: {
|
74
74
|
whole: "23",
|
75
|
-
decimal: "45"
|
76
|
-
}
|
77
|
-
}
|
78
|
-
}
|
79
|
-
}
|
80
|
-
}
|
81
|
-
}
|
75
|
+
decimal: "45",
|
76
|
+
},
|
77
|
+
},
|
78
|
+
},
|
79
|
+
},
|
80
|
+
},
|
81
|
+
},
|
82
82
|
],
|
83
83
|
[
|
84
84
|
"+10e-20e1.0",
|
@@ -95,16 +95,16 @@ RSpec.describe Code::Parser::Number do
|
|
95
95
|
exponent: {
|
96
96
|
decimal: {
|
97
97
|
whole: "1",
|
98
|
-
decimal: "0"
|
99
|
-
}
|
100
|
-
}
|
101
|
-
}
|
102
|
-
}
|
103
|
-
}
|
104
|
-
}
|
105
|
-
}
|
106
|
-
}
|
107
|
-
]
|
98
|
+
decimal: "0",
|
99
|
+
},
|
100
|
+
},
|
101
|
+
},
|
102
|
+
},
|
103
|
+
},
|
104
|
+
},
|
105
|
+
},
|
106
|
+
},
|
107
|
+
],
|
108
108
|
].each do |(input, expected)|
|
109
109
|
context input.inspect do
|
110
110
|
let(:input) { input }
|
@@ -15,8 +15,9 @@ RSpec.describe Code::Parser::String do
|
|
15
15
|
['"\\uABCG"', { string: "uABCG" }],
|
16
16
|
[
|
17
17
|
"'\\u0123\\u4567\\u89aA\\ubBcC\\UdDeE\\ufFfF'",
|
18
|
-
{ string: "\\u0123\\u4567\\u89aA\\ubBcC\\UdDeE\\ufFfF" }
|
19
|
-
]
|
18
|
+
{ string: "\\u0123\\u4567\\u89aA\\ubBcC\\UdDeE\\ufFfF" },
|
19
|
+
],
|
20
|
+
[":asc", { string: "asc" }],
|
20
21
|
].each do |(input, expected)|
|
21
22
|
context input.inspect do
|
22
23
|
let(:input) { input }
|