template-ruby 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +70 -0
- data/lib/code/node/base_10_decimal.rb +27 -0
- data/lib/code/node/base_10_integer.rb +23 -0
- data/lib/code/node/base_10_number.rb +19 -0
- data/lib/code/node/base_16_number.rb +19 -0
- data/lib/code/node/base_2_number.rb +19 -0
- data/lib/code/node/base_8_number.rb +19 -0
- data/lib/code/node/boolean.rb +13 -0
- data/lib/code/node/call.rb +19 -0
- data/lib/code/node/code.rb +19 -0
- data/lib/code/node/dictionnary.rb +18 -0
- data/lib/code/node/dictionnary_key_value.rb +23 -0
- data/lib/code/node/list.rb +13 -0
- data/lib/code/node/name.rb +17 -0
- data/lib/code/node/nothing.rb +12 -0
- data/lib/code/node/number.rb +23 -0
- data/lib/code/node/statement.rb +31 -0
- data/lib/code/node/string.rb +17 -0
- data/lib/code/node.rb +4 -0
- data/lib/code/object/boolean.rb +28 -0
- data/lib/code/object/decimal.rb +31 -0
- data/lib/code/object/dictionnary.rb +32 -0
- data/lib/code/object/integer.rb +29 -0
- data/lib/code/object/list.rb +37 -0
- data/lib/code/object/nothing.rb +22 -0
- data/lib/code/object/string.rb +30 -0
- data/lib/code/object.rb +11 -0
- data/lib/code/parser/boolean.rb +14 -0
- data/lib/code/parser/call.rb +16 -0
- data/lib/code/parser/code.rb +18 -0
- data/lib/code/parser/dictionnary.rb +41 -0
- data/lib/code/parser/list.rb +29 -0
- data/lib/code/parser/name.rb +49 -0
- data/lib/code/parser/nothing.rb +17 -0
- data/lib/code/parser/number.rb +98 -0
- data/lib/code/parser/statement.rb +11 -0
- data/lib/code/parser/string.rb +66 -0
- data/lib/code/parser.rb +4 -0
- data/lib/code.rb +27 -0
- data/lib/template/node/code_part.rb +13 -0
- data/lib/template/node/part.rb +19 -0
- data/lib/template/node/template.rb +13 -0
- data/lib/template/node/text_part.rb +13 -0
- data/lib/template/node.rb +4 -0
- data/lib/template/parser/template.rb +26 -0
- data/lib/template/parser.rb +4 -0
- data/lib/template-ruby.rb +6 -0
- data/lib/template.rb +20 -0
- data/spec/code/parser/boolean_spec.rb +18 -0
- data/spec/code/parser/call_spec.rb +39 -0
- data/spec/code/parser/dictionnary_spec.rb +46 -0
- data/spec/code/parser/list_spec.rb +29 -0
- data/spec/code/parser/name_spec.rb +15 -0
- data/spec/code/parser/nothing_spec.rb +19 -0
- data/spec/code/parser/number_spec.rb +117 -0
- data/spec/code/parser/string_spec.rb +29 -0
- data/spec/code_spec.rb +35 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/template/parser/template_spec.rb +19 -0
- data/spec/template_spec.rb +30 -0
- data/template-ruby.gemspec +20 -0
- metadata +188 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class Boolean < Parslet::Parser
|
4
|
+
rule(:nothing) { ::Code::Parser::Nothing.new }
|
5
|
+
|
6
|
+
rule(:true_keyword) { str("true") }
|
7
|
+
rule(:false_keyword) { str("false") }
|
8
|
+
|
9
|
+
rule(:boolean) { (true_keyword | false_keyword).as(:boolean) | nothing }
|
10
|
+
|
11
|
+
root(:boolean)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class Call < Parslet::Parser
|
4
|
+
rule(:dictionnary) { ::Code::Parser::Dictionnary.new }
|
5
|
+
|
6
|
+
rule(:dot) { str(".") }
|
7
|
+
|
8
|
+
rule(:call) do
|
9
|
+
(dictionnary.as(:left) >> dot >> call.as(:right)).as(:call) |
|
10
|
+
dictionnary
|
11
|
+
end
|
12
|
+
|
13
|
+
root(:call)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class Code < Parslet::Parser
|
4
|
+
rule(:statement) { ::Code::Parser::Statement.new }
|
5
|
+
|
6
|
+
rule(:space) { str(" ") }
|
7
|
+
rule(:newline) { str("\n") }
|
8
|
+
rule(:whitespace) { (space | newline).repeat(1) }
|
9
|
+
rule(:whitespace?) { whitespace.maybe }
|
10
|
+
|
11
|
+
rule(:code) do
|
12
|
+
(whitespace? >> statement >> whitespace?).repeat(1) | whitespace?
|
13
|
+
end
|
14
|
+
|
15
|
+
root(:code)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class Dictionnary < Parslet::Parser
|
4
|
+
rule(:list) { ::Code::Parser::List.new }
|
5
|
+
rule(:code) { ::Code::Parser::Code.new }
|
6
|
+
rule(:string) { ::Code::Parser::String.new }
|
7
|
+
|
8
|
+
rule(:opening_curly_bracket) { str("{") }
|
9
|
+
rule(:closing_curly_bracket) { str("}") }
|
10
|
+
rule(:colon) { str(":") }
|
11
|
+
rule(:equal) { str("=") }
|
12
|
+
rule(:right_caret) { str(">") }
|
13
|
+
rule(:comma) { str(",") }
|
14
|
+
|
15
|
+
rule(:space) { str(" ") }
|
16
|
+
rule(:newline) { str("\n") }
|
17
|
+
rule(:whitespace) { (space | newline).repeat(1) }
|
18
|
+
rule(:whitespace?) { whitespace.maybe }
|
19
|
+
|
20
|
+
rule(:key_value) do
|
21
|
+
(string.as(:key) >> colon >> whitespace? >> code.as(:value)) |
|
22
|
+
(
|
23
|
+
code.as(:key) >> whitespace? >> equal >> right_caret >>
|
24
|
+
whitespace? >> code.as(:value)
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
rule(:dictionnary) do
|
29
|
+
(
|
30
|
+
opening_curly_bracket.ignore >> whitespace?.ignore >>
|
31
|
+
key_value.repeat(0, 1) >>
|
32
|
+
(whitespace? >> comma >> whitespace? >> key_value).repeat >>
|
33
|
+
whitespace?.ignore >> comma.maybe.ignore >> whitespace?.ignore >>
|
34
|
+
closing_curly_bracket.ignore
|
35
|
+
).as(:dictionnary) | list
|
36
|
+
end
|
37
|
+
|
38
|
+
root(:dictionnary)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class List < Parslet::Parser
|
4
|
+
rule(:string) { ::Code::Parser::String.new }
|
5
|
+
rule(:code) { ::Code::Parser::Code.new }
|
6
|
+
|
7
|
+
rule(:opening_square_bracket) { str("[") }
|
8
|
+
rule(:closing_square_bracket) { str("]") }
|
9
|
+
rule(:comma) { str(",") }
|
10
|
+
|
11
|
+
rule(:space) { str(" ") }
|
12
|
+
rule(:newline) { str("\n") }
|
13
|
+
rule(:whitespace) { (space | newline).repeat(1) }
|
14
|
+
rule(:whitespace?) { whitespace.maybe }
|
15
|
+
|
16
|
+
rule(:list) do
|
17
|
+
(
|
18
|
+
opening_square_bracket.ignore >> whitespace?.ignore >>
|
19
|
+
code.as(:code).repeat(0, 1) >>
|
20
|
+
(whitespace? >> comma >> whitespace? >> code.as(:code)).repeat >>
|
21
|
+
whitespace?.ignore >> comma.maybe.ignore >> whitespace?.ignore >>
|
22
|
+
closing_square_bracket.ignore
|
23
|
+
).as(:list) | string
|
24
|
+
end
|
25
|
+
|
26
|
+
root(:list)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class Name < Parslet::Parser
|
4
|
+
rule(:space) { str(" ") }
|
5
|
+
rule(:newline) { str("\n") }
|
6
|
+
rule(:comma) { str(",") }
|
7
|
+
rule(:colon) { str(":") }
|
8
|
+
rule(:dot) { str(".") }
|
9
|
+
rule(:single_quote) { str("'") }
|
10
|
+
rule(:double_quote) { str('"') }
|
11
|
+
rule(:opening_curly_bracket) { str("{") }
|
12
|
+
rule(:closing_curly_bracket) { str("}") }
|
13
|
+
rule(:opening_square_bracket) { str("[") }
|
14
|
+
rule(:closing_square_bracket) { str("]") }
|
15
|
+
rule(:equal) { str("=") }
|
16
|
+
rule(:left_caret) { str("<") }
|
17
|
+
rule(:right_caret) { str(">") }
|
18
|
+
|
19
|
+
rule(:zero) { str("0") }
|
20
|
+
rule(:one) { str("1") }
|
21
|
+
rule(:two) { str("2") }
|
22
|
+
rule(:three) { str("3") }
|
23
|
+
rule(:four) { str("4") }
|
24
|
+
rule(:five) { str("5") }
|
25
|
+
rule(:six) { str("6") }
|
26
|
+
rule(:seven) { str("7") }
|
27
|
+
rule(:eight) { str("8") }
|
28
|
+
rule(:nine) { str("9") }
|
29
|
+
|
30
|
+
rule(:digit) do
|
31
|
+
zero | one | two | three | four | five | six | seven | eight | nine
|
32
|
+
end
|
33
|
+
|
34
|
+
rule(:name_character) do
|
35
|
+
space.absent? >> newline.absent? >> comma.absent? >> colon.absent? >>
|
36
|
+
dot.absent? >> single_quote.absent? >> double_quote.absent? >>
|
37
|
+
opening_curly_bracket.absent? >> closing_curly_bracket.absent? >>
|
38
|
+
opening_square_bracket.absent? >> closing_square_bracket.absent? >>
|
39
|
+
equal.absent? >> left_caret.absent? >> right_caret.absent? >> any
|
40
|
+
end
|
41
|
+
|
42
|
+
rule(:name) do
|
43
|
+
(digit.absent? >> name_character >> name_character.repeat).as(:name)
|
44
|
+
end
|
45
|
+
|
46
|
+
root(:name)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class Nothing < Parslet::Parser
|
4
|
+
rule(:name) { ::Code::Parser::Name.new }
|
5
|
+
|
6
|
+
rule(:nothing_keyword) { str("nothing") }
|
7
|
+
rule(:null_keyword) { str("null") }
|
8
|
+
rule(:nil_keyword) { str("nil") }
|
9
|
+
|
10
|
+
rule(:nothing) do
|
11
|
+
(nothing_keyword | null_keyword | nil_keyword).as(:nothing) | name
|
12
|
+
end
|
13
|
+
|
14
|
+
root(:nothing)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class Number < Parslet::Parser
|
4
|
+
rule(:boolean) { ::Code::Parser::Boolean.new }
|
5
|
+
|
6
|
+
rule(:dot) { str(".") }
|
7
|
+
rule(:plus) { str("+") }
|
8
|
+
rule(:minus) { str("-") }
|
9
|
+
|
10
|
+
rule(:zero) { str("0") }
|
11
|
+
rule(:one) { str("1") }
|
12
|
+
rule(:two) { str("2") }
|
13
|
+
rule(:three) { str("3") }
|
14
|
+
rule(:four) { str("4") }
|
15
|
+
rule(:five) { str("5") }
|
16
|
+
rule(:six) { str("6") }
|
17
|
+
rule(:seven) { str("7") }
|
18
|
+
rule(:eight) { str("8") }
|
19
|
+
rule(:nine) { str("9") }
|
20
|
+
rule(:a) { str("a") | str("A") }
|
21
|
+
rule(:b) { str("b") | str("B") }
|
22
|
+
rule(:b) { str("b") | str("B") }
|
23
|
+
rule(:c) { str("c") | str("C") }
|
24
|
+
rule(:d) { str("d") | str("D") }
|
25
|
+
rule(:e) { str("e") | str("E") }
|
26
|
+
rule(:f) { str("f") | str("F") }
|
27
|
+
rule(:o) { str("o") | str("O") }
|
28
|
+
rule(:x) { str("x") | str("X") }
|
29
|
+
|
30
|
+
# sign
|
31
|
+
|
32
|
+
rule(:sign) { plus | minus }
|
33
|
+
|
34
|
+
# base 2
|
35
|
+
|
36
|
+
rule(:base_2_digit) { zero | one }
|
37
|
+
|
38
|
+
rule(:base_2_number) { zero.ignore >> b.ignore >> base_2_digit.repeat(1) }
|
39
|
+
|
40
|
+
# base 8
|
41
|
+
|
42
|
+
rule(:base_8_digit) do
|
43
|
+
zero | one | two | three | four | five | six | seven
|
44
|
+
end
|
45
|
+
|
46
|
+
rule(:base_8_number) { zero.ignore >> o.ignore >> base_8_digit.repeat(1) }
|
47
|
+
|
48
|
+
# base 10
|
49
|
+
|
50
|
+
rule(:base_10_digit) do
|
51
|
+
zero | one | two | three | four | five | six | seven | eight | nine
|
52
|
+
end
|
53
|
+
|
54
|
+
rule(:base_10_whole) { base_10_digit.repeat(1) }
|
55
|
+
|
56
|
+
rule(:base_10_exponent) { e.ignore >> base_10_number }
|
57
|
+
|
58
|
+
rule(:base_10_integer) do
|
59
|
+
sign.as(:sign).maybe >> base_10_whole.as(:whole) >>
|
60
|
+
base_10_exponent.as(:exponent).maybe
|
61
|
+
end
|
62
|
+
|
63
|
+
rule(:base_10_decimal_decimal) { dot.ignore >> base_10_digit.repeat(1) }
|
64
|
+
|
65
|
+
rule(:base_10_decimal) do
|
66
|
+
sign.as(:sign).maybe >> base_10_whole.as(:whole) >>
|
67
|
+
base_10_decimal_decimal.as(:decimal) >>
|
68
|
+
base_10_exponent.as(:exponent).maybe
|
69
|
+
end
|
70
|
+
|
71
|
+
rule(:base_10_number) do
|
72
|
+
base_10_decimal.as(:decimal) | base_10_integer.as(:integer)
|
73
|
+
end
|
74
|
+
|
75
|
+
# base 16
|
76
|
+
|
77
|
+
rule(:base_16_digit) do
|
78
|
+
zero | one | two | three | four | five | six | seven | eight | nine |
|
79
|
+
a | b | c | d | e | f
|
80
|
+
end
|
81
|
+
|
82
|
+
rule(:base_16_number) do
|
83
|
+
zero.ignore >> x.ignore >> base_16_digit.repeat(1)
|
84
|
+
end
|
85
|
+
|
86
|
+
# number
|
87
|
+
|
88
|
+
rule(:number) do
|
89
|
+
(
|
90
|
+
base_2_number.as(:base_2) | base_8_number.as(:base_8) |
|
91
|
+
base_16_number.as(:base_16) | base_10_number.as(:base_10)
|
92
|
+
).as(:number) | boolean
|
93
|
+
end
|
94
|
+
|
95
|
+
root(:number)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class String < Parslet::Parser
|
4
|
+
rule(:number) { ::Code::Parser::Number.new }
|
5
|
+
|
6
|
+
rule(:single_quote) { str("'") }
|
7
|
+
rule(:double_quote) { str('"') }
|
8
|
+
rule(:backslash) { str("\\") }
|
9
|
+
rule(:zero) { str("0") }
|
10
|
+
rule(:one) { str("1") }
|
11
|
+
rule(:two) { str("2") }
|
12
|
+
rule(:three) { str("3") }
|
13
|
+
rule(:four) { str("4") }
|
14
|
+
rule(:five) { str("5") }
|
15
|
+
rule(:six) { str("6") }
|
16
|
+
rule(:seven) { str("7") }
|
17
|
+
rule(:eight) { str("8") }
|
18
|
+
rule(:nine) { str("9") }
|
19
|
+
rule(:a) { str("a") | str("A") }
|
20
|
+
rule(:b) { str("b") | str("B") }
|
21
|
+
rule(:b) { str("b") | str("B") }
|
22
|
+
rule(:c) { str("c") | str("C") }
|
23
|
+
rule(:d) { str("d") | str("D") }
|
24
|
+
rule(:e) { str("e") | str("E") }
|
25
|
+
rule(:f) { str("f") | str("F") }
|
26
|
+
rule(:n) { str("n") | str("N") }
|
27
|
+
rule(:r) { str("r") | str("R") }
|
28
|
+
rule(:t) { str("t") | str("T") }
|
29
|
+
rule(:u) { str("u") | str("U") }
|
30
|
+
|
31
|
+
rule(:base_16_digit) do
|
32
|
+
zero | one | two | three | four | five | six | seven | eight | nine |
|
33
|
+
a | b | c | d | e | f
|
34
|
+
end
|
35
|
+
|
36
|
+
rule(:escaped_character) do
|
37
|
+
(backslash >> u >> base_16_digit.repeat(4, 4)) |
|
38
|
+
(backslash >> (b | f | n | r | t)) | (backslash.ignore >> any)
|
39
|
+
end
|
40
|
+
|
41
|
+
rule(:single_quoted_character) do
|
42
|
+
escaped_character | (single_quote.absent? >> any)
|
43
|
+
end
|
44
|
+
|
45
|
+
rule(:double_quoted_character) do
|
46
|
+
escaped_character | (double_quote.absent? >> any)
|
47
|
+
end
|
48
|
+
|
49
|
+
rule(:single_quoted_string) do
|
50
|
+
single_quote.ignore >> single_quoted_character.repeat >>
|
51
|
+
single_quote.ignore
|
52
|
+
end
|
53
|
+
|
54
|
+
rule(:double_quoted_string) do
|
55
|
+
double_quote.ignore >> double_quoted_character.repeat >>
|
56
|
+
double_quote.ignore
|
57
|
+
end
|
58
|
+
|
59
|
+
rule(:string) do
|
60
|
+
(single_quoted_string | double_quoted_string).as(:string) | number
|
61
|
+
end
|
62
|
+
|
63
|
+
root(:string)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/code/parser.rb
ADDED
data/lib/code.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require "active_support"
|
2
|
+
require "active_support/core_ext/object/blank"
|
3
|
+
|
4
|
+
class Code
|
5
|
+
def initialize(input)
|
6
|
+
@input = input
|
7
|
+
@parsed = ::Code::Parser::Code.new.parse(@input)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.evaluate(input, context = "")
|
11
|
+
new(input).evaluate(context)
|
12
|
+
end
|
13
|
+
|
14
|
+
def evaluate(context = "")
|
15
|
+
if context.present?
|
16
|
+
context = ::Code.evaluate(context)
|
17
|
+
else
|
18
|
+
context = ::Code::Object::Dictionnary.new
|
19
|
+
end
|
20
|
+
|
21
|
+
::Code::Node::Code.new(parsed).evaluate(context)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :input, :parsed
|
27
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class Template
|
2
|
+
class Node
|
3
|
+
class Part
|
4
|
+
def initialize(part)
|
5
|
+
if part.key?(:text)
|
6
|
+
@part = ::Template::Node::TextPart.new(part[:text])
|
7
|
+
elsif part.key?(:code)
|
8
|
+
@part = ::Template::Node::CodePart.new(part[:code])
|
9
|
+
else
|
10
|
+
raise NotImplementedError.new(part.inspect)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def evaluate(context)
|
15
|
+
@part.evaluate(context)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Template
|
2
|
+
class Node
|
3
|
+
class Template
|
4
|
+
def initialize(parts)
|
5
|
+
@parts = parts.map { |part| ::Template::Node::Part.new(part) }
|
6
|
+
end
|
7
|
+
|
8
|
+
def evaluate(context)
|
9
|
+
::Code::Object::List.new(@parts.map { |part| part.evaluate(context) })
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Template
|
2
|
+
class Parser
|
3
|
+
class Template < Parslet::Parser
|
4
|
+
rule(:code) { ::Code::Parser::Code.new }
|
5
|
+
|
6
|
+
rule(:left_curly_bracket) { str("{") }
|
7
|
+
rule(:right_curly_bracket) { str("}") }
|
8
|
+
rule(:escape) { str("\\") }
|
9
|
+
|
10
|
+
rule(:text_part) do
|
11
|
+
(
|
12
|
+
(escape.ignore >> left_curly_bracket) |
|
13
|
+
(left_curly_bracket.absent? >> any)
|
14
|
+
).repeat(1)
|
15
|
+
end
|
16
|
+
|
17
|
+
rule(:code_part) do
|
18
|
+
left_curly_bracket >> code >> (right_curly_bracket | any.absent?)
|
19
|
+
end
|
20
|
+
|
21
|
+
rule(:template) { (text_part.as(:text) | code_part.as(:code)).repeat(1) }
|
22
|
+
|
23
|
+
root(:template)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/template.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
class Template
|
2
|
+
def initialize(input)
|
3
|
+
@input = input
|
4
|
+
@parsed = ::Template::Parser::Template.new.parse(@input)
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.render(input, context = "")
|
8
|
+
new(input).render(context)
|
9
|
+
end
|
10
|
+
|
11
|
+
def render(context = "")
|
12
|
+
if context.present?
|
13
|
+
context = ::Code.evaluate(context)
|
14
|
+
else
|
15
|
+
context = ::Code::Object::Dictionnary.new
|
16
|
+
end
|
17
|
+
|
18
|
+
::Template::Node::Template.new(@parsed).evaluate(context).map(&:to_s).join
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe Code::Parser::Boolean do
|
4
|
+
subject { described_class.new.parse(input) }
|
5
|
+
|
6
|
+
[
|
7
|
+
["true", { boolean: "true" }],
|
8
|
+
["false", { boolean: "false" }]
|
9
|
+
].each do |(input, expected)|
|
10
|
+
context input.inspect do
|
11
|
+
let(:input) { input }
|
12
|
+
|
13
|
+
it "succeeds" do
|
14
|
+
expect(subject).to eq(expected)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe Code::Parser::Call do
|
4
|
+
subject { described_class.new.parse(input) }
|
5
|
+
|
6
|
+
[
|
7
|
+
[
|
8
|
+
"user.first_name",
|
9
|
+
{ call: { left: { name: "user" }, right: { name: "first_name" } } }
|
10
|
+
],
|
11
|
+
[
|
12
|
+
"3.times",
|
13
|
+
{
|
14
|
+
call: {
|
15
|
+
left: {
|
16
|
+
number: {
|
17
|
+
base_10: {
|
18
|
+
integer: {
|
19
|
+
whole: "3"
|
20
|
+
}
|
21
|
+
}
|
22
|
+
}
|
23
|
+
},
|
24
|
+
right: {
|
25
|
+
name: "times"
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
]
|
30
|
+
].each do |(input, expected)|
|
31
|
+
context input.inspect do
|
32
|
+
let(:input) { input }
|
33
|
+
|
34
|
+
it "succeeds" do
|
35
|
+
expect(subject).to eq(expected)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe Code::Parser::Dictionnary do
|
4
|
+
subject { described_class.new.parse(input) }
|
5
|
+
|
6
|
+
[
|
7
|
+
[
|
8
|
+
'{name: "Dorian"}',
|
9
|
+
{
|
10
|
+
dictionnary: [{ key: { name: "name" }, value: [{ string: "Dorian" }] }]
|
11
|
+
}
|
12
|
+
],
|
13
|
+
[
|
14
|
+
'{a: true, "b": false}',
|
15
|
+
{
|
16
|
+
dictionnary: [
|
17
|
+
{ key: { name: "a" }, value: [{ boolean: "true" }] },
|
18
|
+
{ key: { string: "b" }, value: [{ boolean: "false" }] }
|
19
|
+
]
|
20
|
+
}
|
21
|
+
],
|
22
|
+
[
|
23
|
+
"{ true => 1, false => 2}",
|
24
|
+
{
|
25
|
+
dictionnary: [
|
26
|
+
{
|
27
|
+
key: [{ boolean: "true" }],
|
28
|
+
value: [{ number: { base_10: { integer: { whole: "1" } } } }]
|
29
|
+
},
|
30
|
+
{
|
31
|
+
key: [{ boolean: "false" }],
|
32
|
+
value: [{ number: { base_10: { integer: { whole: "2" } } } }]
|
33
|
+
}
|
34
|
+
]
|
35
|
+
}
|
36
|
+
]
|
37
|
+
].each do |(input, expected)|
|
38
|
+
context input.inspect do
|
39
|
+
let(:input) { input }
|
40
|
+
|
41
|
+
it "succeeds" do
|
42
|
+
expect(subject).to eq(expected)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe Code::Parser::List do
|
4
|
+
subject { described_class.new.parse(input) }
|
5
|
+
|
6
|
+
[
|
7
|
+
[
|
8
|
+
"[true, false]",
|
9
|
+
{
|
10
|
+
list: [
|
11
|
+
{ code: [{ boolean: "true" }] },
|
12
|
+
{ code: [{ boolean: "false" }] }
|
13
|
+
]
|
14
|
+
}
|
15
|
+
],
|
16
|
+
[
|
17
|
+
"[nothing, a]",
|
18
|
+
{ list: [{ code: [{ nothing: "nothing" }] }, { code: [{ name: "a" }] }] }
|
19
|
+
]
|
20
|
+
].each do |(input, expected)|
|
21
|
+
context input.inspect do
|
22
|
+
let(:input) { input }
|
23
|
+
|
24
|
+
it "succeeds" do
|
25
|
+
expect(subject).to eq(expected)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe Code::Parser::Name do
|
4
|
+
subject { described_class.new.parse(input) }
|
5
|
+
|
6
|
+
%w[user dorian User RSpec describe?].each do |(input, expected)|
|
7
|
+
context input.inspect do
|
8
|
+
let(:input) { input }
|
9
|
+
|
10
|
+
it "succeeds" do
|
11
|
+
expect(subject).to eq({ name: input })
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|