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 +4 -4
- data/lib/better_html/parser.rb +10 -8
- data/lib/better_html/test_helper/safe_erb/tag_interpolation.rb +3 -3
- data/lib/better_html/test_helper/safe_erb_tester.rb +4 -2
- data/lib/better_html/test_helper/safe_lodash_tester.rb +6 -4
- data/lib/better_html/tokenizer/base_erb.rb +7 -5
- data/lib/better_html/tokenizer/html_erb.rb +4 -4
- data/lib/better_html/tokenizer/html_lodash.rb +12 -12
- data/lib/better_html/tokenizer/location.rb +31 -48
- data/lib/better_html/version.rb +1 -1
- data/test/better_html/parser_test.rb +26 -26
- data/test/better_html/test_helper/safe_erb/allowed_script_type_test.rb +1 -1
- data/test/better_html/test_helper/safe_erb/no_javascript_tag_helper_test.rb +1 -1
- data/test/better_html/test_helper/safe_erb/no_statements_test.rb +1 -1
- data/test/better_html/test_helper/safe_erb/script_interpolation_test.rb +1 -1
- data/test/better_html/test_helper/safe_erb/tag_interpolation_test.rb +1 -1
- data/test/better_html/test_helper/safe_lodash_tester_test.rb +1 -1
- data/test/better_html/tokenizer/html_erb_test.rb +41 -41
- data/test/better_html/tokenizer/html_lodash_test.rb +25 -25
- data/test/better_html/tokenizer/location_test.rb +26 -10
- data/test/better_html/tokenizer/token_array_test.rb +4 -3
- data/test/better_html/tokenizer/token_test.rb +1 -1
- data/test/test_helper.rb +10 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fbf85413b0af66cc73a928d1b37c0ba104c848ae
|
4
|
+
data.tar.gz: e934a9efa924f0647128517985f66d4dbd97f0de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb4ecf3184328d0388000db860f9126edad2e4a438c6c97623dbd29776d8f6a623fcbc5a24989c5fe47f0a92617eb0222738e28e5cae732d403a3bb805d3eb99
|
7
|
+
data.tar.gz: 5843b4928f2983d53e36e44053423b21286daf6b20cc1d7d5ddab3e3ceffe5f3c16f71a6849205732cd4c9e8776e4d86c299ca1603751da5a4056044eb653369
|
data/lib/better_html/parser.rb
CHANGED
@@ -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(
|
23
|
-
|
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(@
|
29
|
+
Tokenizer::HtmlErb.new(@buffer)
|
28
30
|
when :lodash
|
29
|
-
Tokenizer::HtmlLodash.new(@
|
31
|
+
Tokenizer::HtmlLodash.new(@buffer)
|
30
32
|
when :javascript
|
31
|
-
Tokenizer::JavascriptErb.new(@
|
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(@
|
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(@
|
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(@
|
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.
|
162
|
-
parent_node.loc.
|
163
|
-
parent_node.loc.
|
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
|
-
|
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
|
-
|
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
|
-
|
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(
|
53
|
-
@
|
54
|
+
def initialize(buffer, config: BetterHtml.config)
|
55
|
+
@buffer = buffer
|
54
56
|
@config = config
|
55
57
|
@errors = Errors.new
|
56
|
-
@parser = BetterHtml::Parser.new(
|
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(
|
16
|
-
|
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(
|
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,
|
71
|
+
def add_token(type, begin_pos, end_pos)
|
70
72
|
token = Token.new(
|
71
73
|
type: type,
|
72
|
-
loc: Location.new(@
|
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(
|
9
|
+
def initialize(buffer)
|
10
10
|
@parser = HtmlTokenizer::Parser.new
|
11
|
-
super(
|
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,
|
26
|
-
add_token(type,
|
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(
|
17
|
-
@
|
18
|
-
@scanner = StringScanner.new(
|
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 = @
|
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,
|
66
|
-
add_token(type,
|
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,
|
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,
|
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,
|
81
|
+
add_token(:code, begin_pos: pos, end_pos: pos + code.length)
|
82
82
|
pos += code.length
|
83
83
|
|
84
|
-
add_token(:lodash_end,
|
84
|
+
add_token(:lodash_end, begin_pos: pos, end_pos: pos + 2)
|
85
85
|
end
|
86
86
|
|
87
|
-
def add_token(type,
|
87
|
+
def add_token(type, begin_pos: nil, end_pos: nil)
|
88
88
|
token = Token.new(
|
89
89
|
type: type,
|
90
|
-
loc: Location.new(@
|
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
|
-
|
5
|
-
|
6
|
-
|
7
|
-
raise ArgumentError, "
|
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
|
-
|
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(
|
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
|
-
|
25
|
-
|
26
|
-
|
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
|
41
|
-
|
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
|
45
|
-
|
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
|
49
|
-
@
|
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
|
53
|
-
|
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
|
-
|
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
|
68
|
-
|
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
|
73
|
-
|
55
|
+
def end
|
56
|
+
with(begin_pos: @end_pos)
|
74
57
|
end
|
75
58
|
end
|
76
59
|
end
|
data/lib/better_html/version.rb
CHANGED
@@ -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
|
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
|
@@ -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: {
|
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: {
|
22
|
-
assert_attributes ({ type: :code, loc: {
|
23
|
-
assert_attributes ({ type: :erb_end, loc: {
|
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: {
|
31
|
-
assert_attributes ({ type: :indicator, loc: {
|
32
|
-
assert_attributes ({ type: :code, loc: {
|
33
|
-
assert_attributes ({ type: :erb_end, loc: {
|
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: {
|
42
|
-
assert_attributes ({ type: :code, loc: {
|
43
|
-
assert_attributes ({ type: :erb_end, loc: {
|
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: {
|
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: {
|
62
|
-
assert_attributes ({ type: :tag_name, loc: {
|
63
|
-
assert_attributes ({ type: :whitespace, loc: {
|
64
|
-
assert_attributes ({ type: :attribute_name, loc: {
|
65
|
-
assert_attributes ({ type: :equal, loc: {
|
66
|
-
assert_attributes ({ type: :attribute_quoted_value_start, loc: {
|
67
|
-
assert_attributes ({ type: :attribute_quoted_value, loc: {
|
68
|
-
assert_attributes ({ type: :attribute_quoted_value_end, loc: {
|
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: {
|
77
|
-
assert_attributes ({ type: :indicator, loc: {
|
78
|
-
assert_attributes ({ type: :code, loc: {
|
79
|
-
assert_attributes ({ type: :erb_end, loc: {
|
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: {
|
87
|
-
assert_attributes ({ type: :indicator, loc: {
|
88
|
-
assert_attributes ({ type: :code, loc: {
|
89
|
-
assert_attributes ({ type: :erb_end, loc: {
|
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: {
|
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: {
|
19
|
-
assert_attributes ({ type: :indicator, loc: {
|
20
|
-
assert_attributes ({ type: :code, loc: {
|
21
|
-
assert_attributes ({ type: :lodash_end, loc: {
|
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: {
|
29
|
-
assert_attributes ({ type: :indicator, loc: {
|
30
|
-
assert_attributes ({ type: :code, loc: {
|
31
|
-
assert_attributes ({ type: :lodash_end, loc: {
|
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: {
|
39
|
-
assert_attributes ({ type: :code, loc: {
|
40
|
-
assert_attributes ({ type: :lodash_end, loc: {
|
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: {
|
48
|
-
assert_attributes ({ type: :lodash_begin, loc: {
|
49
|
-
assert_attributes ({ type: :indicator, loc: {
|
50
|
-
assert_attributes ({ type: :code, loc: {
|
51
|
-
assert_attributes ({ type: :lodash_end, loc: {
|
52
|
-
assert_attributes ({ type: :text, loc: {
|
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 "
|
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 "
|
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 "
|
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,
|
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
|
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,
|
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,
|
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(@
|
13
|
-
Token.new(type: :name, loc: Location.new(@
|
14
|
-
Token.new(type: :rquote, loc: Location.new(@
|
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,
|
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
|
data/test/test_helper.rb
CHANGED
@@ -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.
|
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-
|
11
|
+
date: 2018-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ast
|