code-ruby 0.4.0 → 0.5.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.
Files changed (204) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/Gemfile +2 -1
  4. data/Gemfile.lock +27 -54
  5. data/TODO +17 -0
  6. data/bin/code +56 -31
  7. data/bin/format +3 -0
  8. data/bin/template +62 -20
  9. data/bin/test +17 -0
  10. data/code-ruby.gemspec +1 -3
  11. data/docs/class.code +9 -0
  12. data/docs/euler/1.template +1 -5
  13. data/docs/euler/5.template +0 -1
  14. data/docs/meetup.code +12 -0
  15. data/docs/precedence.template +6 -39
  16. data/docs/rain.code +22 -0
  17. data/docs/slack.code +17 -0
  18. data/docs/stripe.code +7 -0
  19. data/docs/twitter.code +9 -0
  20. data/language-ruby.gemspec +18 -0
  21. data/lib/code/node/base_10.rb +29 -0
  22. data/lib/code/node/base_16.rb +13 -0
  23. data/lib/code/node/base_2.rb +13 -0
  24. data/lib/code/node/base_8.rb +13 -0
  25. data/lib/code/node/boolean.rb +7 -7
  26. data/lib/code/node/call.rb +32 -38
  27. data/lib/code/node/call_argument.rb +11 -27
  28. data/lib/code/node/chained_call.rb +10 -27
  29. data/lib/code/node/code.rb +4 -6
  30. data/lib/code/node/decimal.rb +26 -0
  31. data/lib/code/node/dictionnary.rb +20 -9
  32. data/lib/code/node/equal.rb +18 -20
  33. data/lib/code/node/function.rb +10 -7
  34. data/lib/code/node/function_parameter.rb +31 -0
  35. data/lib/code/node/if.rb +36 -32
  36. data/lib/code/node/if_modifier.rb +35 -36
  37. data/lib/code/node/list.rb +6 -8
  38. data/lib/code/node/negation.rb +5 -23
  39. data/lib/code/node/not.rb +15 -0
  40. data/lib/code/node/nothing.rb +1 -1
  41. data/lib/code/node/number.rb +14 -12
  42. data/lib/code/node/operation.rb +21 -16
  43. data/lib/code/node/power.rb +10 -6
  44. data/lib/code/node/rescue.rb +4 -3
  45. data/lib/code/node/splat.rb +15 -0
  46. data/lib/code/node/statement.rb +48 -70
  47. data/lib/code/node/string.rb +42 -16
  48. data/lib/code/node/ternary.rb +7 -9
  49. data/lib/code/node/unary_minus.rb +5 -12
  50. data/lib/code/node/while.rb +17 -24
  51. data/lib/code/node.rb +7 -8
  52. data/lib/code/object/argument.rb +2 -11
  53. data/lib/code/object/decimal.rb +45 -30
  54. data/lib/code/object/dictionnary.rb +6 -5
  55. data/lib/code/object/function.rb +20 -23
  56. data/lib/code/object/global.rb +11 -6
  57. data/lib/code/object/integer.rb +73 -30
  58. data/lib/code/object/list.rb +40 -34
  59. data/lib/code/object/range.rb +18 -17
  60. data/lib/code/object/ruby_function.rb +12 -6
  61. data/lib/code/object/string.rb +22 -12
  62. data/lib/code/object.rb +82 -24
  63. data/lib/code/parser/addition.rb +12 -20
  64. data/lib/code/parser/and_operator.rb +9 -20
  65. data/lib/code/parser/bitwise_and.rb +9 -20
  66. data/lib/code/parser/bitwise_or.rb +12 -20
  67. data/lib/code/parser/boolean.rb +10 -7
  68. data/lib/code/parser/call.rb +92 -60
  69. data/lib/code/parser/chained_call.rb +47 -0
  70. data/lib/code/parser/class.rb +45 -0
  71. data/lib/code/parser/code.rb +17 -10
  72. data/lib/code/parser/dictionnary.rb +56 -30
  73. data/lib/code/parser/equal.rb +87 -35
  74. data/lib/code/parser/equality.rb +23 -24
  75. data/lib/code/parser/equality_lower.rb +9 -0
  76. data/lib/code/parser/function.rb +67 -42
  77. data/lib/code/parser/greater.rb +25 -0
  78. data/lib/code/parser/group.rb +13 -8
  79. data/lib/code/parser/if.rb +51 -21
  80. data/lib/code/parser/if_modifier.rb +43 -16
  81. data/lib/code/parser/list.rb +32 -19
  82. data/lib/code/parser/multiplication.rb +15 -20
  83. data/lib/code/parser/name.rb +96 -84
  84. data/lib/code/parser/negation.rb +20 -9
  85. data/lib/code/parser/not_keyword.rb +14 -12
  86. data/lib/code/parser/nothing.rb +13 -8
  87. data/lib/code/parser/number.rb +124 -68
  88. data/lib/code/parser/operation.rb +35 -0
  89. data/lib/code/parser/or_keyword.rb +12 -20
  90. data/lib/code/parser/or_operator.rb +9 -20
  91. data/lib/code/parser/power.rb +32 -14
  92. data/lib/code/parser/range.rb +9 -17
  93. data/lib/code/parser/rescue.rb +29 -13
  94. data/lib/code/parser/shift.rb +11 -21
  95. data/lib/code/parser/splat.rb +31 -0
  96. data/lib/code/parser/statement.rb +4 -3
  97. data/lib/code/parser/string.rb +53 -62
  98. data/lib/code/parser/ternary.rb +36 -15
  99. data/lib/code/parser/unary_minus.rb +23 -5
  100. data/lib/code/parser/while.rb +26 -15
  101. data/lib/code/parser/whitespace.rb +49 -0
  102. data/lib/code/parser.rb +15 -0
  103. data/lib/code/ruby.rb +13 -12
  104. data/lib/code-ruby.rb +2 -11
  105. data/lib/code.rb +16 -13
  106. data/lib/language/atom.rb +343 -0
  107. data/lib/language/output.rb +130 -0
  108. data/lib/language/parser/absent/present.rb +8 -0
  109. data/lib/language/parser/absent.rb +6 -0
  110. data/lib/language/parser/end_of_input.rb +6 -0
  111. data/lib/language/parser/interuption.rb +38 -0
  112. data/lib/language/parser/not_end_of_input.rb +6 -0
  113. data/lib/language/parser/str/not_found.rb +16 -0
  114. data/lib/language/parser/str.rb +6 -0
  115. data/lib/language/parser.rb +53 -0
  116. data/lib/language-ruby.rb +10 -0
  117. data/lib/language.rb +80 -0
  118. data/lib/template/node/code_part.rb +1 -1
  119. data/lib/template/node/part.rb +1 -1
  120. data/lib/template/node/template.rb +1 -1
  121. data/lib/template/node/text_part.rb +1 -1
  122. data/lib/template/node.rb +1 -1
  123. data/lib/template/parser/template.rb +26 -17
  124. data/lib/template/parser.rb +15 -0
  125. data/lib/template/version.rb +1 -1
  126. data/lib/template-ruby.rb +2 -11
  127. data/lib/template.rb +6 -11
  128. data/spec/code/addition_spec.rb +13 -0
  129. data/spec/code/and_operator_spec.rb +13 -0
  130. data/spec/code/bitwise_and_spec.rb +13 -0
  131. data/spec/code/bitwise_or_spec.rb +13 -0
  132. data/spec/code/boolean_spec.rb +13 -0
  133. data/spec/code/call_spec.rb +21 -0
  134. data/spec/code/chained_call_spec.rb +16 -0
  135. data/spec/code/dictionnary_spec.rb +17 -0
  136. data/spec/code/equal_spec.rb +26 -0
  137. data/spec/code/equality_spec.rb +13 -0
  138. data/spec/code/function_spec.rb +18 -0
  139. data/spec/code/greater_spec.rb +18 -0
  140. data/spec/code/group_spec.rb +12 -0
  141. data/spec/code/if_modifier_spec.rb +20 -0
  142. data/spec/code/if_spec.rb +25 -0
  143. data/spec/code/list_spec.rb +17 -0
  144. data/spec/code/multiplication_spec.rb +18 -0
  145. data/spec/code/negation_spec.rb +20 -0
  146. data/spec/code/not_keyword_spec.rb +13 -0
  147. data/spec/code/nothing_spec.rb +17 -0
  148. data/spec/code/number_spec.rb +22 -0
  149. data/spec/code/or_keyword_spec.rb +17 -0
  150. data/spec/code/or_operator_spec.rb +16 -0
  151. data/spec/code/parser/boolean_spec.rb +5 -7
  152. data/spec/code/parser/call_spec.rb +16 -56
  153. data/spec/code/parser/chained_call.rb +17 -0
  154. data/spec/code/parser/dictionnary_spec.rb +8 -9
  155. data/spec/code/parser/function_spec.rb +5 -21
  156. data/spec/code/parser/group_spec.rb +18 -0
  157. data/spec/code/parser/list_spec.rb +9 -20
  158. data/spec/code/parser/number_spec.rb +4 -109
  159. data/spec/code/parser/string_spec.rb +9 -17
  160. data/spec/code/parser_spec.rb +23 -0
  161. data/spec/code/power_spec.rb +13 -0
  162. data/spec/code/range_spec.rb +16 -0
  163. data/spec/code/rescue_spec.rb +13 -0
  164. data/spec/code/shift_spec.rb +13 -0
  165. data/spec/code/splat_spec.rb +13 -0
  166. data/spec/code/string_spec.rb +25 -0
  167. data/spec/code/ternary_spec.rb +18 -0
  168. data/spec/code/unary_minus_spec.rb +13 -0
  169. data/spec/code/while_spec.rb +18 -0
  170. data/spec/spec_helper.rb +4 -1
  171. data/template-ruby.gemspec +2 -4
  172. metadata +110 -71
  173. data/lib/code/node/base_10_decimal.rb +0 -32
  174. data/lib/code/node/base_10_integer.rb +0 -32
  175. data/lib/code/node/base_10_number.rb +0 -19
  176. data/lib/code/node/base_16_number.rb +0 -19
  177. data/lib/code/node/base_2_number.rb +0 -19
  178. data/lib/code/node/base_8_number.rb +0 -19
  179. data/lib/code/node/block.rb +0 -17
  180. data/lib/code/node/defined.rb +0 -19
  181. data/lib/code/node/dictionnary_key_value.rb +0 -23
  182. data/lib/code/node/function_argument.rb +0 -45
  183. data/lib/code/node/group.rb +0 -13
  184. data/lib/code/node/keyword_call_argument.rb +0 -30
  185. data/lib/code/node/keyword_function_argument.rb +0 -33
  186. data/lib/code/node/name.rb +0 -28
  187. data/lib/code/node/not_keyword.rb +0 -13
  188. data/lib/code/node/or_keyword.rb +0 -34
  189. data/lib/code/node/range.rb +0 -31
  190. data/lib/code/node/regular_call_argument.rb +0 -34
  191. data/lib/code/node/regular_function_argument.rb +0 -36
  192. data/lib/code/node/string_characters.rb +0 -13
  193. data/lib/code/node/string_component.rb +0 -23
  194. data/lib/code/node/string_interpolation.rb +0 -13
  195. data/lib/code/parser/defined.rb +0 -20
  196. data/lib/code/parser/greater_than.rb +0 -33
  197. data/spec/call_spec.rb +0 -22
  198. data/spec/code/error/type_error_spec.rb +0 -63
  199. data/spec/code/parser/name_spec.rb +0 -15
  200. data/spec/code/parser/nothing_spec.rb +0 -19
  201. data/spec/code_spec.rb +0 -182
  202. data/spec/function_spec.rb +0 -26
  203. data/spec/template/parser/template_spec.rb +0 -19
  204. data/spec/template_spec.rb +0 -52
