better_html 1.0.5 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 120de12348f0595aba1d9966e7643111a25e8ef8
4
- data.tar.gz: 1d1dd0f4e7e572392e51aa38186bf9bc5973d96c
3
+ metadata.gz: fbf85413b0af66cc73a928d1b37c0ba104c848ae
4
+ data.tar.gz: e934a9efa924f0647128517985f66d4dbd97f0de
5
5
  SHA512:
6
- metadata.gz: 3dcc692abe303950c191c74e3ed9b03481d13721416012ee7760e3b7b03830ef2199fc5d685200272d11fff02384f6394c926419b27243588d9b128981fb4ae4
7
- data.tar.gz: 83e8cfdbce133bad899a7d4b079e25424f0673c36f6bff6d78577a4822473e0da10027bd9023277775babeee1f50dc2dcd84a4edffd115820a064f44aa4f2429
6
+ metadata.gz: eb4ecf3184328d0388000db860f9126edad2e4a438c6c97623dbd29776d8f6a623fcbc5a24989c5fe47f0a92617eb0222738e28e5cae732d403a3bb805d3eb99
7
+ data.tar.gz: 5843b4928f2983d53e36e44053423b21286daf6b20cc1d7d5ddab3e3ceffe5f3c16f71a6849205732cd4c9e8776e4d86c299ca1603751da5a4056044eb653369
@@ -4,6 +4,7 @@ require_relative 'tokenizer/html_lodash'
4
4
  require_relative 'tokenizer/location'
5
5
  require_relative 'tokenizer/token_array'
6
6
  require_relative 'ast/node'
7
+ require 'parser/source/buffer'
7
8
 
8
9
  module BetterHtml
9
10
  class Parser
@@ -19,16 +20,17 @@ module BetterHtml
19
20
  end
20
21
  end
21
22
 
22
- def initialize(document, template_language: :html)
23
- @document = document
23
+ def initialize(buffer, template_language: :html)
24
+ raise ArgumentError, 'first argument must be Parser::Source::Buffer' unless buffer.is_a?(::Parser::Source::Buffer)
25
+ @buffer = buffer
24
26
  @template_language = template_language
25
27
  @erb = case template_language
26
28
  when :html
27
- Tokenizer::HtmlErb.new(@document)
29
+ Tokenizer::HtmlErb.new(@buffer)
28
30
  when :lodash
29
- Tokenizer::HtmlLodash.new(@document)
31
+ Tokenizer::HtmlLodash.new(@buffer)
30
32
  when :javascript
31
- Tokenizer::JavascriptErb.new(@document)
33
+ Tokenizer::JavascriptErb.new(@buffer)
32
34
  else
33
35
  raise ArgumentError, "template_language can be :html or :javascript"
34
36
  end
@@ -47,7 +49,7 @@ module BetterHtml
47
49
  @erb.parser.errors.map do |error|
48
50
  Error.new(
49
51
  error.message,
50
- location: Tokenizer::Location.new(@document, error.position, error.position + 1)
52
+ location: Tokenizer::Location.new(@buffer, error.position, error.position + 1)
51
53
  )
52
54
  end
53
55
  end
@@ -199,11 +201,11 @@ module BetterHtml
199
201
  def build_location(enumerable)
200
202
  enumerable = enumerable.compact
201
203
  raise ArgumentError, "cannot build location for #{enumerable.inspect}" unless enumerable.first && enumerable.last
202
- Tokenizer::Location.new(@document, enumerable.first.loc.start, enumerable.last.loc.stop)
204
+ Tokenizer::Location.new(@buffer, enumerable.first.loc.begin_pos, enumerable.last.loc.end_pos)
203
205
  end
204
206
 
205
207
  def empty_location
206
- Tokenizer::Location.new(@document, 0, 0)
208
+ Tokenizer::Location.new(@buffer, 0, 0)
207
209
  end
208
210
 
209
211
  def shift_all(tokens, *types)
@@ -158,9 +158,9 @@ module BetterHtml
158
158
 
159
159
  def nested_location(parent_node, ruby_node)
160
160
  Tokenizer::Location.new(
161
- parent_node.loc.document,
162
- parent_node.loc.start + ruby_node.loc.expression.begin_pos,
163
- parent_node.loc.start + ruby_node.loc.expression.end_pos - 1
161
+ parent_node.loc.source_buffer,
162
+ parent_node.loc.begin_pos + ruby_node.loc.expression.begin_pos,
163
+ parent_node.loc.begin_pos + ruby_node.loc.expression.end_pos
164
164
  )
165
165
  end
166
166
  end
@@ -37,7 +37,9 @@ EOF
37
37
  def assert_erb_safety(data, **options)
38
38
  options = options.present? ? options.dup : {}
39
39
  options[:template_language] ||= :html
40
- parser = BetterHtml::Parser.new(data, options)
40
+ buffer = ::Parser::Source::Buffer.new(options[:filename] || '(buffer)')
41
+ buffer.source = data
42
+ parser = BetterHtml::Parser.new(buffer, options)
41
43
 
