liquid 5.1.0 → 5.4.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 (98) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +35 -0
  3. data/README.md +4 -4
  4. data/lib/liquid/block_body.rb +6 -6
  5. data/lib/liquid/condition.rb +7 -1
  6. data/lib/liquid/context.rb +6 -2
  7. data/lib/liquid/expression.rb +11 -10
  8. data/lib/liquid/forloop_drop.rb +44 -1
  9. data/lib/liquid/locales/en.yml +6 -5
  10. data/lib/liquid/partial_cache.rb +3 -3
  11. data/lib/liquid/registers.rb +51 -0
  12. data/lib/liquid/standardfilters.rb +463 -75
  13. data/lib/liquid/strainer_factory.rb +15 -10
  14. data/lib/liquid/strainer_template.rb +9 -0
  15. data/lib/liquid/tablerowloop_drop.rb +58 -1
  16. data/lib/liquid/tags/assign.rb +12 -8
  17. data/lib/liquid/tags/break.rb +8 -0
  18. data/lib/liquid/tags/capture.rb +13 -10
  19. data/lib/liquid/tags/case.rb +21 -0
  20. data/lib/liquid/tags/comment.rb +13 -0
  21. data/lib/liquid/tags/continue.rb +8 -9
  22. data/lib/liquid/tags/cycle.rb +12 -11
  23. data/lib/liquid/tags/decrement.rb +16 -17
  24. data/lib/liquid/tags/echo.rb +16 -9
  25. data/lib/liquid/tags/for.rb +22 -43
  26. data/lib/liquid/tags/if.rb +11 -9
  27. data/lib/liquid/tags/include.rb +15 -13
  28. data/lib/liquid/tags/increment.rb +16 -14
  29. data/lib/liquid/tags/inline_comment.rb +43 -0
  30. data/lib/liquid/tags/raw.rb +11 -0
  31. data/lib/liquid/tags/render.rb +29 -4
  32. data/lib/liquid/tags/table_row.rb +22 -0
  33. data/lib/liquid/tags/unless.rb +15 -4
  34. data/lib/liquid/template.rb +2 -3
  35. data/lib/liquid/variable.rb +4 -4
  36. data/lib/liquid/variable_lookup.rb +10 -7
  37. data/lib/liquid/version.rb +1 -1
  38. data/lib/liquid.rb +4 -4
  39. metadata +7 -121
  40. data/lib/liquid/register.rb +0 -6
  41. data/lib/liquid/static_registers.rb +0 -44
  42. data/test/fixtures/en_locale.yml +0 -9
  43. data/test/integration/assign_test.rb +0 -117
  44. data/test/integration/blank_test.rb +0 -109
  45. data/test/integration/block_test.rb +0 -58
  46. data/test/integration/capture_test.rb +0 -58
  47. data/test/integration/context_test.rb +0 -636
  48. data/test/integration/document_test.rb +0 -21
  49. data/test/integration/drop_test.rb +0 -257
  50. data/test/integration/error_handling_test.rb +0 -272
  51. data/test/integration/expression_test.rb +0 -46
  52. data/test/integration/filter_test.rb +0 -189
  53. data/test/integration/hash_ordering_test.rb +0 -25
  54. data/test/integration/output_test.rb +0 -125
  55. data/test/integration/parsing_quirks_test.rb +0 -134
  56. data/test/integration/profiler_test.rb +0 -213
  57. data/test/integration/security_test.rb +0 -89
  58. data/test/integration/standard_filter_test.rb +0 -880
  59. data/test/integration/tag/disableable_test.rb +0 -59
  60. data/test/integration/tag_test.rb +0 -45
  61. data/test/integration/tags/break_tag_test.rb +0 -17
  62. data/test/integration/tags/continue_tag_test.rb +0 -17
  63. data/test/integration/tags/echo_test.rb +0 -13
  64. data/test/integration/tags/for_tag_test.rb +0 -466
  65. data/test/integration/tags/if_else_tag_test.rb +0 -190
  66. data/test/integration/tags/include_tag_test.rb +0 -269
  67. data/test/integration/tags/increment_tag_test.rb +0 -25
  68. data/test/integration/tags/liquid_tag_test.rb +0 -116
  69. data/test/integration/tags/raw_tag_test.rb +0 -34
  70. data/test/integration/tags/render_tag_test.rb +0 -213
  71. data/test/integration/tags/standard_tag_test.rb +0 -303
  72. data/test/integration/tags/statements_test.rb +0 -113
  73. data/test/integration/tags/table_row_test.rb +0 -66
  74. data/test/integration/tags/unless_else_tag_test.rb +0 -28
  75. data/test/integration/template_test.rb +0 -340
  76. data/test/integration/trim_mode_test.rb +0 -563
  77. data/test/integration/variable_test.rb +0 -138
  78. data/test/test_helper.rb +0 -207
  79. data/test/unit/block_unit_test.rb +0 -53
  80. data/test/unit/condition_unit_test.rb +0 -168
  81. data/test/unit/file_system_unit_test.rb +0 -37
  82. data/test/unit/i18n_unit_test.rb +0 -39
  83. data/test/unit/lexer_unit_test.rb +0 -53
  84. data/test/unit/parse_tree_visitor_test.rb +0 -261
  85. data/test/unit/parser_unit_test.rb +0 -84
  86. data/test/unit/partial_cache_unit_test.rb +0 -128
  87. data/test/unit/regexp_unit_test.rb +0 -46
  88. data/test/unit/static_registers_unit_test.rb +0 -156
  89. data/test/unit/strainer_factory_unit_test.rb +0 -100
  90. data/test/unit/strainer_template_unit_test.rb +0 -82
  91. data/test/unit/tag_unit_test.rb +0 -23
  92. data/test/unit/tags/case_tag_unit_test.rb +0 -12
  93. data/test/unit/tags/for_tag_unit_test.rb +0 -15
  94. data/test/unit/tags/if_tag_unit_test.rb +0 -10
  95. data/test/unit/template_factory_unit_test.rb +0 -12
  96. data/test/unit/template_unit_test.rb +0 -87
  97. data/test/unit/tokenizer_unit_test.rb +0 -62
  98. data/test/unit/variable_unit_test.rb +0 -164