@@ -1,34 +0,0 @@
1
- class Code
2
- class Node
3
- class OrKeyword < Node
4
- OR_KEYWORD = "or"
5
- AND_KEYWORD = "and"
6
-
7
- def initialize(or_keyword)
8
- @first = ::Code::Node::Statement.new(or_keyword.fetch(:first))
9
- @rest = or_keyword.fetch(:rest)
10
- @rest.map! do |operation|
11
- ::Code::Node::Operation::Operation.new(operation)
12
- end
13
- end
14
-
15
- def evaluate(**args)
16
- object = @first.evaluate(**args)
17
-
18
- @rest.each do |operation|
19
- if operation.operator == OR_KEYWORD
20
- return object if object.truthy?
21
- elsif operation.operator == AND_KEYWORD
22
- return object unless object.truthy?
23
- else
24
- raise NotImplementedError.new(operation.operator.inspect)
25
- end
26
-
27
- object = operation.statement.evaluate(**args)
28
- end
29
-
30
- object
31
- end
32
- end
33
- end
34
- end
@@ -1,31 +0,0 @@
1
- class Code
2
- class Node
3
- class Range < Node
4
- INCLUSIVE_RANGE = ".."
5
- EXCLUSIVE_RANGE = "..."
6
-
7
- def initialize(range)
8
- @left = ::Code::Node::Statement.new(range.fetch(:left))
9
- @operator = range.fetch(:operator)
10
- @right = ::Code::Node::Statement.new(range.fetch(:right))
11
- end
12
-
13
- def evaluate(**args)
14
- left = @left.evaluate(**args)
15
- right = @right.evaluate(**args)
16
-
17
- if operator == INCLUSIVE_RANGE
18
- ::Code::Object::Range.new(left, right, exclude_end: false)
19
- elsif operator == EXCLUSIVE_RANGE
20
- ::Code::Object::Range.new(left, right, exclude_end: true)
21
- else
22
- raise NotImplementedError.new(operator)
23
- end
24
- end
25
-
26
- private
27
-
28
- attr_reader :operator
29
- end
30
- end
31
- end
@@ -1,34 +0,0 @@
1
- class Code
2
- class Node
3
- class RegularCallArgument < Node
4
- def initialize(argument)
5
- @splat = argument.key?(:splat)
6
- @keyword_splat = argument.key?(:keyword_splat)
7
- @block = argument.key?(:block)
8
- @value = ::Code::Node::Code.new(argument.fetch(:value))
9
- end
10
-
11
- def evaluate(**args)
12
- object = @value.evaluate(**args)
13
-
14
- block? ? simple_call(object, :to_function, **args) : object
15
- end
16
-
17
- def block?
18
- @block
19
- end
20
-
21
- def splat?
22
- @splat
23
- end
24
-
25
- def keyword_splat?
26
- @keyword_splat
27
- end
28
-
29
- def name
30
- nil
31
- end
32
- end
33
- end
34
- end
@@ -1,36 +0,0 @@
1
- class Code
2
- class Node
3
- class RegularFunctionArgument < Node
4
- def initialize(argument)
5
- @block = argument.key?(:block)
6
- @splat = argument.key?(:splat)
7
- @keyword_splat = argument.key?(:keyword_splat)
8
- @name = argument.fetch(:name)
9
-
10
- if argument.key?(:default)
11
- @default = ::Code::Node::Code.new(argument.fetch(:default))
12
- end
13
- end
14
-
15
- def evaluate(**args)
16
- @default ? @default.evaluate(**args) : ::Code::Object::Nothing.new
17
- end
18
-
19
- def name
20
- ::Code::Object::String.new(@name.to_s)
21
- end
22
-
23
- def splat?
24
- @splat
25
- end
26
-
27
- def keyword_splat?
28
- @keyword_splat
29
- end
30
-
31
- def block?
32
- @block
33
- end
34
- end
35
- end
36
- end
@@ -1,13 +0,0 @@
1
- class Code
2
- class Node
3
- class StringCharacters < Node
4
- def initialize(characters)
5
- @characters = characters
6
- end
7
-
8
- def evaluate(**args)
9
- ::Code::Object::String.new(@characters.to_s)
10
- end
11
- end
12
- end
13
- end
@@ -1,23 +0,0 @@
1
- class Code
2
- class Node
3
- class StringComponent < Node
4
- def initialize(component)
5
- if component.key?(:characters)
6
- @component =
7
- ::Code::Node::StringCharacters.new(component.fetch(:characters))
8
- elsif component.key?(:interpolation)
9
- @component =
10
- ::Code::Node::StringInterpolation.new(
11
- component.fetch(:interpolation),
12
- )
13
- else
14
- raise NotImplementedError.new(component.inspect)
15
- end
16
- end
17
-
18
- def evaluate(**args)
19
- @component.evaluate(**args)
20
- end
21
- end
22
- end
23
- end
@@ -1,13 +0,0 @@
1
- class Code
2
- class Node
3
- class StringInterpolation < Node
4
- def initialize(interpolation)
5
- @interpolation = ::Code::Node::Code.new(interpolation)
6
- end
7
-
8
- def evaluate(**args)
9
- @interpolation.evaluate(**args)
10
- end
11
- end
12
- end
13
- end
@@ -1,20 +0,0 @@
1
- class Code
2
- class Parser
3
- class Defined < Parslet::Parser
4
- rule(:range) { ::Code::Parser::Range.new }
5
- rule(:name) { ::Code::Parser::Name.new }
6
-
7
- rule(:defined_keyword) { str("defined?") }
8
- rule(:opening_parenthesis) { str("(") }
9
- rule(:closing_parenthesis) { str(")") }
10
-
11
- rule(:defined) do
12
- (
13
- defined_keyword >> opening_parenthesis >> name >> closing_parenthesis
14
- ).as(:defined) | range
15
- end
16
-
17
- root(:defined)
18
- end
19
- end
20
- end
@@ -1,33 +0,0 @@
1
- class Code
2
- class Parser
3
- class GreaterThan < Parslet::Parser
4
- rule(:bitwise_or) { ::Code::Parser::BitwiseOr.new }
5
-
6
- rule(:right_caret) { str(">") }
7
- rule(:left_caret) { str("<") }
8
- rule(:equal) { str("=") }
9
-
10
- rule(:operator) do
11
- (right_caret >> equal) | (left_caret >> equal) | right_caret |
12
- left_caret
13
- end
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(:greater_than) do
21
- (
22
- bitwise_or.as(:first) >>
23
- (
24
- whitespace? >> operator.as(:operator) >> whitespace? >>
25
- bitwise_or.as(:statement)
26
- ).repeat(1).as(:rest)
27
- ).as(:greater_than) | bitwise_or
28
- end
29
-
30
- root(:greater_than)
31
- end
32
- end
33
- end
data/spec/call_spec.rb DELETED
@@ -1,22 +0,0 @@
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
@@ -1,63 +0,0 @@
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
- ].each do |input|
28
- context input.inspect do
29
- it "raises" do
30
- expect { ::Code.evaluate(input) }.to raise_error(described_class)
31
- end
32
- end
33
- end
34
- end
35
-
36
- describe "Decimal" do
37
- context "creating an integer with a non-number exponent" do
38
- it "raises" do
39
- expect { ::Code::Object::Decimal.new(1, exponent: "2") }.to raise_error(
40
- described_class,
41
- )
42
- end
43
- end
44
-
45
- [
46
- '1.0 / ""',
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
- ].each do |input|
56
- context input.inspect do
57
- it "raises" do
58
- expect { ::Code.evaluate(input) }.to raise_error(described_class)
59
- end
60
- end
61
- end
62
- end
63
- end
@@ -1,15 +0,0 @@
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
@@ -1,19 +0,0 @@
1
- require "spec_helper"
2
-
3
- RSpec.describe Code::Parser::Nothing do
4
- subject { described_class.new.parse(input) }
5
-
6
- [
7
- ["nothing", { nothing: "nothing" }],
8
- ["null", { nothing: "null" }],
9
- ["nil", { nothing: "nil" }],
10
- ].each do |(input, expected)|
11
- context input.inspect do
12
- let(:input) { input }
13
-
14
- it "succeeds" do
15
- expect(subject).to eq(expected)
16
- end
17
- end
18
- end
19
- end
data/spec/code_spec.rb DELETED
@@ -1,182 +0,0 @@
1
- require "spec_helper"
2
-
3
- RSpec.describe Code do
4
- let!(:input) { "" }
5
- let!(:context) { "" }
6
- let!(:io) { StringIO.new }
7
- let!(:timeout) { 0.1 }
8
- let!(:ruby) { {} }
9
-
10
- subject do
11
- Code.evaluate(input, context, io: io, timeout: timeout, ruby: ruby).to_s
12
- end
13
-
14
- [
15
- ["nothing", ""],
16
- ["null", ""],
17
- ["nil", ""],
18
- %w[true true],
19
- %w[false false],
20
- %w[1 1],
21
- %w[1.2 1.2],
22
- %w[0b10 2],
23
- %w[0o10 8],
24
- %w[0x10 16],
25
- %w[1e2 100],
26
- %w[1.2e2.2 190.1871830953336182242521644],
27
- %w[1e1e1 10000000000],
28
- %w['hello' hello],
29
- %w["hello" hello],
30
- ["[true, 1, nothing]", "[true, 1, nothing]"],
31
- ['{a: 1, "b": 2}', '{"a" => 1, "b" => 2}'],
32
- %w[!true false],
33
- %w[!!true true],
34
- %w[!!nothing false],
35
- %w[!!1 true],
36
- %w[+1 1],
37
- %w[++++1 1],
38
- ["++++nothing", ""],
39
- %w[+{} {}],
40
- ["2 ** 2", "4"],
41
- ["2 ** 2 ** 3", "256"],
42
- %w[-2 -2],
43
- %w[--2 2],
44
- ["2 * 3", "6"],
45
- ["1 / 2", "0.5"],
46
- ["1 / 2 / 2", "0.25"],
47
- ["12 % 10", "2"],
48
- ["8 / -2 ** 3", "-1.0"],
49
- ["1 + 2 * 3 + 4", "11"],
50
- ["1e1.1 * 2", "25.1785082358833442084790822"],
51
- ["1 / 3 * 3", "0.999999999999999999999999999999999999"],
52
- ['3 * "hello"', "hellohellohello"],
53
- ['"Go" + "od"', "Good"],
54
- ["1 << 2", "4"],
55
- ["4 >> 2", "1"],
56
- ["2 & 1", "0"],
57
- ["2 | 1", "3"],
58
- ["5 ^ 6", "3"],
59
- ["5 > 6", "false"],
60
- ["5 > 5", "false"],
61
- ["5 > 4", "true"],
62
- ["2 > 1 == 3 > 2", "true"],
63
- ["true && false", "false"],
64
- ["true || false", "true"],
65
- %w[1..3 1..3],
66
- ['1 > 3 ? "Impossible" : "Sounds about right"', "Sounds about right"],
67
- ['1 < 3 ? "OK"', "OK"],
68
- ['1 < "" rescue "oops"', "oops"],
69
- ['"fine" rescue "oops"', "fine"],
70
- ["a = 1", "1"],
71
- ["a = 1 a * 2", "2"],
72
- ["a = 1 a += 1 a", "2"],
73
- ["a = 1 a -= 1 a", "0"],
74
- %w[defined?(a) false],
75
- ["a = 1 defined?(a)", "true"],
76
- ["not true", "false"],
77
- ["not false", "true"],
78
- ["not not 1", "true"],
79
- ["1 or 2", "1"],
80
- ["true or false", "true"],
81
- ["1 and 2", "2"],
82
- ["false and 2", "false"],
83
- ["true and false", "false"],
84
- ["true and true", "true"],
85
- ["1 if false", ""],
86
- ["1 if true", "1"],
87
- ["1 if true if true", "1"],
88
- ["1 unless false", "1"],
89
- ["1 unless true", ""],
90
- ["a = 0 a += 1 while a < 10 a", "10"],
91
- ["a = 0 a += 1 until a > 10 a", "11"],
92
- ["if true 1 end", "1"],
93
- ["if false 1 end", ""],
94
- ["if false 1 else 2 end", "2"],
95
- ["unless false 1 end", "1"],
96
- ["unless true 1 end", ""],
97
- ["if false 1 else if true 2 else 3 end", "2"],
98
- ["if false 1 else if false 2 else 3 end", "3"],
99
- ["unless false 1 else if false 2 else 3 end", "1"],
100
- ["if false 1 else unless false 2 else 3 end", "2"],
101
- ["a = 0\n while a < 10 a += 1 end a", "10"],
102
- ["a = 0\n until a > 10 a += 1 end a", "11"],
103
- ["until true end", ""],
104
- ["until true\nend", ""],
105
- %w[("Good".."Bad").first Good],
106
- ['"Dorian " * 2', "Dorian Dorian "],
107
- ["while false end == nothing", "true"],
108
- ['"1 + 1 = {1 + 1}"', "1 + 1 = 2"],
109
- ["'1 + 1 = {1 + 1}'", "1 + 1 = 2"],
110
- ["{}.to_string + [].to_string", "{}[]"],
111
- ["'a' + 1", "a1"],
112
- ["'a' + 1.0", "a1.0"],
113
- ["1 + 'a'", "1a"],
114
- ["1.0 + 'a'", "1.0a"],
115
- ["1 << 1", "2"],
116
- ["1.0 << 1", "2"],
117
- ["1 << 1.0", "2"],
118
- ["1.0 << 1.0", "2"],
119
- ["eval('1 + 1')", "2"],
120
- ].each do |(input, expected)|
121
- context input.inspect do
122
- let(:input) { input }
123
-
124
- it "succeeds" do
125
- expect(subject).to eq(expected)
126
- end
127
- end
128
- end
129
-
130
- context "with ruby" do
131
- context "with a constant" do
132
- let!(:input) { "a + a" }
133
- let!(:ruby) { { a: 1 } }
134
-
135
- it "can access a" do
136
- expect(subject).to eq("2")
137
- end
138
- end
139
-
140
- context "with a function without arguments" do
141
- let!(:input) { "a + a" }
142
- let!(:ruby) { { a: ->{ "hello" } } }
143
-
144
- it "can call a" do
145
- expect(subject).to eq("hellohello")
146
- end
147
- end
148
-
149
- context "with a function with regular arguments" do
150
- let!(:input) { "add(1, 2)" }
151
- let!(:ruby) { { add: ->(a, b){ a + b } } }
152
-
153
- it "can call add" do
154
- expect(subject).to eq("3")
155
- end
156
- end
157
-
158
- context "with a function with keyword arguments" do
159
- let!(:input) { "add(a: 1, b: 2)" }
160
- let!(:ruby) { { add: ->(a:, b:){ a + b } } }
161
-
162
- it "can call add" do
163
- expect(subject).to eq("3")
164
- end
165
- end
166
-
167
- context "with a complex function" do
168
- let!(:input) { "add(1, 1, 1, 1, c: 1, d: 1, e: 1)" }
169
- let!(:ruby) do
170
- {
171
- add: ->(a, b = 1, *args, c:, d: 2, **kargs){
172
- a + b + args.sum + c + d + kargs.values.sum
173
- }
174
- }
175
- end
176
-
177
- it "can call add" do
178
- expect(subject).to eq("7")
179
- end
180
- end
181
- end
182
- end
@@ -1,26 +0,0 @@
1
- require "spec_helper"
2
-
3
- RSpec.describe Code do
4
- subject { described_class.evaluate(input).to_s }
5
-
6
- [
7
- ['hello = () => { "Hello" } hello', "Hello"],
8
- ["add = (a, b) => { a + b } add(1, 2)", "3"],
9
- ["add = (a:, b:) => { a + b } add(a: 1, b: 2)", "3"],
10
- ["add = (a = 1, b = 2) => { a + b } add", "3"],
11
- ["add = (a: 1, b: 2) => { a + b } add", "3"],
12
- ["add = (*args) => { args.first + args.last } add(1, 2)", "3"],
13
- [
14
- "add = (**kargs) => { kargs.values.first + kargs.values.last } add(a: 1, b: 2)",
15
- "3",
16
- ],
17
- ].each do |(input, expected)|
18
- context input.inspect do
19
- let(:input) { input }
20
-
21
- it "succeeds" do
22
- expect(subject).to eq(expected)
23
- end
24
- end
25
- end
26
- end
@@ -1,19 +0,0 @@
1
- require "spec_helper"
2
-
3
- RSpec.describe Template::Parser::Template do
4
- subject { described_class.new.parse(input) }
5
-
6
- [
7
- ["hello", [{ text: "hello" }]],
8
- ["hello {name}", [{ text: "hello " }, { code: [{ name: "name" }] }]],
9
- ["{name", [{ code: [{ name: "name" }] }]],
10
- ].each do |(input, expected)|
11
- context input.inspect do
12
- let(:input) { input }
13
-
14
- it "succeeds" do
15
- expect(subject).to eq(expected)
16
- end
17
- end
18
- end
19
- end
@@ -1,52 +0,0 @@
1
- require "spec_helper"
2
- require "prime"
3
-
4
- RSpec.describe Template do
5
- let!(:ruby) { {} }
6
- let!(:input_context) { "" }
7
- let!(:timeout) { 0 }
8
- subject { Template.render(input, input_context, ruby: ruby, timeout: timeout) }
9
-
10
- [
11
- ["Hello World", "", "Hello World"],
12
- ["1 + 1 = {2}", "", "1 + 1 = 2"],
13
- ["Hello {name}", '{ name: "Dorian" }', "Hello Dorian"],
14
- [
15
- "Hello {user.first_name}",
16
- '{ user: { first_name: "Dorian" } }',
17
- "Hello Dorian",
18
- ],
19
- ["{add(1, 2)", "add = (a, b) => { a + b } { add: context(:add) }", "3"],
20
- ["Hello {", "", "Hello "],
21
- ["{{a: 1}.each { |k, v| print(k) } nothing", "", "a"],
22
- ["{{a: 1}.each { |k, v| puts(k) } nothing", "", "a\n"],
23
- ["", "", ""],
24
- ].each do |(input, input_context, expected)|
25
- context "#{input.inspect} #{input_context.inspect}" do
26
- let(:input) { input }
27
- let(:input_context) { input_context }
28
-
29
- it "succeeds" do
30
- expect(subject).to eq(expected)
31
- end
32
- end
33
- end
34
-
35
- context "with a function from ruby" do
36
- let!(:ruby) { { prime: ->(n){ n.prime? } } }
37
- let!(:input) { "{prime(19201)" }
38
-
39
- it "calls the ruby function" do
40
- expect(subject).to eq("false")
41
- end
42
- end
43
-
44
- context "with a function from ruby in an object" do
45
- let!(:ruby) { { Prime: { prime: ->(n){ n.prime? } } } }
46
- let!(:input) { "{Prime.prime(19201)" }
47
-
48
- it "calls the ruby function" do
49
- expect(subject).to eq("false")
50
- end
51
- end
52
- end