code-ruby 0.4.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
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/publish +19 -0
  9. data/bin/template +62 -20
  10. data/bin/test +17 -0
  11. data/code-ruby.gemspec +1 -3
  12. data/docs/class.code +9 -0
  13. data/docs/euler/1.template +1 -5
  14. data/docs/euler/5.template +0 -1
  15. data/docs/meetup.code +12 -0
  16. data/docs/precedence.template +6 -39
  17. data/docs/rain.code +22 -0
  18. data/docs/slack.code +17 -0
  19. data/docs/stripe.code +7 -0
  20. data/docs/twitter.code +9 -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 +47 -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 +342 -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 +19 -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 +111 -72
  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,13 +0,0 @@
1
- class Code
2
- class Node
3
- class NotKeyword < Node
4
- def initialize(not_keyword)
5
- @statement = ::Code::Node::Statement.new(not_keyword)
6
- end
7
-
8
- def evaluate(**args)
9
- ::Code::Object::Boolean.new(!@statement.evaluate(**args).truthy?)
10
- end
11
- end
12
- end
13
- end
@@ -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