42
44
  tester_classes = [
43
45
  SafeErb::NoStatements,
@@ -57,7 +59,7 @@ EOF
57
59
 
58
60
  messages = errors.map do |error|
59
61
  <<~EOL
60
- On line #{error.location.line}
62
+ In #{buffer.name}:#{error.location.line}
61
63
  #{error.message}
62
64
  #{error.location.line_source_with_underline}\n
63
65
  EOL
@@ -28,7 +28,9 @@ Never use <script> tags inside lodash template.
28
28
  EOF
29
29
 
30
30
  def assert_lodash_safety(data, **options)
31
- tester = Tester.new(data, **options)
31
+ buffer = ::Parser::Source::Buffer.new(options[:filename] || '(buffer)')
32
+ buffer.source = data
33
+ tester = Tester.new(buffer, **options)
32
34
 
33
35
  message = ""
34
36
  tester.errors.each do |error|
@@ -49,11 +51,11 @@ EOF
49
51
  class Tester
50
52
  attr_reader :errors
51
53
 
52
- def initialize(data, config: BetterHtml.config)
53
- @data = data
54
+ def initialize(buffer, config: BetterHtml.config)
55
+ @buffer = buffer
54
56
  @config = config
55
57
  @errors = Errors.new
56
- @parser = BetterHtml::Parser.new(data, template_language: :lodash)
58
+ @parser = BetterHtml::Parser.new(buffer, template_language: :lodash)
57
59
  validate!
58
60
  end
59
61
 
@@ -1,6 +1,7 @@
1
1
  require 'erubi'
2
2
  require_relative 'token'
3
3
  require_relative 'location'
4
+ require 'parser/source/buffer'
4
5
 
5
6
  module BetterHtml
6
7
  module Tokenizer
@@ -12,11 +13,12 @@ module BetterHtml
12
13
  attr_reader :tokens
13
14
  attr_reader :current_position
14
15
 
15
- def initialize(document)
16
- @document = document
16
+ def initialize(buffer)
17
+ raise ArgumentError, 'first argument must be Parser::Source::Buffer' unless buffer.is_a?(::Parser::Source::Buffer)
18
+ @buffer = buffer
17
19
  @tokens = []
18
20
  @current_position = 0
19
- super(document, regexp: REGEXP_WITHOUT_TRIM, trim: false)
21
+ super(buffer.source, regexp: REGEXP_WITHOUT_TRIM, trim: false)
20
22
  end
21
23
 
22
24
  private
@@ -66,10 +68,10 @@ module BetterHtml
66
68
  token = add_token(:erb_end, pos, pos + 2)
67
69
  end
68
70
 
69
- def add_token(type, start, stop)
71
+ def add_token(type, begin_pos, end_pos)
70
72
  token = Token.new(
71
73
  type: type,
72
- loc: Location.new(@document, start, stop - 1)
74
+ loc: Location.new(@buffer, begin_pos, end_pos)
73
75
  )
74
76
  @tokens << token
75
77
  token
@@ -6,9 +6,9 @@ module BetterHtml
6
6
  class HtmlErb < BaseErb
7
7
  attr_reader :parser
8
8
 
9
- def initialize(document)
9
+ def initialize(buffer)
10
10
  @parser = HtmlTokenizer::Parser.new
11
- super(document)
11
+ super(buffer)
12
12
  end
13
13
 
14
14
  def current_position
@@ -22,8 +22,8 @@ module BetterHtml
22
22
  end
23
23
 
24
24
  def add_text(text)
25
- @parser.parse(text) do |type, start, stop, _line, _column|
26
- add_token(type, start, stop)
25
+ @parser.parse(text) do |type, begin_pos, end_pos, _line, _column|
26
+ add_token(type, begin_pos, end_pos)
27
27
  end
28
28
  end
29
29
  end
@@ -13,9 +13,9 @@ module BetterHtml
13
13
  self.lodash_evaluate = %r{(?:\[\%)(.+?)(?:\%\])}m
14
14
  self.lodash_interpolate = %r{(?:\[\%)!(.+?)(?:\%\])}m
15
15
 
16
- def initialize(document)
17
- @document = document
18
- @scanner = StringScanner.new(document)
16
+ def initialize(buffer)
17
+ @buffer = buffer
18
+ @scanner = StringScanner.new(buffer.source)
19
19
  @parser = HtmlTokenizer::Parser.new
20
20
  @tokens = []
21
21
  scan!
@@ -43,7 +43,7 @@ module BetterHtml
43
43
  end
44
44
  @parser.append_placeholder(match)
45
45
  else
46
- text = @document[(@scanner.pos)..(@document.size)]
46
+ text = @buffer.source[(@scanner.pos)..(@buffer.source.size)]
47
47
  add_text(text) unless text.blank?
48
48
  break
49
49
  end
@@ -62,32 +62,32 @@ module BetterHtml
62
62
  end
63
63
 
64
64
  def add_text(text)
65
- @parser.parse(text) do |type, start, stop, _line, _column|
66
- add_token(type, start: start, stop: stop)
65
+ @parser.parse(text) do |type, begin_pos, end_pos, _line, _column|
66
+ add_token(type, begin_pos: begin_pos, end_pos: end_pos)
67
67
  end
68
68
  end
69
69
 
70
70
  def add_lodash_tokens(indicator, code)
71
71
  pos = @parser.document_length
72
72
 
73
- add_token(:lodash_begin, start: pos, stop: pos + 2)
73
+ add_token(:lodash_begin, begin_pos: pos, end_pos: pos + 2)
74
74
  pos += 2
75
75
 
76
76
  if indicator
77
- add_token(:indicator, start: pos, stop: pos + indicator.length)
77
+ add_token(:indicator, begin_pos: pos, end_pos: pos + indicator.length)
78
78
  pos += indicator.length
79
79
  end
80
80
 
81
- add_token(:code, start: pos, stop: pos + code.length)
81
+ add_token(:code, begin_pos: pos, end_pos: pos + code.length)
82
82
  pos += code.length
83
83
 
84
- add_token(:lodash_end, start: pos, stop: pos + 2)
84
+ add_token(:lodash_end, begin_pos: pos, end_pos: pos + 2)
85
85
  end
86
86
 
87
- def add_token(type, start: nil, stop: nil)
87
+ def add_token(type, begin_pos: nil, end_pos: nil)
88
88
  token = Token.new(
89
89
  type: type,
90
- loc: Location.new(@document, start, stop-1)
90
+ loc: Location.new(@buffer, begin_pos, end_pos)
91
91
  )
92
92
  @tokens << token
93
93
  token
@@ -1,76 +1,59 @@
1
+ require 'parser/source/buffer'
2
+ require 'parser/source/range'
3
+
1
4
  module BetterHtml
2
5
  module Tokenizer
3
- class Location
4
- attr_accessor :document, :start, :stop
5
-
6
- def initialize(document, start, stop)
7
- raise ArgumentError, "start location #{start} is out of range for document of size #{document.size}" if start > document.size
8
- raise ArgumentError, "stop location #{stop} is out of range for document of size #{document.size}" if stop > document.size
9
- raise ArgumentError, "end of range must be greater than start of range (#{stop} < #{start})" if stop < start
6
+ class Location < ::Parser::Source::Range
7
+ def initialize(buffer, begin_pos, end_pos)
8
+ raise ArgumentError, 'first argument must be Parser::Source::Buffer' unless buffer.is_a?(::Parser::Source::Buffer)
9
+ raise ArgumentError, "begin_pos location #{begin_pos} is out of range for document of size #{buffer.source.size}" if begin_pos > buffer.source.size
10
+ raise ArgumentError, "end_pos location #{end_pos} is out of range for document of size #{buffer.source.size}" if (end_pos - 1) > buffer.source.size
10
11
 
11
- @document = document
12
- @start = start
13
- @stop = stop
12
+ super(buffer, begin_pos, end_pos)
14
13
  end
15
14
 
16
15
  def range
17
- Range.new(start, stop)
16
+ Range.new(begin_pos, end_pos, true)
18
17
  end
19
18
 
20
19
  def line_range
21
20
  Range.new(start_line, stop_line)
22
21
  end
23
22
 
24
- def source
25
- @document[range]
26
- end
27
-
28
- def start_line
29
- @start_line ||= calculate_line(start)
30
- end
31
-
32
- def line
33
- start_line
34
- end
35
-
36
- def stop_line
37
- @stop_line ||= calculate_line(stop)
38
- end
23
+ alias_method :start_line, :line
24
+ alias_method :stop_line, :last_line
25
+ alias_method :start_column, :column
26
+ alias_method :stop_column, :last_column
39
27
 
40
- def start_column
41
- @start_column ||= calculate_column(start)
28
+ def line_source_with_underline
29
+ spaces = source_line.scan(/\A\s*/).first
30
+ column_without_spaces = [column - spaces.length, 0].max
31
+ underscore_length = [[end_pos - begin_pos, source_line.length - column_without_spaces].min, 1].max
32
+ "#{source_line.gsub(/\A\s*/, '')}\n#{' ' * column_without_spaces}#{'^' * underscore_length}"
42
33
  end
43
34
 
44
- def column
45
- start_column
35
+ def with(begin_pos: @begin_pos, end_pos: @end_pos)
36
+ self.class.new(@source_buffer, begin_pos, end_pos)
46
37
  end
47
38
 
48
- def stop_column
49
- @stop_column ||= calculate_column(stop)
39
+ def adjust(begin_pos: 0, end_pos: 0)
40
+ self.class.new(@source_buffer, @begin_pos + begin_pos, @end_pos + end_pos)
50
41
  end
51
42
 
52
- def line_source_with_underline
53
- line_content = extract_line(line: start_line)
54
- spaces = line_content.scan(/\A\s*/).first
55
- column_without_spaces = [column - spaces.length, 0].max
56
- underscore_length = [[stop - start + 1, line_content.length - column_without_spaces].min, 1].max
57
- "#{line_content.gsub(/\A\s*/, '')}\n#{' ' * column_without_spaces}#{'^' * underscore_length}"
43
+ def resize(new_size)
44
+ with(end_pos: @begin_pos + new_size)
58
45
  end
59
46
 
60
- private
61
-
62
- def calculate_line(pos)
63
- return 1 if pos == 0
64
- @document[0..pos-1].scan("\n").count + 1
47
+ def offset(offset)
48
+ with(begin_pos: offset + @begin_pos, end_pos: offset + @end_pos)
65
49
  end
66
50
 
67
- def calculate_column(pos)
68
- return 0 if pos == 0
69
- @document[0..pos-1]&.split("\n", -1)&.last&.length || 0
51
+ def begin
52
+ with(end_pos: @begin_pos)
70
53
  end
71
54
 
72
- def extract_line(line:)
73
- @document.split("\n", -1)[line - 1]&.gsub(/\n$/, '') || ""
55
+ def end
56
+ with(begin_pos: @end_pos)
74
57
  end
75
58
  end
76
59
  end
@@ -1,3 +1,3 @@
1
1
  module BetterHtml
2
- VERSION = "1.0.5"
2
+ VERSION = "1.0.6"
3
3
  end
@@ -7,17 +7,17 @@ module BetterHtml
7
7
  include ::AST::Sexp
8
8
 
9
9
  test "parse empty document" do
10
- tree = Parser.new('')
10
+ tree = Parser.new(buffer(''))
11
11
 
12
12
  assert_equal s(:document), tree.ast
13
13
  end
14
14
 
15
15
  test "parser errors" do
16
- tree = Parser.new('<>')
16
+ tree = Parser.new(buffer('<>'))
17
17
 
18
18
  assert_equal 1, tree.parser_errors.size
19
19
  assert_equal "expected '/' or tag name", tree.parser_errors[0].message
20
- assert_equal 1..2, tree.parser_errors[0].location.range
20
+ assert_equal 1...2, tree.parser_errors[0].location.range
21
21
  assert_equal <<~EOF.strip, tree.parser_errors[0].location.line_source_with_underline
22
22
  <>
23
23
  ^
@@ -26,7 +26,7 @@ module BetterHtml
26
26
 
27
27
  test "consume cdata nodes" do
28
28
  code = "<![CDATA[ foo ]]>"
29
- tree = Parser.new(code)
29
+ tree = Parser.new(buffer(code))
30
30
 
31
31
  assert_equal s(:document, s(:cdata, ' foo ')), tree.ast
32
32
  assert_equal code, tree.ast.loc.source
@@ -34,7 +34,7 @@ module BetterHtml
34
34
 
35
35
  test "unterminated cdata nodes are consumed until end" do
36
36
  code = "<![CDATA[ foo"
37
- tree = Parser.new(code)
37
+ tree = Parser.new(buffer(code))
38
38
 
39
39
  assert_equal s(:document, s(:cdata, ' foo')), tree.ast
40
40
  assert_equal code, tree.ast.loc.source
@@ -42,7 +42,7 @@ module BetterHtml
42
42
 
43
43
  test "consume cdata with interpolation" do
44
44
  code = "<![CDATA[ foo <%= bar %> baz ]]>"
45
- tree = Parser.new(code)
45
+ tree = Parser.new(buffer(code))
46
46
 
47
47
  assert_equal s(:document,
48
48
  s(:cdata,
@@ -55,19 +55,19 @@ module BetterHtml
55
55
  end
56
56
 
57
57
  test "consume comment nodes" do
58
- tree = Parser.new("<!-- foo -->")
58
+ tree = Parser.new(buffer("<!-- foo -->"))
59
59
 
60
60
  assert_equal s(:document, s(:comment, ' foo ')), tree.ast
61
61
  end
62
62
 
63
63
  test "unterminated comment nodes are consumed until end" do
64
- tree = Parser.new("<!-- foo")
64
+ tree = Parser.new(buffer("<!-- foo"))
65
65
 
66
66
  assert_equal s(:document, s(:comment, ' foo')), tree.ast
67
67
  end
68
68
 
69
69
  test "consume comment with interpolation" do
70
- tree = Parser.new("<!-- foo <%= bar %> baz -->")
70
+ tree = Parser.new(buffer("<!-- foo <%= bar %> baz -->"))
71
71
 
72
72
  assert_equal s(:document,
73
73
  s(:comment,
@@ -79,12 +79,12 @@ module BetterHtml
79
79
  end
80
80
 
81
81
  test "consume tag nodes" do
82
- tree = Parser.new("<div>")
82
+ tree = Parser.new(buffer("<div>"))
83
83
  assert_equal s(:document, s(:tag, nil, s(:tag_name, "div"), nil, nil)), tree.ast
84
84
  end
85
85
 
86
86
  test "tag without name" do
87
- tree = Parser.new("foo < bar")
87
+ tree = Parser.new(buffer("foo < bar"))
88
88
  assert_equal s(:document,
89
89
  s(:text, "foo "),
90
90
  s(:tag, nil, nil,
@@ -97,25 +97,25 @@ module BetterHtml
97
97
  end
98
98
 
99
99
  test "consume tag nodes with solidus" do
100
- tree = Parser.new("</div>")
100
+ tree = Parser.new(buffer("</div>"))
101
101
  assert_equal s(:document, s(:tag, s(:solidus), s(:tag_name, "div"), nil, nil)), tree.ast
102
102
  end
103
103
 
104
104
  test "sets self_closing when appropriate" do
105
- tree = Parser.new("<div/>")
105
+ tree = Parser.new(buffer("<div/>"))
106
106
  assert_equal s(:document, s(:tag, nil, s(:tag_name, "div"), nil, s(:solidus))), tree.ast
107
107
  end
108
108
 
109
109
  test "consume tag nodes until name ends" do
110
- tree = Parser.new("<div/>")
110
+ tree = Parser.new(buffer("<div/>"))
111
111
  assert_equal s(:document, s(:tag, nil, s(:tag_name, "div"), nil, s(:solidus))), tree.ast
112
112
 
113
- tree = Parser.new("<div ")
113
+ tree = Parser.new(buffer("<div "))
114
114
  assert_equal s(:document, s(:tag, nil, s(:tag_name, "div"), nil, nil)), tree.ast
115
115
  end
116
116
 
117
117
  test "consume tag nodes with interpolation" do
118
- tree = Parser.new("<ns:<%= name %>-thing>")
118
+ tree = Parser.new(buffer("<ns:<%= name %>-thing>"))
119
119
  assert_equal s(:document,
120
120
  s(:tag,
121
121
  nil,
@@ -126,7 +126,7 @@ module BetterHtml
126
126
  end
127
127
 
128
128
  test "consume tag attributes with erb" do
129
- tree = Parser.new("<div class=foo <%= erb %> name=bar>")
129
+ tree = Parser.new(buffer("<div class=foo <%= erb %> name=bar>"))
130
130
  assert_equal s(:document,
131
131
  s(:tag, nil,
132
132
  s(:tag_name, "div"),
@@ -149,7 +149,7 @@ module BetterHtml
149
149
  end
150
150
 
151
151
  test "consume tag attributes nodes unquoted value" do
152
- tree = Parser.new("<div foo=bar>")
152
+ tree = Parser.new(buffer("<div foo=bar>"))
153
153
  assert_equal s(:document,
154
154
  s(:tag, nil,
155
155
  s(:tag_name, "div"),
@@ -165,7 +165,7 @@ module BetterHtml
165
165
  end
166
166
 
167
167
  test "consume attributes without name" do
168
- tree = Parser.new("<div 'thing'>")
168
+ tree = Parser.new(buffer("<div 'thing'>"))
169
169
  assert_equal s(:document,
170
170
  s(:tag, nil,
171
171
  s(:tag_name, "div"),
@@ -181,7 +181,7 @@ module BetterHtml
181
181
  end
182
182
 
183
183
  test "consume tag attributes nodes quoted value" do
184
- tree = Parser.new("<div foo=\"bar\">")
184
+ tree = Parser.new(buffer("<div foo=\"bar\">"))
185
185
  assert_equal s(:document,
186
186
  s(:tag, nil,
187
187
  s(:tag_name, "div"),
@@ -197,7 +197,7 @@ module BetterHtml
197
197
  end
198
198
 
199
199
  test "consume tag attributes nodes interpolation in name and value" do
200
- tree = Parser.new("<div data-<%= foo %>=\"some <%= value %> foo\">")
200
+ tree = Parser.new(buffer("<div data-<%= foo %>=\"some <%= value %> foo\">"))
201
201
  assert_equal s(:document,
202
202
  s(:tag, nil,
203
203
  s(:tag_name, "div"),
@@ -219,7 +219,7 @@ module BetterHtml
219
219
  end
220
220
 
221
221
  test "consume text nodes" do
222
- tree = Parser.new("here is <%= some %> text")
222
+ tree = Parser.new(buffer("here is <%= some %> text"))
223
223
 
224
224
  assert_equal s(:document,
225
225
  s(:text,
@@ -230,7 +230,7 @@ module BetterHtml
230
230
  end
231
231
 
232
232
  test "javascript template parsing works" do
233
- tree = Parser.new("here is <%= some %> text", template_language: :javascript)
233
+ tree = Parser.new(buffer("here is <%= some %> text"), template_language: :javascript)
234
234
 
235
235
  assert_equal s(:document,
236
236
  s(:text,
@@ -241,7 +241,7 @@ module BetterHtml
241
241
  end
242
242
 
243
243
  test "javascript template does not consume html tags" do
244
- tree = Parser.new("<div <%= some %> />", template_language: :javascript)
244
+ tree = Parser.new(buffer("<div <%= some %> />"), template_language: :javascript)
245
245
 
246
246
  assert_equal s(:document,
247
247
  s(:text,
@@ -252,7 +252,7 @@ module BetterHtml
252
252
  end
253
253
 
254
254
  test "lodash template parsing works" do
255
- tree = Parser.new('<div class="[%= foo %]">', template_language: :lodash)
255
+ tree = Parser.new(buffer('<div class="[%= foo %]">'), template_language: :lodash)
256
256
 
257
257
  assert_equal s(:document,
258
258
  s(:tag,
@@ -275,7 +275,7 @@ module BetterHtml
275
275
  end
276
276
 
277
277
  test "nodes are all nested under document" do
278
- tree = Parser.new(<<~HTML)
278
+ tree = Parser.new(buffer(<<~HTML))
279
279
  some text
280
280
  <!-- a comment -->
281
281
  some more text
@@ -34,7 +34,7 @@ module BetterHtml
34
34
 
35
35
  private
36
36
  def validate(data, template_language: :html)
37
- parser = BetterHtml::Parser.new(data, template_language: template_language)
37
+ parser = BetterHtml::Parser.new(buffer(data), template_language: template_language)
38
38
  tester = BetterHtml::TestHelper::SafeErb::AllowedScriptType.new(parser, config: @config)
39
39
  tester.validate
40
40
  tester
@@ -26,7 +26,7 @@ module BetterHtml
26
26
 
27
27
  private
28
28
  def validate(data, template_language: :html)
29
- parser = BetterHtml::Parser.new(data, template_language: template_language)
29
+ parser = BetterHtml::Parser.new(buffer(data), template_language: template_language)
30
30
  tester = BetterHtml::TestHelper::SafeErb::NoJavascriptTagHelper.new(parser, config: @config)
31
31
  tester.validate
32
32
  tester
@@ -117,7 +117,7 @@ module BetterHtml
117
117
 
118
118
  private
119
119
  def validate(data, template_language: :html)
120
- parser = BetterHtml::Parser.new(data, template_language: template_language)
120
+ parser = BetterHtml::Parser.new(buffer(data), template_language: template_language)
121
121
  tester = BetterHtml::TestHelper::SafeErb::NoStatements.new(parser, config: @config)
122
122
  tester.validate
123
123
  tester
@@ -138,7 +138,7 @@ module BetterHtml
138
138
 
139
139
  private
140
140
  def validate(data, template_language: :html)
141
- parser = BetterHtml::Parser.new(data, template_language: template_language)
141
+ parser = BetterHtml::Parser.new(buffer(data), template_language: template_language)
142
142
  tester = BetterHtml::TestHelper::SafeErb::ScriptInterpolation.new(parser, config: @config)
143
143
  tester.validate
144
144
  tester
@@ -292,7 +292,7 @@ module BetterHtml
292
292
 
293
293
  private
294
294
  def validate(data, template_language: :html)
295
- parser = BetterHtml::Parser.new(data, template_language: template_language)
295
+ parser = BetterHtml::Parser.new(buffer(data), template_language: template_language)
296
296
  tester = BetterHtml::TestHelper::SafeErb::TagInterpolation.new(parser, config: @config)
297
297
  tester.validate
298
298
  tester
@@ -83,7 +83,7 @@ module BetterHtml
83
83
  private
84
84
 
85
85
  def parse(data)
86
- SafeLodashTester::Tester.new(data)
86
+ SafeLodashTester::Tester.new(buffer(data))
87
87
  end
88
88
  end
89
89
  end
@@ -5,92 +5,92 @@ module BetterHtml
5
5
  module Tokenizer
6
6
  class HtmlErbTest < ActiveSupport::TestCase
7
7
  test "text" do
8
- scanner = HtmlErb.new("just some text")
8
+ scanner = HtmlErb.new(buffer("just some text"))
9
9
  assert_equal 1, scanner.tokens.size
10
10
 
11
11
  assert_attributes ({
12
12
  type: :text,
13
- loc: { start: 0, stop: 13, source: 'just some text' }
13
+ loc: { begin_pos: 0, end_pos: 14, source: 'just some text' }
14
14
  }), scanner.tokens[0]
15
15
  end
16
16
 
17
17
  test "statement" do
18
- scanner = HtmlErb.new("<% statement %>")
18
+ scanner = HtmlErb.new(buffer("<% statement %>"))
19
19
  assert_equal 3, scanner.tokens.size
20
20
 
21
- assert_attributes ({ type: :erb_begin, loc: { start: 0, stop: 1, source: '<%' } }), scanner.tokens[0]
22
- assert_attributes ({ type: :code, loc: { start: 2, stop: 12, source: ' statement ' } }), scanner.tokens[1]
23
- assert_attributes ({ type: :erb_end, loc: { start: 13, stop: 14, source: '%>' } }), scanner.tokens[2]
21
+ assert_attributes ({ type: :erb_begin, loc: { begin_pos: 0, end_pos: 2, source: '<%' } }), scanner.tokens[0]
22
+ assert_attributes ({ type: :code, loc: { begin_pos: 2, end_pos: 13, source: ' statement ' } }), scanner.tokens[1]
23
+ assert_attributes ({ type: :erb_end, loc: { begin_pos: 13, end_pos: 15, source: '%>' } }), scanner.tokens[2]
24
24
  end
25
25
 
26
26
  test "debug statement" do
27
- scanner = HtmlErb.new("<%# statement %>")
27
+ scanner = HtmlErb.new(buffer("<%# statement %>"))
28
28
  assert_equal 4, scanner.tokens.size
29
29
 
30
- assert_attributes ({ type: :erb_begin, loc: { start: 0, stop: 1, source: '<%' } }), scanner.tokens[0]
31
- assert_attributes ({ type: :indicator, loc: { start: 2, stop: 2, source: '#' } }), scanner.tokens[1]
32
- assert_attributes ({ type: :code, loc: { start: 3, stop: 13, source: ' statement ' } }), scanner.tokens[2]
33
- assert_attributes ({ type: :erb_end, loc: { start: 14, stop: 15, source: '%>' } }), scanner.tokens[3]
30
+ assert_attributes ({ type: :erb_begin, loc: { begin_pos: 0, end_pos: 2, source: '<%' } }), scanner.tokens[0]
31
+ assert_attributes ({ type: :indicator, loc: { begin_pos: 2, end_pos: 3, source: '#' } }), scanner.tokens[1]
32
+ assert_attributes ({ type: :code, loc: { begin_pos: 3, end_pos: 14, source: ' statement ' } }), scanner.tokens[2]
33
+ assert_attributes ({ type: :erb_end, loc: { begin_pos: 14, end_pos: 16, source: '%>' } }), scanner.tokens[3]
34
34
  end
35
35
 
36
36
  test "when multi byte characters are present in erb" do
37
37
  code = "<% ui_helper 'your store’s' %>"
38
- scanner = HtmlErb.new(code)
38
+ scanner = HtmlErb.new(buffer(code))
39
39
  assert_equal 3, scanner.tokens.size
40
40
 
41
- assert_attributes ({ type: :erb_begin, loc: { start: 0, stop: 1, source: '<%' } }), scanner.tokens[0]
42
- assert_attributes ({ type: :code, loc: { start: 2, stop: 27, source: " ui_helper 'your store’s' " } }), scanner.tokens[1]
43
- assert_attributes ({ type: :erb_end, loc: { start: 28, stop: 29, source: '%>' } }), scanner.tokens[2]
41
+ assert_attributes ({ type: :erb_begin, loc: { begin_pos: 0, end_pos: 2, source: '<%' } }), scanner.tokens[0]
42
+ assert_attributes ({ type: :code, loc: { begin_pos: 2, end_pos: 28, source: " ui_helper 'your store’s' " } }), scanner.tokens[1]
43
+ assert_attributes ({ type: :erb_end, loc: { begin_pos: 28, end_pos: 30, source: '%>' } }), scanner.tokens[2]
44
44
  assert_equal code.length, scanner.current_position
45
45
  end
46
46
 
47
47
  test "when multi byte characters are present in text" do
48
48
  code = "your store’s"
49
- scanner = HtmlErb.new(code)
49
+ scanner = HtmlErb.new(buffer(code))
50
50
  assert_equal 1, scanner.tokens.size
51
51
 
52
- assert_attributes ({ type: :text, loc: { start: 0, stop: 11, source: 'your store’s' } }), scanner.tokens[0]
52
+ assert_attributes ({ type: :text, loc: { begin_pos: 0, end_pos: 12, source: 'your store’s' } }), scanner.tokens[0]
53
53
  assert_equal code.length, scanner.current_position
54
54
  end
55
55
 
56
56
  test "when multi byte characters are present in html" do
57
57
  code = "<div title='your store’s'>foo</div>"
58
- scanner = HtmlErb.new(code)
58
+ scanner = HtmlErb.new(buffer(code))
59
59
  assert_equal 14, scanner.tokens.size
60
60
 
61
- assert_attributes ({ type: :tag_start, loc: { start: 0, stop: 0, source: '<' } }), scanner.tokens[0]
62
- assert_attributes ({ type: :tag_name, loc: { start: 1, stop: 3, source: "div" } }), scanner.tokens[1]
63
- assert_attributes ({ type: :whitespace, loc: { start: 4, stop: 4, source: " " } }), scanner.tokens[2]
64
- assert_attributes ({ type: :attribute_name, loc: { start: 5, stop: 9, source: "title" } }), scanner.tokens[3]
65
- assert_attributes ({ type: :equal, loc: { start: 10, stop: 10, source: "=" } }), scanner.tokens[4]
66
- assert_attributes ({ type: :attribute_quoted_value_start, loc: { start: 11, stop: 11, source: "'" } }), scanner.tokens[5]
67
- assert_attributes ({ type: :attribute_quoted_value, loc: { start: 12, stop: 23, source: "your store’s" } }), scanner.tokens[6]
68
- assert_attributes ({ type: :attribute_quoted_value_end, loc: { start: 24, stop: 24, source: "'" } }), scanner.tokens[7]
61
+ assert_attributes ({ type: :tag_start, loc: { begin_pos: 0, end_pos: 1, source: '<' } }), scanner.tokens[0]
62
+ assert_attributes ({ type: :tag_name, loc: { begin_pos: 1, end_pos: 4, source: "div" } }), scanner.tokens[1]
63
+ assert_attributes ({ type: :whitespace, loc: { begin_pos: 4, end_pos: 5, source: " " } }), scanner.tokens[2]
64
+ assert_attributes ({ type: :attribute_name, loc: { begin_pos: 5, end_pos: 10, source: "title" } }), scanner.tokens[3]
65
+ assert_attributes ({ type: :equal, loc: { begin_pos: 10, end_pos: 11, source: "=" } }), scanner.tokens[4]
66
+ assert_attributes ({ type: :attribute_quoted_value_start, loc: { begin_pos: 11, end_pos: 12, source: "'" } }), scanner.tokens[5]
67
+ assert_attributes ({ type: :attribute_quoted_value, loc: { begin_pos: 12, end_pos: 24, source: "your store’s" } }), scanner.tokens[6]
68
+ assert_attributes ({ type: :attribute_quoted_value_end, loc: { begin_pos: 24, end_pos: 25, source: "'" } }), scanner.tokens[7]
69
69
  assert_equal code.length, scanner.current_position
70
70
  end
71
71
 
72
72
  test "expression literal" do
73
- scanner = HtmlErb.new("<%= literal %>")
73
+ scanner = HtmlErb.new(buffer("<%= literal %>"))
74
74
  assert_equal 4, scanner.tokens.size
75
75
 
76
- assert_attributes ({ type: :erb_begin, loc: { start: 0, stop: 1, source: '<%' } }), scanner.tokens[0]
77
- assert_attributes ({ type: :indicator, loc: { start: 2, stop: 2, source: '=' } }), scanner.tokens[1]
78
- assert_attributes ({ type: :code, loc: { start: 3, stop: 11, source: ' literal ' } }), scanner.tokens[2]
79
- assert_attributes ({ type: :erb_end, loc: { start: 12, stop: 13, source: '%>' } }), scanner.tokens[3]
76
+ assert_attributes ({ type: :erb_begin, loc: { begin_pos: 0, end_pos: 2, source: '<%' } }), scanner.tokens[0]
77
+ assert_attributes ({ type: :indicator, loc: { begin_pos: 2, end_pos: 3, source: '=' } }), scanner.tokens[1]
78
+ assert_attributes ({ type: :code, loc: { begin_pos: 3, end_pos: 12, source: ' literal ' } }), scanner.tokens[2]
79
+ assert_attributes ({ type: :erb_end, loc: { begin_pos: 12, end_pos: 14, source: '%>' } }), scanner.tokens[3]
80
80
  end
81
81
 
82
82
  test "expression escaped" do
83
- scanner = HtmlErb.new("<%== escaped %>")
83
+ scanner = HtmlErb.new(buffer("<%== escaped %>"))
84
84
  assert_equal 4, scanner.tokens.size
85
85
 
86
- assert_attributes ({ type: :erb_begin, loc: { start: 0, stop: 1, source: '<%' } }), scanner.tokens[0]
87
- assert_attributes ({ type: :indicator, loc: { start: 2, stop: 3, source: '==' } }), scanner.tokens[1]
88
- assert_attributes ({ type: :code, loc: { start: 4, stop: 12, source: ' escaped ' } }), scanner.tokens[2]
89
- assert_attributes ({ type: :erb_end, loc: { start: 13, stop: 14, source: '%>' } }), scanner.tokens[3]
86
+ assert_attributes ({ type: :erb_begin, loc: { begin_pos: 0, end_pos: 2, source: '<%' } }), scanner.tokens[0]
87
+ assert_attributes ({ type: :indicator, loc: { begin_pos: 2, end_pos: 4, source: '==' } }), scanner.tokens[1]
88
+ assert_attributes ({ type: :code, loc: { begin_pos: 4, end_pos: 13, source: ' escaped ' } }), scanner.tokens[2]
89
+ assert_attributes ({ type: :erb_end, loc: { begin_pos: 13, end_pos: 15, source: '%>' } }), scanner.tokens[3]
90
90
  end
91
91
 
92
92
  test "line number for multi-line statements" do
93
- scanner = HtmlErb.new("before <% multi\nline %> after")
93
+ scanner = HtmlErb.new(buffer("before <% multi\nline %> after"))
94
94
  assert_equal 5, scanner.tokens.size
95
95
 
96
96
  assert_attributes ({ type: :text, loc: { line: 1, source: 'before ' } }), scanner.tokens[0]
@@ -101,7 +101,7 @@ module BetterHtml
101
101
  end
102
102
 
103
103
  test "multi-line statements with trim" do
104
- scanner = HtmlErb.new("before\n<% multi\nline -%>\nafter")
104
+ scanner = HtmlErb.new(buffer("before\n<% multi\nline -%>\nafter"))
105
105
  assert_equal 7, scanner.tokens.size
106
106
 
107
107
  assert_attributes ({ type: :text, loc: { line: 1, source: "before\n" } }), scanner.tokens[0]
@@ -114,7 +114,7 @@ module BetterHtml
114
114
  end
115
115
 
116
116
  test "right trim with =%>" do
117
- scanner = HtmlErb.new("<% trim =%>")
117
+ scanner = HtmlErb.new(buffer("<% trim =%>"))
118
118
  assert_equal 4, scanner.tokens.size
119
119
 
120
120
  assert_attributes ({ type: :erb_begin, loc: { line: 1, source: '<%' } }), scanner.tokens[0]
@@ -124,7 +124,7 @@ module BetterHtml
124
124
  end
125
125
 
126
126
  test "multi-line expression with trim" do
127
- scanner = HtmlErb.new("before\n<%= multi\nline -%>\nafter")
127
+ scanner = HtmlErb.new(buffer("before\n<%= multi\nline -%>\nafter"))
128
128
  assert_equal 8, scanner.tokens.size
129
129
 
130
130
  assert_attributes ({ type: :text, loc: { line: 1, source: "before\n" } }), scanner.tokens[0]
@@ -138,7 +138,7 @@ module BetterHtml
138
138
  end
139
139
 
140
140
  test "line counts with comments" do
141
- scanner = HtmlErb.new("before\n<%# BO$$ Mode %>\nafter")
141
+ scanner = HtmlErb.new(buffer("before\n<%# BO$$ Mode %>\nafter"))
142
142
  assert_equal 7, scanner.tokens.size
143
143
 
144
144
  assert_attributes ({ type: :text, loc: { line: 1, source: "before\n" } }), scanner.tokens[0]
@@ -5,55 +5,55 @@ module BetterHtml
5
5
  module Tokenizer
6
6
  class HtmlLodashTest < ActiveSupport::TestCase
7
7
  test "matches text" do
8
- scanner = HtmlLodash.new("just some text")
8
+ scanner = HtmlLodash.new(buffer("just some text"))
9
9
  assert_equal 1, scanner.tokens.size
10
10
 
11
- assert_attributes ({ type: :text, loc: { start: 0, stop: 13, source: "just some text" } }), scanner.tokens[0]
11
+ assert_attributes ({ type: :text, loc: { begin_pos: 0, end_pos: 14, source: "just some text" } }), scanner.tokens[0]
12
12
  end
13
13
 
14
14
  test "matches strings to be escaped" do
15
- scanner = HtmlLodash.new("[%= foo %]")
15
+ scanner = HtmlLodash.new(buffer("[%= foo %]"))
16
16
  assert_equal 4, scanner.tokens.size
17
17
 
18
- assert_attributes ({ type: :lodash_begin, loc: { start: 0, stop: 1, source: "[%" } }), scanner.tokens[0]
19
- assert_attributes ({ type: :indicator, loc: { start: 2, stop: 2, source: "=" } }), scanner.tokens[1]
20
- assert_attributes ({ type: :code, loc: { start: 3, stop: 7, source: " foo " } }), scanner.tokens[2]
21
- assert_attributes ({ type: :lodash_end, loc: { start: 8, stop: 9, source: "%]" } }), scanner.tokens[3]
18
+ assert_attributes ({ type: :lodash_begin, loc: { begin_pos: 0, end_pos: 2, source: "[%" } }), scanner.tokens[0]
19
+ assert_attributes ({ type: :indicator, loc: { begin_pos: 2, end_pos: 3, source: "=" } }), scanner.tokens[1]
20
+ assert_attributes ({ type: :code, loc: { begin_pos: 3, end_pos: 8, source: " foo " } }), scanner.tokens[2]
21
+ assert_attributes ({ type: :lodash_end, loc: { begin_pos: 8, end_pos: 10, source: "%]" } }), scanner.tokens[3]
22
22
  end
23
23
 
24
24
  test "matches interpolate" do
25
- scanner = HtmlLodash.new("[%! foo %]")
25
+ scanner = HtmlLodash.new(buffer("[%! foo %]"))
26
26
  assert_equal 4, scanner.tokens.size
27
27
 
28
- assert_attributes ({ type: :lodash_begin, loc: { start: 0, stop: 1, source: "[%" } }), scanner.tokens[0]
29
- assert_attributes ({ type: :indicator, loc: { start: 2, stop: 2, source: "!" } }), scanner.tokens[1]
30
- assert_attributes ({ type: :code, loc: { start: 3, stop: 7, source: " foo " } }), scanner.tokens[2]
31
- assert_attributes ({ type: :lodash_end, loc: { start: 8, stop: 9, source: "%]" } }), scanner.tokens[3]
28
+ assert_attributes ({ type: :lodash_begin, loc: { begin_pos: 0, end_pos: 2, source: "[%" } }), scanner.tokens[0]
29
+ assert_attributes ({ type: :indicator, loc: { begin_pos: 2, end_pos: 3, source: "!" } }), scanner.tokens[1]
30
+ assert_attributes ({ type: :code, loc: { begin_pos: 3, end_pos: 8, source: " foo " } }), scanner.tokens[2]
31
+ assert_attributes ({ type: :lodash_end, loc: { begin_pos: 8, end_pos: 10, source: "%]" } }), scanner.tokens[3]
32
32
  end
33
33
 
34
34
  test "matches statement" do
35
- scanner = HtmlLodash.new("[% foo %]")
35
+ scanner = HtmlLodash.new(buffer("[% foo %]"))
36
36
  assert_equal 3, scanner.tokens.size
37
37
 
38
- assert_attributes ({ type: :lodash_begin, loc: { start: 0, stop: 1, source: "[%" } }), scanner.tokens[0]
39
- assert_attributes ({ type: :code, loc: { start: 2, stop: 6, source: " foo " } }), scanner.tokens[1]
40
- assert_attributes ({ type: :lodash_end, loc: { start: 7, stop: 8, source: "%]" } }), scanner.tokens[2]
38
+ assert_attributes ({ type: :lodash_begin, loc: { begin_pos: 0, end_pos: 2, source: "[%" } }), scanner.tokens[0]
39
+ assert_attributes ({ type: :code, loc: { begin_pos: 2, end_pos: 7, source: " foo " } }), scanner.tokens[1]
40
+ assert_attributes ({ type: :lodash_end, loc: { begin_pos: 7, end_pos: 9, source: "%]" } }), scanner.tokens[2]
41
41
  end
42
42
 
43
43
  test "matches text before and after" do
44
- scanner = HtmlLodash.new("before\n[%= foo %]\nafter")
44
+ scanner = HtmlLodash.new(buffer("before\n[%= foo %]\nafter"))
45
45
  assert_equal 6, scanner.tokens.size
46
46
 
47
- assert_attributes ({ type: :text, loc: { start: 0, stop: 6, source: "before\n" } }), scanner.tokens[0]
48
- assert_attributes ({ type: :lodash_begin, loc: { start: 7, stop: 8, source: "[%" } }), scanner.tokens[1]
49
- assert_attributes ({ type: :indicator, loc: { start: 9, stop: 9, source: "=" } }), scanner.tokens[2]
50
- assert_attributes ({ type: :code, loc: { start: 10, stop: 14, source: " foo " } }), scanner.tokens[3]
51
- assert_attributes ({ type: :lodash_end, loc: { start: 15, stop: 16, source: "%]" } }), scanner.tokens[4]
52
- assert_attributes ({ type: :text, loc: { start: 17, stop: 22, source: "\nafter" } }), scanner.tokens[5]
47
+ assert_attributes ({ type: :text, loc: { begin_pos: 0, end_pos: 7, source: "before\n" } }), scanner.tokens[0]
48
+ assert_attributes ({ type: :lodash_begin, loc: { begin_pos: 7, end_pos: 9, source: "[%" } }), scanner.tokens[1]
49
+ assert_attributes ({ type: :indicator, loc: { begin_pos: 9, end_pos: 10, source: "=" } }), scanner.tokens[2]
50
+ assert_attributes ({ type: :code, loc: { begin_pos: 10, end_pos: 15, source: " foo " } }), scanner.tokens[3]
51
+ assert_attributes ({ type: :lodash_end, loc: { begin_pos: 15, end_pos: 17, source: "%]" } }), scanner.tokens[4]
52
+ assert_attributes ({ type: :text, loc: { begin_pos: 17, end_pos: 23, source: "\nafter" } }), scanner.tokens[5]
53
53
  end
54
54
 
55
55
  test "matches multiple" do
56
- scanner = HtmlLodash.new("[% if() { %][%= foo %][% } %]")
56
+ scanner = HtmlLodash.new(buffer("[% if() { %][%= foo %][% } %]"))
57
57
  assert_equal 10, scanner.tokens.size
58
58
 
59
59
  assert_attributes ({ type: :lodash_begin, loc: { source: "[%" } }), scanner.tokens[0]
@@ -71,7 +71,7 @@ module BetterHtml
71
71
  end
72
72
 
73
73
  test "parses out html correctly" do
74
- scanner = HtmlLodash.new('<div class="[%= foo %]">')
74
+ scanner = HtmlLodash.new(buffer('<div class="[%= foo %]">'))
75
75
  assert_equal 12, scanner.tokens.size
76
76
  assert_equal [:tag_start, :tag_name, :whitespace, :attribute_name,
77
77
  :equal, :attribute_quoted_value_start,
@@ -6,37 +6,53 @@ module BetterHtml
6
6
  class LocationTest < ActiveSupport::TestCase
7
7
  test "location start out of bounds" do
8
8
  e = assert_raises(ArgumentError) do
9
- Location.new("foo", 5, 6)
9
+ Location.new(buffer("foo"), 5, 6)
10
10
  end
11
- assert_equal "start location 5 is out of range for document of size 3", e.message
11
+ assert_equal "begin_pos location 5 is out of range for document of size 3", e.message
12
12
  end
13
13
 
14
14
  test "location stop out of bounds" do
15
15
  e = assert_raises(ArgumentError) do
16
- Location.new("foo", 2, 6)
16
+ Location.new(buffer("foo"), 2, 6)
17
17
  end
18
- assert_equal "stop location 6 is out of range for document of size 3", e.message
18
+ assert_equal "end_pos location 6 is out of range for document of size 3", e.message
19
19
  end
20
20
 
21
21
  test "location stop < start" do
22
22
  e = assert_raises(ArgumentError) do
23
- Location.new("aaaaaa", 5, 2)
23
+ Location.new(buffer("aaaaaa"), 5, 2)
24
24
  end
25
- assert_equal "end of range must be greater than start of range (2 < 5)", e.message
25
+ assert_equal "Parser::Source::Range: end_pos must not be less than begin_pos", e.message
26
+ end
27
+
28
+ test "location stop == start" do
29
+ loc = Location.new(buffer("aaaaaa"), 5, 5)
30
+ assert_equal "", loc.source
31
+ assert_equal 0, loc.size
32
+ end
33
+
34
+ test "end_pos is stop+1" do
35
+ loc = Location.new(buffer("aaaaaa"), 5, 5)
36
+ assert_equal 5, loc.end_pos
37
+ end
38
+
39
+ test "range is exclusive of last char" do
40
+ loc = Location.new(buffer("aaaaaa"), 5, 5)
41
+ assert_equal 5...5, loc.range
26
42
  end
27
43
 
28
44
  test "location calulates start and stop line and column" do
29
- loc = Location.new("foo\nbar\nbaz", 5, 9)
45
+ loc = Location.new(buffer("foo\nbar\nbaz"), 5, 10)
30
46
 
31
47
  assert_equal "ar\nba", loc.source
32
48
  assert_equal 2, loc.start_line
33
49
  assert_equal 1, loc.start_column
34
50
  assert_equal 3, loc.stop_line
35
- assert_equal 1, loc.stop_column
51
+ assert_equal 2, loc.stop_column
36
52
  end
37
53
 
38
54
  test "line_source_with_underline" do
39
- loc = Location.new("ui_helper(foo)", 10, 12)
55
+ loc = Location.new(buffer("ui_helper(foo)"), 10, 13)
40
56
 
41
57
  assert_equal "foo", loc.source
42
58
  assert_equal <<~EOL.strip, loc.line_source_with_underline
@@ -46,7 +62,7 @@ module BetterHtml
46
62
  end
47
63
 
48
64
  test "line_source_with_underline removes empty spaces" do
49
- loc = Location.new(" \t ui_helper(foo)", 17, 19)
65
+ loc = Location.new(buffer(" \t ui_helper(foo)"), 17, 20)
50
66
 
51
67
  assert_equal "foo", loc.source
52
68
  assert_equal <<~EOL.strip, loc.line_source_with_underline
@@ -8,10 +8,11 @@ module BetterHtml
8
8
  class TokenArrayTest < ActiveSupport::TestCase
9
9
  setup do
10
10
  @document = "<x>"
11
+ @buffer = buffer(@document)
11
12
  @tokens = [
12
- Token.new(type: :lquote, loc: Location.new(@document, 0, 0)),
13
- Token.new(type: :name, loc: Location.new(@document, 1, 1)),
14
- Token.new(type: :rquote, loc: Location.new(@document, 2, 2)),
13
+ Token.new(type: :lquote, loc: Location.new(@buffer, 0, 0)),
14
+ Token.new(type: :name, loc: Location.new(@buffer, 1, 1)),
15
+ Token.new(type: :rquote, loc: Location.new(@buffer, 2, 2)),
15
16
  ]
16
17
  @array = TokenArray.new(@tokens)
17
18
  end
@@ -6,7 +6,7 @@ module BetterHtml
6
6
  module Tokenizer
7
7
  class TokenTest < ActiveSupport::TestCase
8
8
  test "token inspect" do
9
- loc = Location.new("foo", 0, 2)
9
+ loc = Location.new(buffer("foo"), 0, 3)
10
10
  token = Token.new(type: :foo, loc: loc)
11
11
  assert_equal "t(:foo, \"foo\")", token.inspect
12
12
  end
@@ -18,3 +18,13 @@ if ActiveSupport::TestCase.respond_to?(:fixture_path=)
18
18
  end
19
19
 
20
20
  require 'mocha/mini_test'
21
+
22
+ class ActiveSupport::TestCase
23
+ private
24
+
25
+ def buffer(string)
26
+ buffer = ::Parser::Source::Buffer.new('(test)')
27
+ buffer.source = string
28
+ buffer
29
+ end
30
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: better_html
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Francois Chagnon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-29 00:00:00.000000000 Z
11
+ date: 2018-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ast