data/test/test_helper.rb DELETED
@@ -1,207 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- ENV["MT_NO_EXPECTATIONS"] = "1"
5
- require 'minitest/autorun'
6
-
7
- $LOAD_PATH.unshift(File.join(File.expand_path(__dir__), '..', 'lib'))
8
- require 'liquid.rb'
9
- require 'liquid/profiler'
10
-
11
- mode = :strict
12
- if (env_mode = ENV['LIQUID_PARSER_MODE'])
13
- puts "-- #{env_mode.upcase} ERROR MODE"
14
- mode = env_mode.to_sym
15
- end
16
- Liquid::Template.error_mode = mode
17
-
18
- if ENV['LIQUID_C'] == '1'
19
- puts "-- LIQUID C"
20
- require 'liquid/c'
21
- end
22
-
23
- if Minitest.const_defined?('Test')
24
- # We're on Minitest 5+. Nothing to do here.
25
- else
26
- # Minitest 4 doesn't have Minitest::Test yet.
27
- Minitest::Test = MiniTest::Unit::TestCase
28
- end
29
-
30
- module Minitest
31
- class Test
32
- def fixture(name)
33
- File.join(File.expand_path(__dir__), "fixtures", name)
34
- end
35
- end
36
-
37
- module Assertions
38
- include Liquid
39
-
40
- def assert_template_result(expected, template, assigns = {}, message = nil)
41
- assert_equal(expected, Template.parse(template, line_numbers: true).render!(assigns), message)
42
- end
43
-
44
- def assert_template_result_matches(expected, template, assigns = {}, message = nil)
45
- return assert_template_result(expected, template, assigns, message) unless expected.is_a?(Regexp)
46
-
47
- assert_match(expected, Template.parse(template, line_numbers: true).render!(assigns), message)
48
- end
49
-
50
- def assert_match_syntax_error(match, template, assigns = {})
51
- exception = assert_raises(Liquid::SyntaxError) do
52
- Template.parse(template, line_numbers: true).render(assigns)
53
- end
54
- assert_match(match, exception.message)
55
- end
56
-
57
- def assert_usage_increment(name, times: 1)
58
- old_method = Liquid::Usage.method(:increment)
59
- calls = 0
60
- begin
61
- Liquid::Usage.singleton_class.send(:remove_method, :increment)
62
- Liquid::Usage.define_singleton_method(:increment) do |got_name|
63
- calls += 1 if got_name == name
64
- old_method.call(got_name)
65
- end
66
- yield
67
- ensure
68
- Liquid::Usage.singleton_class.send(:remove_method, :increment)
69
- Liquid::Usage.define_singleton_method(:increment, old_method)
70
- end
71
- assert_equal(times, calls, "Number of calls to Usage.increment with #{name.inspect}")
72
- end
73
-
74
- def with_global_filter(*globals)
75
- original_global_filters = Liquid::StrainerFactory.instance_variable_get(:@global_filters)
76
- Liquid::StrainerFactory.instance_variable_set(:@global_filters, [])
77
- globals.each do |global|
78
- Liquid::StrainerFactory.add_global_filter(global)
79
- end
80
-
81
- Liquid::StrainerFactory.send(:strainer_class_cache).clear
82
-
83
- globals.each do |global|
84
- Liquid::Template.register_filter(global)
85
- end
86
- yield
87
- ensure
88
- Liquid::StrainerFactory.send(:strainer_class_cache).clear
89
- Liquid::StrainerFactory.instance_variable_set(:@global_filters, original_global_filters)
90
- end
91
-
92
- def with_error_mode(mode)
93
- old_mode = Liquid::Template.error_mode
94
- Liquid::Template.error_mode = mode
95
- yield
96
- ensure
97
- Liquid::Template.error_mode = old_mode
98
- end
99
-
100
- def with_custom_tag(tag_name, tag_class)
101
- old_tag = Liquid::Template.tags[tag_name]
102
- begin
103
- Liquid::Template.register_tag(tag_name, tag_class)
104
- yield
105
- ensure
106
- if old_tag
107
- Liquid::Template.tags[tag_name] = old_tag
108
- else
109
- Liquid::Template.tags.delete(tag_name)
110
- end
111
- end
112
- end
113
- end
114
- end
115
-
116
- class ThingWithToLiquid
117
- def to_liquid
118
- 'foobar'
119
- end
120
- end
121
-
122
- class IntegerDrop < Liquid::Drop
123
- def initialize(value)
124
- super()
125
- @value = value.to_i
126
- end
127
-
128
- def ==(other)
129
- @value == other
130
- end
131
-
132
- def to_s
133
- @value.to_s
134
- end
135
-
136
- def to_liquid_value
137
- @value
138
- end
139
- end
140
-
141
- class BooleanDrop < Liquid::Drop
142
- def initialize(value)
143
- super()
144
- @value = value
145
- end
146
-
147
- def ==(other)
148
- @value == other
149
- end
150
-
151
- def to_liquid_value
152
- @value
153
- end
154
-
155
- def to_s
156
- @value ? "Yay" : "Nay"
157
- end
158
- end
159
-
160
- class ErrorDrop < Liquid::Drop
161
- def standard_error
162
- raise Liquid::StandardError, 'standard error'
163
- end
164
-
165
- def argument_error
166
- raise Liquid::ArgumentError, 'argument error'
167
- end
168
-
169
- def syntax_error
170
- raise Liquid::SyntaxError, 'syntax error'
171
- end
172
-
173
- def runtime_error
174
- raise 'runtime error'
175
- end
176
-
177
- def exception
178
- raise Exception, 'exception'
179
- end
180
- end
181
-
182
- class StubFileSystem
183
- attr_reader :file_read_count
184
-
185
- def initialize(values)
186
- @file_read_count = 0
187
- @values = values
188
- end
189
-
190
- def read_template_file(template_path)
191
- @file_read_count += 1
192
- @values.fetch(template_path)
193
- end
194
- end
195
-
196
- class StubTemplateFactory
197
- attr_reader :count
198
-
199
- def initialize
200
- @count = 0
201
- end
202
-
203
- def for(_template_name)
204
- @count += 1
205
- Liquid::Template.new
206
- end
207
- end
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'test_helper'
4
-
5
- class BlockUnitTest < Minitest::Test
6
- include Liquid
7
-
8
- def test_blankspace
9
- template = Liquid::Template.parse(" ")
10
- assert_equal([" "], template.root.nodelist)
11
- end
12
-
13
- def test_variable_beginning
14
- template = Liquid::Template.parse("{{funk}} ")
15
- assert_equal(2, template.root.nodelist.size)
16
- assert_equal(Variable, template.root.nodelist[0].class)
17
- assert_equal(String, template.root.nodelist[1].class)
18
- end
19
-
20
- def test_variable_end
21
- template = Liquid::Template.parse(" {{funk}}")
22
- assert_equal(2, template.root.nodelist.size)
23
- assert_equal(String, template.root.nodelist[0].class)
24
- assert_equal(Variable, template.root.nodelist[1].class)
25
- end
26
-
27
- def test_variable_middle
28
- template = Liquid::Template.parse(" {{funk}} ")
29
- assert_equal(3, template.root.nodelist.size)
30
- assert_equal(String, template.root.nodelist[0].class)
31
- assert_equal(Variable, template.root.nodelist[1].class)
32
- assert_equal(String, template.root.nodelist[2].class)
33
- end
34
-
35
- def test_variable_many_embedded_fragments
36
- template = Liquid::Template.parse(" {{funk}} {{so}} {{brother}} ")
37
- assert_equal(7, template.root.nodelist.size)
38
- assert_equal([String, Variable, String, Variable, String, Variable, String],
39
- block_types(template.root.nodelist))
40
- end
41
-
42
- def test_with_block
43
- template = Liquid::Template.parse(" {% comment %} {% endcomment %} ")
44
- assert_equal([String, Comment, String], block_types(template.root.nodelist))
45
- assert_equal(3, template.root.nodelist.size)
46
- end
47
-
48
- private
49
-
50
- def block_types(nodelist)
51
- nodelist.collect(&:class)
52
- end
53
- end
@@ -1,168 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'test_helper'
4
-
5
- class ConditionUnitTest < Minitest::Test
6
- include Liquid
7
-
8
- def setup
9
- @context = Liquid::Context.new
10
- end
11
-
12
- def test_basic_condition
13
- assert_equal(false, Condition.new(1, '==', 2).evaluate)
14
- assert_equal(true, Condition.new(1, '==', 1).evaluate)
15
- end
16
-
17
- def test_default_operators_evalute_true
18
- assert_evaluates_true(1, '==', 1)
19
- assert_evaluates_true(1, '!=', 2)
20
- assert_evaluates_true(1, '<>', 2)
21
- assert_evaluates_true(1, '<', 2)
22
- assert_evaluates_true(2, '>', 1)
23
- assert_evaluates_true(1, '>=', 1)
24
- assert_evaluates_true(2, '>=', 1)
25
- assert_evaluates_true(1, '<=', 2)
26
- assert_evaluates_true(1, '<=', 1)
27
- # negative numbers
28
- assert_evaluates_true(1, '>', -1)
29
- assert_evaluates_true(-1, '<', 1)
30
- assert_evaluates_true(1.0, '>', -1.0)
31
- assert_evaluates_true(-1.0, '<', 1.0)
32
- end
33
-
34
- def test_default_operators_evalute_false
35
- assert_evaluates_false(1, '==', 2)
36
- assert_evaluates_false(1, '!=', 1)
37
- assert_evaluates_false(1, '<>', 1)
38
- assert_evaluates_false(1, '<', 0)
39
- assert_evaluates_false(2, '>', 4)
40
- assert_evaluates_false(1, '>=', 3)
41
- assert_evaluates_false(2, '>=', 4)
42
- assert_evaluates_false(1, '<=', 0)
43
- assert_evaluates_false(1, '<=', 0)
44
- end
45
-
46
- def test_contains_works_on_strings
47
- assert_evaluates_true('bob', 'contains', 'o')
48
- assert_evaluates_true('bob', 'contains', 'b')
49
- assert_evaluates_true('bob', 'contains', 'bo')
50
- assert_evaluates_true('bob', 'contains', 'ob')
51
- assert_evaluates_true('bob', 'contains', 'bob')
52
-
53
- assert_evaluates_false('bob', 'contains', 'bob2')
54
- assert_evaluates_false('bob', 'contains', 'a')
55
- assert_evaluates_false('bob', 'contains', '---')
56
- end
57
-
58
- def test_invalid_comparation_operator
59
- assert_evaluates_argument_error(1, '~~', 0)
60
- end
61
-
62
- def test_comparation_of_int_and_str
63
- assert_evaluates_argument_error('1', '>', 0)
64
- assert_evaluates_argument_error('1', '<', 0)
65
- assert_evaluates_argument_error('1', '>=', 0)
66
- assert_evaluates_argument_error('1', '<=', 0)
67
- end
68
-
69
- def test_hash_compare_backwards_compatibility
70
- assert_nil(Condition.new({}, '>', 2).evaluate)
71
- assert_nil(Condition.new(2, '>', {}).evaluate)
72
- assert_equal(false, Condition.new({}, '==', 2).evaluate)
73
- assert_equal(true, Condition.new({ 'a' => 1 }, '==', 'a' => 1).evaluate)
74
- assert_equal(true, Condition.new({ 'a' => 2 }, 'contains', 'a').evaluate)
75
- end
76
-
77
- def test_contains_works_on_arrays
78
- @context = Liquid::Context.new
79
- @context['array'] = [1, 2, 3, 4, 5]
80
- array_expr = VariableLookup.new("array")
81
-
82
- assert_evaluates_false(array_expr, 'contains', 0)
83
- assert_evaluates_true(array_expr, 'contains', 1)
84
- assert_evaluates_true(array_expr, 'contains', 2)
85
- assert_evaluates_true(array_expr, 'contains', 3)
86
- assert_evaluates_true(array_expr, 'contains', 4)
87
- assert_evaluates_true(array_expr, 'contains', 5)
88
- assert_evaluates_false(array_expr, 'contains', 6)
89
- assert_evaluates_false(array_expr, 'contains', "1")
90
- end
91
-
92
- def test_contains_returns_false_for_nil_operands
93
- @context = Liquid::Context.new
94
- assert_evaluates_false(VariableLookup.new('not_assigned'), 'contains', '0')
95
- assert_evaluates_false(0, 'contains', VariableLookup.new('not_assigned'))
96
- end
97
-
98
- def test_contains_return_false_on_wrong_data_type
99
- assert_evaluates_false(1, 'contains', 0)
100
- end
101
-
102
- def test_contains_with_string_left_operand_coerces_right_operand_to_string
103
- assert_evaluates_true(' 1 ', 'contains', 1)
104
- assert_evaluates_false(' 1 ', 'contains', 2)
105
- end
106
-
107
- def test_or_condition
108
- condition = Condition.new(1, '==', 2)
109
-
110
- assert_equal(false, condition.evaluate)
111
-
112
- condition.or(Condition.new(2, '==', 1))
113
-
114
- assert_equal(false, condition.evaluate)
115
-
116
- condition.or(Condition.new(1, '==', 1))
117
-
118
- assert_equal(true, condition.evaluate)
119
- end
120
-
121
- def test_and_condition
122
- condition = Condition.new(1, '==', 1)
123
-
124
- assert_equal(true, condition.evaluate)
125
-
126
- condition.and(Condition.new(2, '==', 2))
127
-
128
- assert_equal(true, condition.evaluate)
129
-
130
- condition.and(Condition.new(2, '==', 1))
131
-
132
- assert_equal(false, condition.evaluate)
133
- end
134
-
135
- def test_should_allow_custom_proc_operator
136
- Condition.operators['starts_with'] = proc { |_cond, left, right| left =~ /^#{right}/ }
137
-
138
- assert_evaluates_true('bob', 'starts_with', 'b')
139
- assert_evaluates_false('bob', 'starts_with', 'o')
140
- ensure
141
- Condition.operators.delete('starts_with')
142
- end
143
-
144
- def test_left_or_right_may_contain_operators
145
- @context = Liquid::Context.new
146
- @context['one'] = @context['another'] = "gnomeslab-and-or-liquid"
147
-
148
- assert_evaluates_true(VariableLookup.new("one"), '==', VariableLookup.new("another"))
149
- end
150
-
151
- private
152
-
153
- def assert_evaluates_true(left, op, right)
154
- assert(Condition.new(left, op, right).evaluate(@context),
155
- "Evaluated false: #{left} #{op} #{right}")
156
- end
157
-
158
- def assert_evaluates_false(left, op, right)
159
- assert(!Condition.new(left, op, right).evaluate(@context),
160
- "Evaluated true: #{left} #{op} #{right}")
161
- end
162
-
163
- def assert_evaluates_argument_error(left, op, right)
164
- assert_raises(Liquid::ArgumentError) do
165
- Condition.new(left, op, right).evaluate(@context)
166
- end
167
- end
168
- end # ConditionTest
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'test_helper'
4
-
5
- class FileSystemUnitTest < Minitest::Test
6
- include Liquid
7
-
8
- def test_default
9
- assert_raises(FileSystemError) do
10
- BlankFileSystem.new.read_template_file("dummy")
11
- end
12
- end
13
-
14
- def test_local
15
- file_system = Liquid::LocalFileSystem.new("/some/path")
16
- assert_equal("/some/path/_mypartial.liquid", file_system.full_path("mypartial"))
17
- assert_equal("/some/path/dir/_mypartial.liquid", file_system.full_path("dir/mypartial"))
18
-
19
- assert_raises(FileSystemError) do
20
- file_system.full_path("../dir/mypartial")
21
- end
22
-
23
- assert_raises(FileSystemError) do
24
- file_system.full_path("/dir/../../dir/mypartial")
25
- end
26
-
27
- assert_raises(FileSystemError) do
28
- file_system.full_path("/etc/passwd")
29
- end
30
- end
31
-
32
- def test_custom_template_filename_patterns
33
- file_system = Liquid::LocalFileSystem.new("/some/path", "%s.html")
34
- assert_equal("/some/path/mypartial.html", file_system.full_path("mypartial"))
35
- assert_equal("/some/path/dir/mypartial.html", file_system.full_path("dir/mypartial"))
36
- end
37
- end # FileSystemTest
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'test_helper'
4
-
5
- class I18nUnitTest < Minitest::Test
6
- include Liquid
7
-
8
- def setup
9
- @i18n = I18n.new(fixture("en_locale.yml"))
10
- end
11
-
12
- def test_simple_translate_string
13
- assert_equal("less is more", @i18n.translate("simple"))
14
- end
15
-
16
- def test_nested_translate_string
17
- assert_equal("something wasn't right", @i18n.translate("errors.syntax.oops"))
18
- end
19
-
20
- def test_single_string_interpolation
21
- assert_equal("something different", @i18n.translate("whatever", something: "different"))
22
- end
23
-
24
- # def test_raises_translation_error_on_undefined_interpolation_key
25
- # assert_raises I18n::TranslationError do
26
- # @i18n.translate("whatever", :oopstypos => "yes")
27
- # end
28
- # end
29
-
30
- def test_raises_unknown_translation
31
- assert_raises(I18n::TranslationError) do
32
- @i18n.translate("doesnt_exist")
33
- end
34
- end
35
-
36
- def test_sets_default_path_to_en
37
- assert_equal(I18n::DEFAULT_LOCALE, I18n.new.path)
38
- end
39
- end
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'test_helper'
4
-
5
- class LexerUnitTest < Minitest::Test
6
- include Liquid
7
-
8
- def test_strings
9
- tokens = Lexer.new(%( 'this is a test""' "wat 'lol'")).tokenize
10
- assert_equal([[:string, %('this is a test""')], [:string, %("wat 'lol'")], [:end_of_string]], tokens)
11
- end
12
-
13
- def test_integer
14
- tokens = Lexer.new('hi 50').tokenize
15
- assert_equal([[:id, 'hi'], [:number, '50'], [:end_of_string]], tokens)
16
- end
17
-
18
- def test_float
19
- tokens = Lexer.new('hi 5.0').tokenize
20
- assert_equal([[:id, 'hi'], [:number, '5.0'], [:end_of_string]], tokens)
21
- end
22
-
23
- def test_comparison
24
- tokens = Lexer.new('== <> contains ').tokenize
25
- assert_equal([[:comparison, '=='], [:comparison, '<>'], [:comparison, 'contains'], [:end_of_string]], tokens)
26
- end
27
-
28
- def test_specials
29
- tokens = Lexer.new('| .:').tokenize
30
- assert_equal([[:pipe, '|'], [:dot, '.'], [:colon, ':'], [:end_of_string]], tokens)
31
- tokens = Lexer.new('[,]').tokenize
32
- assert_equal([[:open_square, '['], [:comma, ','], [:close_square, ']'], [:end_of_string]], tokens)
33
- end
34
-
35
- def test_fancy_identifiers
36
- tokens = Lexer.new('hi five?').tokenize
37
- assert_equal([[:id, 'hi'], [:id, 'five?'], [:end_of_string]], tokens)
38
-
39
- tokens = Lexer.new('2foo').tokenize
40
- assert_equal([[:number, '2'], [:id, 'foo'], [:end_of_string]], tokens)
41
- end
42
-
43
- def test_whitespace
44
- tokens = Lexer.new("five|\n\t ==").tokenize
45
- assert_equal([[:id, 'five'], [:pipe, '|'], [:comparison, '=='], [:end_of_string]], tokens)
46
- end
47
-
48
- def test_unexpected_character
49
- assert_raises(SyntaxError) do
50
- Lexer.new("%").tokenize
51
- end
52
- end
53
- end