synvert-core 1.23.0 → 1.24.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -1
- data/Gemfile.lock +3 -3
- data/lib/synvert/core/engine/elegant.rb +125 -0
- data/lib/synvert/core/engine/haml.rb +40 -55
- data/lib/synvert/core/engine/slim.rb +102 -0
- data/lib/synvert/core/engine.rb +3 -0
- data/lib/synvert/core/rewriter/scope/goto_scope.rb +1 -1
- data/lib/synvert/core/version.rb +1 -1
- data/lib/synvert/core.rb +4 -2
- data/spec/spec_helper.rb +1 -0
- data/spec/synvert/core/engine/haml_spec.rb +161 -3
- data/spec/synvert/core/engine/slim_spec.rb +223 -0
- data/spec/synvert/core/rewriter/instance_spec.rb +48 -0
- data/spec/synvert/core/rewriter/scope/goto_scope_spec.rb +15 -1
- data/synvert-core-ruby.gemspec +1 -1
- metadata +9 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b80b28538674cde89c7dc0098b53d736abb355874d4736654b48234c38c76e2b
|
4
|
+
data.tar.gz: 463e9b2616f07146ce551e904912dc2cbfb71e010ffa11eda8ff134c0ea1a5b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f25773c6887fe6b676dc1abd92df89b82dddab81e26841d3e1b566b1ab4f84666f7fde4563e864508814b49f7a54313014a88e412946b908e58976641a1223f
|
7
|
+
data.tar.gz: 13cadd41c39b742837a0b562626b1de9355e63f52f953133139f60c47f6341001f2442bca9276078bfdadea909ef5068db688444ed8e55ceaf9fc2511e7321d4
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,19 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 1.24.0 (2023-04-16)
|
4
|
+
|
5
|
+
* Add `Slim` engine
|
6
|
+
* Abstract `Engine/Elegant` module
|
7
|
+
* Rewrite `Haml` and `Slim` engine by StringScanner
|
8
|
+
|
9
|
+
## 1.23.1 (2023-04-06)
|
10
|
+
|
11
|
+
* Fix array index name in `GotoScope`
|
12
|
+
* Update `node_query` to 1.12.1
|
13
|
+
|
3
14
|
## 1.23.0 (2023-04-05)
|
4
15
|
|
5
|
-
* Add
|
16
|
+
* Add `Haml` engine
|
6
17
|
* Add `Engine.register` and `Engine.encode` and `Engine.generate_transform_proc`
|
7
18
|
* Set NodeMutation `transform_proc`
|
8
19
|
* Update `node_mutation` to 1.14.0
|
data/Gemfile.lock
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
synvert-core (1.
|
4
|
+
synvert-core (1.24.0)
|
5
5
|
activesupport (< 7.0.0)
|
6
6
|
node_mutation (>= 1.14.0)
|
7
|
-
node_query (>= 1.12.
|
7
|
+
node_query (>= 1.12.1)
|
8
8
|
parallel
|
9
9
|
parser
|
10
10
|
parser_node_ext (>= 1.0.0)
|
@@ -49,7 +49,7 @@ GEM
|
|
49
49
|
minitest (5.18.0)
|
50
50
|
nenv (0.3.0)
|
51
51
|
node_mutation (1.14.0)
|
52
|
-
node_query (1.12.
|
52
|
+
node_query (1.12.1)
|
53
53
|
notiffany (0.1.3)
|
54
54
|
nenv (~> 0.1)
|
55
55
|
shellany (~> 0.0)
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Synvert::Core
|
4
|
+
module Engine
|
5
|
+
# Engine::Elegant provides some helper methods for engines
|
6
|
+
# who read block code without end.
|
7
|
+
# For those engines, it will try to insert `end\n` when encode,
|
8
|
+
# while delete `end\n` when generate_transform_proc.
|
9
|
+
module Elegant
|
10
|
+
END_LINE = "end\n"
|
11
|
+
WHITESPACE = ' '
|
12
|
+
DO_BLOCK_REGEX = / do(\s|\z|\n)/
|
13
|
+
|
14
|
+
IF_KEYWORDS = %w[if unless begin case for while until]
|
15
|
+
ELSE_KEYWORDS = %w[else elsif when in rescue ensure]
|
16
|
+
|
17
|
+
# Generate transform proc, it's used to adjust start and end position of actions.
|
18
|
+
# Due to the fact that we insert `end\n` when encode the source code, we need to adjust
|
19
|
+
# start and end position of actions to match the original source code.
|
20
|
+
# e.g. if end\n exists in position 10, action start position is 20 and end position is 30,
|
21
|
+
# then action start position should be 16 and end position should be 26.
|
22
|
+
#
|
23
|
+
# @param encoded_source [String] encoded source.
|
24
|
+
# @return [Proc] transform proc.
|
25
|
+
def generate_transform_proc(encoded_source)
|
26
|
+
proc do |actions|
|
27
|
+
start = 0
|
28
|
+
indices = []
|
29
|
+
loop do
|
30
|
+
index = encoded_source[start..-1].index(END_LINE)
|
31
|
+
break unless index
|
32
|
+
|
33
|
+
indices << (start + index)
|
34
|
+
start += index + END_LINE.length
|
35
|
+
end
|
36
|
+
indices.each do |index|
|
37
|
+
actions.each do |action|
|
38
|
+
action.start -= END_LINE.length if action.start > index
|
39
|
+
action.end -= END_LINE.length if action.end > index
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Check if the current leading_spaces_count is less than or equal to the last leading_spaces_count in leading_spaces_counts.
|
46
|
+
# If so, pop the last leading_spaces_count and return true.
|
47
|
+
def insert_end?(leading_spaces_counts, current_leading_spaces_count, equal = true)
|
48
|
+
operation = equal ? :<= : :<
|
49
|
+
if !leading_spaces_counts.empty? && current_leading_spaces_count.send(operation, leading_spaces_counts.last)
|
50
|
+
leading_spaces_counts.pop
|
51
|
+
true
|
52
|
+
else
|
53
|
+
false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def scan_ruby_statement(scanner, new_code, leading_spaces_counts, leading_spaces_count)
|
58
|
+
new_code << scanner.scan(/\s*/)
|
59
|
+
keyword = scanner.scan(/\w+/)
|
60
|
+
rest = scanner.scan(/.*?(\z|\n)/)
|
61
|
+
if insert_end?(leading_spaces_counts, leading_spaces_count, !ELSE_KEYWORDS.include?(keyword))
|
62
|
+
new_code << END_LINE
|
63
|
+
end
|
64
|
+
if IF_KEYWORDS.include?(keyword) || rest =~ DO_BLOCK_REGEX
|
65
|
+
leading_spaces_counts << leading_spaces_count
|
66
|
+
end
|
67
|
+
new_code << keyword
|
68
|
+
new_code << rest
|
69
|
+
|
70
|
+
while rest.rstrip.end_with?(',')
|
71
|
+
rest = scanner.scan(/.*?(\z|\n)/)
|
72
|
+
new_code << rest
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def scan_ruby_expression(scanner, new_code, leading_spaces_counts, leading_spaces_count)
|
77
|
+
if insert_end?(leading_spaces_counts, leading_spaces_count)
|
78
|
+
new_code << END_LINE
|
79
|
+
end
|
80
|
+
rest = scanner.scan(/.*?(\z|\n)/)
|
81
|
+
if rest =~ DO_BLOCK_REGEX
|
82
|
+
leading_spaces_counts << leading_spaces_count
|
83
|
+
end
|
84
|
+
new_code << rest
|
85
|
+
|
86
|
+
while rest.rstrip.end_with?(',')
|
87
|
+
rest = scanner.scan(/.*?(\z|\n)/)
|
88
|
+
new_code << rest
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def scan_ruby_interpolation_and_plain_text(scanner, new_code, leading_spaces_counts, leading_spaces_count)
|
93
|
+
if insert_end?(leading_spaces_counts, leading_spaces_count)
|
94
|
+
new_code << END_LINE
|
95
|
+
end
|
96
|
+
while scanner.scan(/(.*?)(\\*)#\{/) # it matches interpolation " #{current_user.login}"
|
97
|
+
new_code << WHITESPACE * scanner.matched.size
|
98
|
+
unless scanner.matched[-3] == '\\'
|
99
|
+
count = 1
|
100
|
+
while scanner.scan(/.*?([\{\}])/)
|
101
|
+
if scanner.matched[-1] == '}'
|
102
|
+
count -= 1
|
103
|
+
if count == 0
|
104
|
+
new_code << scanner.matched[0..-2] + ';'
|
105
|
+
break
|
106
|
+
else
|
107
|
+
new_code << scanner.matched
|
108
|
+
end
|
109
|
+
else
|
110
|
+
count += 1
|
111
|
+
new_code << scanner.matched
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
if scanner.scan(/.*?\z/)
|
117
|
+
new_code << WHITESPACE * scanner.matched.size
|
118
|
+
end
|
119
|
+
if scanner.scan(/.*?\n/)
|
120
|
+
new_code << WHITESPACE * (scanner.matched.size - 1) + "\n"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -4,7 +4,7 @@ module Synvert::Core
|
|
4
4
|
module Engine
|
5
5
|
class Haml
|
6
6
|
class << self
|
7
|
-
|
7
|
+
include Elegant
|
8
8
|
|
9
9
|
# Encode haml string, leave only ruby code, replace other haml code with whitespace.
|
10
10
|
# And insert `end\n` for each if, unless, begin, case to make it a valid ruby code.
|
@@ -12,70 +12,55 @@ module Synvert::Core
|
|
12
12
|
# @param source [String] haml code.
|
13
13
|
# @return [String] encoded ruby code.
|
14
14
|
def encode(source)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
15
|
+
leading_spaces_counts = []
|
16
|
+
new_code = []
|
17
|
+
scanner = StringScanner.new(source)
|
18
|
+
loop do
|
19
|
+
new_code << scanner.scan(/\s*/)
|
20
|
+
leading_spaces_count = scanner.matched.size
|
21
|
+
if scanner.scan('-') # it matches ruby statement " - current_user"
|
22
|
+
new_code << WHITESPACE
|
23
|
+
scan_ruby_statement(scanner, new_code, leading_spaces_counts, leading_spaces_count)
|
24
|
+
elsif scanner.scan('=') # it matches ruby expression " = current_user.login"
|
25
|
+
new_code << WHITESPACE
|
26
|
+
scan_ruby_expression(scanner, new_code, leading_spaces_counts, leading_spaces_count)
|
27
|
+
elsif scanner.scan(/[%#\.][a-zA-Z0-9\-_%#\.]+/) # it matches element, id and class " %span.user"
|
28
|
+
new_code << WHITESPACE * scanner.matched.size
|
29
|
+
scan_matching_wrapper(scanner, new_code, '{', '}')
|
30
|
+
if scanner.scan('=')
|
31
|
+
new_code << WHITESPACE
|
32
|
+
scan_ruby_expression(scanner, new_code, leading_spaces_counts, leading_spaces_count)
|
25
33
|
else
|
26
|
-
|
27
|
-
code = (' ' * ($1.size + ($2 || '').size + 1)) + $3
|
28
|
-
new_line = check_and_insert_end(code, tab_sizes, $1.size)
|
29
|
-
tab_sizes.push($1.size) if line.include?(' do ')
|
30
|
-
new_line
|
31
|
-
elsif line =~ /\A(\s*)(.*)/ # match any other line
|
32
|
-
check_and_insert_end(' ' * line.size, tab_sizes, $1.size)
|
33
|
-
end
|
34
|
+
scan_ruby_interpolation_and_plain_text(scanner, new_code, leading_spaces_counts, leading_spaces_count)
|
34
35
|
end
|
36
|
+
else
|
37
|
+
scan_ruby_interpolation_and_plain_text(scanner, new_code, leading_spaces_counts, leading_spaces_count)
|
35
38
|
end
|
36
|
-
lines.push(END_LINE) unless tab_sizes.empty?
|
37
|
-
lines.join("\n")
|
38
|
-
end
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
# start and end position of actions to match the original source code.
|
43
|
-
# e.g. if end\n exists in position 10, action start position is 20 and end position is 30,
|
44
|
-
# then action start position should be 16 and end position should be 26.
|
45
|
-
#
|
46
|
-
# @param encoded_source [String] encoded source.
|
47
|
-
# @return [Proc] transform proc.
|
48
|
-
def generate_transform_proc(encoded_source)
|
49
|
-
proc do |actions|
|
50
|
-
start = 0
|
51
|
-
indices = []
|
52
|
-
loop do
|
53
|
-
index = encoded_source[start..-1].index(END_LINE)
|
54
|
-
break unless index
|
40
|
+
break if scanner.eos?
|
41
|
+
end
|
55
42
|
|
56
|
-
|
57
|
-
|
58
|
-
end
|
59
|
-
indices.each do |index|
|
60
|
-
actions.each do |action|
|
61
|
-
action.start -= END_LINE.length if action.start > index
|
62
|
-
action.end -= END_LINE.length if action.end > index
|
63
|
-
end
|
64
|
-
end
|
43
|
+
while leading_spaces_counts.pop
|
44
|
+
new_code << END_LINE
|
65
45
|
end
|
46
|
+
new_code.join
|
66
47
|
end
|
67
48
|
|
68
49
|
private
|
69
50
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
51
|
+
def scan_matching_wrapper(scanner, new_code, start, ending)
|
52
|
+
if scanner.scan(start) # it matches attributes " %span{:class => 'user'}"
|
53
|
+
new_code << start
|
54
|
+
count = 1
|
55
|
+
while scanner.scan(/.*?[#{Regexp.quote(start)}#{Regexp.quote(ending)}]/m)
|
56
|
+
new_code << scanner.matched
|
57
|
+
if scanner.matched[-1] == ending
|
58
|
+
count -= 1
|
59
|
+
break if count == 0
|
60
|
+
else
|
61
|
+
count += 1
|
62
|
+
end
|
63
|
+
end
|
79
64
|
end
|
80
65
|
end
|
81
66
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Synvert::Core
|
4
|
+
module Engine
|
5
|
+
class Slim
|
6
|
+
class << self
|
7
|
+
include Elegant
|
8
|
+
|
9
|
+
ATTRIBUTES_PAIR = {
|
10
|
+
'{' => '}',
|
11
|
+
'[' => ']',
|
12
|
+
'(' => ')'
|
13
|
+
}
|
14
|
+
|
15
|
+
# Encode haml string, leave only ruby code, replace other haml code with whitespace.
|
16
|
+
# And insert `end\n` for each if, unless, begin, case to make it a valid ruby code.
|
17
|
+
#
|
18
|
+
# @param source [String] haml code.
|
19
|
+
# @return [String] encoded ruby code.
|
20
|
+
def encode(source)
|
21
|
+
leading_spaces_counts = []
|
22
|
+
new_code = []
|
23
|
+
scanner = StringScanner.new(source)
|
24
|
+
loop do
|
25
|
+
new_code << scanner.scan(/\s*/)
|
26
|
+
leading_spaces_count = scanner.matched.size
|
27
|
+
if scanner.scan('-') # it matches ruby statement " - current_user"
|
28
|
+
new_code << WHITESPACE
|
29
|
+
scan_ruby_statement(scanner, new_code, leading_spaces_counts, leading_spaces_count)
|
30
|
+
elsif scanner.scan(/==?/) # it matches ruby expression " = current_user.login"
|
31
|
+
new_code << WHITESPACE * scanner.matched.size
|
32
|
+
scan_ruby_expression(scanner, new_code, leading_spaces_counts, leading_spaces_count)
|
33
|
+
elsif scanner.scan(/[a-z#\.][a-zA-Z0-9\-_%#\.]*/) # it matches element, id and class " span.user"
|
34
|
+
new_code << WHITESPACE * scanner.matched.size
|
35
|
+
ATTRIBUTES_PAIR.each do |start, ending| # it matches attributes in brackets " span[ class='user' ]"
|
36
|
+
scan_matching_wrapper(scanner, new_code, start, ending)
|
37
|
+
end
|
38
|
+
scan_attributes_between_whitespace(scanner, new_code)
|
39
|
+
if scanner.scan(/ ?==?/) # it matches ruby expression " span= current_user.login"
|
40
|
+
new_code << WHITESPACE * scanner.matched.size
|
41
|
+
scan_ruby_expression(scanner, new_code, leading_spaces_counts, leading_spaces_count)
|
42
|
+
else
|
43
|
+
scan_ruby_interpolation_and_plain_text(scanner, new_code, leading_spaces_counts, leading_spaces_count)
|
44
|
+
end
|
45
|
+
else
|
46
|
+
scan_ruby_interpolation_and_plain_text(scanner, new_code, leading_spaces_counts, leading_spaces_count)
|
47
|
+
end
|
48
|
+
|
49
|
+
break if scanner.eos?
|
50
|
+
end
|
51
|
+
|
52
|
+
while leading_spaces_counts.pop
|
53
|
+
new_code << END_LINE
|
54
|
+
end
|
55
|
+
new_code.join
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def scan_matching_wrapper(scanner, new_code, start, ending)
|
61
|
+
if scanner.scan(start) # it matches attributes " %span[ class='user' ]"
|
62
|
+
new_code << WHITESPACE
|
63
|
+
count = 1
|
64
|
+
while scanner.scan(/.*?[#{Regexp.quote(start)}#{Regexp.quote(ending)}]/m)
|
65
|
+
matched = scanner.matched.gsub(/(\A| ).*?=/) { |key| WHITESPACE * key.size }
|
66
|
+
if scanner.matched[-1] == ending
|
67
|
+
new_code << matched[0..-2] + ';'
|
68
|
+
count -= 1
|
69
|
+
break if count == 0
|
70
|
+
else
|
71
|
+
new_code << matched
|
72
|
+
count += 1
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def scan_attributes_between_whitespace(scanner, new_code)
|
79
|
+
while scanner.scan(/ ?[\w\-_]+==?/) # it matches attributes split by space " span class='user'"
|
80
|
+
new_code << WHITESPACE * scanner.matched.size
|
81
|
+
stack = []
|
82
|
+
while scanner.scan(/(.*?['"\(\)\[\]\{\}]|.+?\b)/)
|
83
|
+
matched = scanner.matched
|
84
|
+
new_code << matched
|
85
|
+
if ['(', '[', '{'].include?(matched[-1])
|
86
|
+
stack << matched[-1]
|
87
|
+
elsif [')', ']', '}'].include?(matched[-1])
|
88
|
+
stack.pop
|
89
|
+
elsif %w[' "].include?(matched[-1])
|
90
|
+
stack.last == matched[-1] ? stack.pop : stack << matched[-1]
|
91
|
+
end
|
92
|
+
break if stack.empty?
|
93
|
+
end
|
94
|
+
if scanner.scan(' ')
|
95
|
+
new_code << ';'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
data/lib/synvert/core/engine.rb
CHANGED
@@ -3,8 +3,10 @@
|
|
3
3
|
module Synvert::Core
|
4
4
|
# Engine defines how to encode / decode other files (like erb).
|
5
5
|
module Engine
|
6
|
+
autoload :Elegant, 'synvert/core/engine/elegant'
|
6
7
|
autoload :Erb, 'synvert/core/engine/erb'
|
7
8
|
autoload :Haml, 'synvert/core/engine/haml'
|
9
|
+
autoload :Slim, 'synvert/core/engine/slim'
|
8
10
|
|
9
11
|
# Register an engine
|
10
12
|
# @param [String] extension
|
@@ -36,4 +38,5 @@ module Synvert::Core
|
|
36
38
|
|
37
39
|
Engine.register('.erb', Engine::Erb)
|
38
40
|
Engine.register('.haml', Engine::Haml)
|
41
|
+
Engine.register('.slim', Engine::Slim)
|
39
42
|
end
|
@@ -20,7 +20,7 @@ module Synvert::Core
|
|
20
20
|
|
21
21
|
child_node = current_node
|
22
22
|
@child_node_name.to_s.split('.').each do |child_node_name|
|
23
|
-
child_node =
|
23
|
+
child_node = child_node.is_a?(Array) && child_node_name =~ /-?\d+/ ? child_node[child_node_name.to_i] : child_node.send(child_node_name)
|
24
24
|
end
|
25
25
|
if child_node.is_a?(Array)
|
26
26
|
child_node.each do |child_child_node|
|
data/lib/synvert/core/version.rb
CHANGED
data/lib/synvert/core.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'synvert/core/version'
|
4
4
|
require 'bundler'
|
5
|
+
require 'strscan'
|
5
6
|
require 'parser'
|
6
7
|
require 'parser/current'
|
7
8
|
require 'parser_node_ext'
|
@@ -29,8 +30,9 @@ module Synvert
|
|
29
30
|
ALL_RUBY_FILES = %w[**/*.rb]
|
30
31
|
ALL_ERB_FILES = %w[**/*.erb]
|
31
32
|
ALL_HAML_FILES = %w[**/*.haml]
|
33
|
+
ALL_SLIM_FILES = %w[**/*.slim]
|
32
34
|
ALL_RAKE_FILES = %w[**/*.rake]
|
33
|
-
ALL_FILES = ALL_RUBY_FILES + ALL_ERB_FILES + ALL_HAML_FILES + ALL_RAKE_FILES
|
35
|
+
ALL_FILES = ALL_RUBY_FILES + ALL_ERB_FILES + ALL_HAML_FILES + ALL_SLIM_FILES + ALL_RAKE_FILES
|
34
36
|
|
35
37
|
RAILS_APP_FILES = %w[app/**/*.rb engines/*/app/**/*.rb]
|
36
38
|
RAILS_CONTROLLER_FILES = %w[app/controllers/**/*.rb engines/*/app/controllers/**/*.rb]
|
@@ -47,7 +49,7 @@ module Synvert
|
|
47
49
|
engines/*/config/routes.rb
|
48
50
|
engines/*/config/routes/**/*.rb
|
49
51
|
]
|
50
|
-
RAILS_VIEW_FILES = ALL_ERB_FILES + ALL_HAML_FILES
|
52
|
+
RAILS_VIEW_FILES = ALL_ERB_FILES + ALL_HAML_FILES + ALL_SLIM_FILES
|
51
53
|
|
52
54
|
RAILS_CONTROLLER_TEST_FILES = %w[
|
53
55
|
test/functional/**/*.rb
|
data/spec/spec_helper.rb
CHANGED
@@ -17,11 +17,11 @@ module Synvert::Core
|
|
17
17
|
= "Hello!"
|
18
18
|
- if current_admin?
|
19
19
|
%strong= "Admin"
|
20
|
+
#error= error_message
|
21
|
+
.form-actions
|
22
|
+
= form_for @user do |f|
|
20
23
|
- elsif current_user?
|
21
24
|
%span= "User"
|
22
|
-
#error= error_message
|
23
|
-
.form-actions
|
24
|
-
= form_for @user do |f|
|
25
25
|
Test
|
26
26
|
EOS
|
27
27
|
encoded_source = Engine::Haml.encode(source)
|
@@ -43,6 +43,164 @@ module Synvert::Core
|
|
43
43
|
expect(encoded_source).not_to be_include 'Test'
|
44
44
|
expect(encoded_source).not_to be_include '.form-actions'
|
45
45
|
end
|
46
|
+
|
47
|
+
it 'encodes plain text' do
|
48
|
+
source = <<~EOS
|
49
|
+
%gee
|
50
|
+
%whiz
|
51
|
+
Wow this is cool!
|
52
|
+
EOS
|
53
|
+
encoded_source = Engine::Haml.encode(source)
|
54
|
+
expect(encoded_source).not_to be_include '%gee'
|
55
|
+
expect(encoded_source).not_to be_include '%whiz'
|
56
|
+
expect(encoded_source).not_to be_include 'Wow this is cool!'
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'encodes escaping' do
|
60
|
+
source = <<~EOS
|
61
|
+
%title
|
62
|
+
= @title
|
63
|
+
\\= @title
|
64
|
+
EOS
|
65
|
+
encoded_source = Engine::Haml.encode(source)
|
66
|
+
expect(encoded_source.scan('@title').length).to eq 1
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'encodes attributes' do
|
70
|
+
source = <<~EOS
|
71
|
+
%html{:xmlns => "http://www.w3.org/1999/xhtml", "xml:lang" => "en", :lang => "en"}
|
72
|
+
EOS
|
73
|
+
encoded_source = Engine::Haml.encode(source)
|
74
|
+
expect(encoded_source).to be_include '{:xmlns => "http://www.w3.org/1999/xhtml", "xml:lang" => "en", :lang => "en"}'
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'encodes multiple lines attributes' do
|
78
|
+
source = <<~EOS
|
79
|
+
%script{
|
80
|
+
"type": "text/javascript",
|
81
|
+
"src": "javascripts/script_9",
|
82
|
+
"data": {
|
83
|
+
"controller": "reporter",
|
84
|
+
},
|
85
|
+
}
|
86
|
+
EOS
|
87
|
+
encoded_source = Engine::Haml.encode(source)
|
88
|
+
expect(encoded_source).to be_include '"type": "text/javascript",'
|
89
|
+
expect(encoded_source).to be_include '"src": "javascripts/script_9",'
|
90
|
+
expect(encoded_source).to be_include '"controller": "reporter",'
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'encodes prefixed attributes' do
|
94
|
+
source = <<~EOS
|
95
|
+
%a{:href=>"/posts", :data => {:author_id => 123, :category => 7}} Posts By Author
|
96
|
+
EOS
|
97
|
+
encoded_source = Engine::Haml.encode(source)
|
98
|
+
expect(encoded_source).to be_include '{:href=>"/posts", :data => {:author_id => 123, :category => 7}}'
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'encodes class and ID' do
|
102
|
+
source = <<~EOS
|
103
|
+
%div#things
|
104
|
+
%span#rice Chicken Fried
|
105
|
+
%p.beans{ :food => 'true' } The magical fruit
|
106
|
+
%h1.class.otherclass#id La La La
|
107
|
+
EOS
|
108
|
+
encoded_source = Engine::Haml.encode(source)
|
109
|
+
expect(encoded_source).not_to be_include '%div'
|
110
|
+
expect(encoded_source).not_to be_include '#things'
|
111
|
+
expect(encoded_source).not_to be_include '.beans'
|
112
|
+
expect(encoded_source).not_to be_include '.class'
|
113
|
+
expect(encoded_source).not_to be_include '#id'
|
114
|
+
expect(encoded_source).to be_include "{ :food => 'true' }"
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'encodes haml comments' do
|
118
|
+
source = <<~EOS
|
119
|
+
%p foo
|
120
|
+
-# This is a comment
|
121
|
+
%p bar
|
122
|
+
EOS
|
123
|
+
encoded_source = Engine::Haml.encode(source)
|
124
|
+
expect(encoded_source).not_to be_include 'foo'
|
125
|
+
expect(encoded_source).not_to be_include 'bar'
|
126
|
+
expect(encoded_source).to be_include '# This is a comment'
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'encodes ruby evaluation' do
|
130
|
+
source = <<~EOS
|
131
|
+
%p
|
132
|
+
= ['hi', 'there', 'reader!'].join " "
|
133
|
+
= "yo"
|
134
|
+
EOS
|
135
|
+
encoded_source = Engine::Haml.encode(source)
|
136
|
+
expect(encoded_source).to be_include "['hi', 'there', 'reader!'].join \" \""
|
137
|
+
expect(encoded_source).to be_include '"yo"'
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'encodes ruby evaluation in the same line' do
|
141
|
+
source = <<~EOS
|
142
|
+
%p= "hello"
|
143
|
+
EOS
|
144
|
+
encoded_source = Engine::Haml.encode(source)
|
145
|
+
expect(encoded_source).not_to be_include '%p'
|
146
|
+
expect(encoded_source).to be_include '"hello"'
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'encodes multiple lines ruby evaluation' do
|
150
|
+
source = <<~EOS
|
151
|
+
= link_to_remote "Add to cart",
|
152
|
+
:url => { :action => "add", :id => product.id },
|
153
|
+
:update => { :success => "cart", :failure => "error" }
|
154
|
+
EOS
|
155
|
+
encoded_source = Engine::Haml.encode(source)
|
156
|
+
expect(encoded_source).to be_include 'link_to_remote "Add to cart",'
|
157
|
+
expect(encoded_source).to be_include ':url => { :action => "add", :id => product.id },'
|
158
|
+
expect(encoded_source).to be_include ':update => { :success => "cart", :failure => "error" }'
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'encodes running ruby' do
|
162
|
+
source = <<~EOS
|
163
|
+
- foo = "hello"
|
164
|
+
- foo << " there"
|
165
|
+
- foo << " you!"
|
166
|
+
EOS
|
167
|
+
encoded_source = Engine::Haml.encode(source)
|
168
|
+
expect(encoded_source).to be_include 'foo = "hello"'
|
169
|
+
expect(encoded_source).to be_include 'foo << " there"'
|
170
|
+
expect(encoded_source).to be_include 'foo << " you!"'
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'encodes multiple line running ruby' do
|
174
|
+
source = <<~EOS
|
175
|
+
- links = {:home => "/",
|
176
|
+
:docs => "/docs",
|
177
|
+
:about => "/about"}
|
178
|
+
EOS
|
179
|
+
encoded_source = Engine::Haml.encode(source)
|
180
|
+
expect(encoded_source).to be_include 'links = {:home => "/",'
|
181
|
+
expect(encoded_source).to be_include ':docs => "/docs",'
|
182
|
+
expect(encoded_source).to be_include ':about => "/about"}'
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'encodes ruby block' do
|
186
|
+
source = <<~EOS
|
187
|
+
- (42...47).each do |i|
|
188
|
+
%p= i
|
189
|
+
%p See, I can count!
|
190
|
+
EOS
|
191
|
+
encoded_source = Engine::Haml.encode(source)
|
192
|
+
expect(encoded_source).to be_include '(42...47).each do |i|'
|
193
|
+
expect(encoded_source).to be_include 'end'
|
194
|
+
expect(encoded_source).not_to be_include 'See, I can count!'
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'encodes ruby interpolation' do
|
198
|
+
source = 'Look at #{h word} lack of backslash: \#{foo}'
|
199
|
+
encoded_source = Engine::Haml.encode(source)
|
200
|
+
expect(encoded_source).to be_include 'h word;'
|
201
|
+
expect(encoded_source).not_to be_include 'foo'
|
202
|
+
expect(encoded_source).not_to be_include 'lack of backslash:'
|
203
|
+
end
|
46
204
|
end
|
47
205
|
|
48
206
|
describe '#generate_transform_proc' do
|
@@ -0,0 +1,223 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
module Synvert::Core
|
6
|
+
describe Engine::Slim do
|
7
|
+
describe '#encode' do
|
8
|
+
it 'encodes source' do
|
9
|
+
source = <<~EOS
|
10
|
+
doctype html
|
11
|
+
html
|
12
|
+
head
|
13
|
+
title Slim Examples
|
14
|
+
meta name="keywords" content="template language"
|
15
|
+
meta name="author" content=author
|
16
|
+
javascript:
|
17
|
+
alert('Slim supports embedded javascript!')
|
18
|
+
|
19
|
+
body
|
20
|
+
h1 Markup examples
|
21
|
+
|
22
|
+
#content
|
23
|
+
p This example shows you what a basic Slim file looks like.
|
24
|
+
|
25
|
+
== yield
|
26
|
+
|
27
|
+
- unless items.empty?
|
28
|
+
table
|
29
|
+
- items.each do |item|
|
30
|
+
tr
|
31
|
+
td.name = item.name
|
32
|
+
td.price = item.price
|
33
|
+
- else
|
34
|
+
p
|
35
|
+
| No items found. Please add some inventory.
|
36
|
+
Thank you!
|
37
|
+
|
38
|
+
div id="footer"
|
39
|
+
= render 'footer'
|
40
|
+
| Copyright © \#{year} \#{author}
|
41
|
+
EOS
|
42
|
+
encoded_source = Engine::Slim.encode(source)
|
43
|
+
expect(encoded_source).to be_include 'yield'
|
44
|
+
expect(encoded_source).to be_include 'unless items.empty?'
|
45
|
+
expect(encoded_source).to be_include 'items.each do |item|'
|
46
|
+
expect(encoded_source).to be_include 'item.name'
|
47
|
+
expect(encoded_source).to be_include 'item.price'
|
48
|
+
expect(encoded_source).to be_include "render 'footer'"
|
49
|
+
expect(encoded_source).to be_include 'year'
|
50
|
+
expect(encoded_source).to be_include 'author'
|
51
|
+
expect(encoded_source.scan("end\n").length).to eq 2
|
52
|
+
expect(encoded_source).not_to be_include 'html'
|
53
|
+
expect(encoded_source).not_to be_include 'meta'
|
54
|
+
expect(encoded_source).not_to be_include 'javascript:'
|
55
|
+
expect(encoded_source).not_to be_include 'Markup examples'
|
56
|
+
expect(encoded_source).not_to be_include 'td.name'
|
57
|
+
expect(encoded_source).not_to be_include 'td.price'
|
58
|
+
expect(encoded_source).not_to be_include 'Copyright'
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'encodes control code' do
|
62
|
+
source = <<~EOS
|
63
|
+
body
|
64
|
+
- if articles.empty?
|
65
|
+
| No inventory
|
66
|
+
EOS
|
67
|
+
encoded_source = Engine::Slim.encode(source)
|
68
|
+
expect(encoded_source).to be_include 'if articles.empty?'
|
69
|
+
expect(encoded_source).to be_include 'end'
|
70
|
+
expect(encoded_source).not_to be_include 'No inventory'
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'encodes output' do
|
74
|
+
source = <<~EOS
|
75
|
+
= javascript_include_tag \
|
76
|
+
"jquery",
|
77
|
+
"application"
|
78
|
+
EOS
|
79
|
+
encoded_source = Engine::Slim.encode(source)
|
80
|
+
expect(encoded_source).to be_include 'javascript_include_tag'
|
81
|
+
expect(encoded_source).to be_include '"jquery",'
|
82
|
+
expect(encoded_source).to be_include '"application"'
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'encodes output without html escaping' do
|
86
|
+
source = <<~EOS
|
87
|
+
== yield
|
88
|
+
EOS
|
89
|
+
encoded_source = Engine::Slim.encode(source)
|
90
|
+
expect(encoded_source).to be_include 'yield'
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'encodes tags' do
|
94
|
+
source = <<~EOS
|
95
|
+
ul
|
96
|
+
li.first: a href="/a" A link
|
97
|
+
li: a href="/b" B link
|
98
|
+
EOS
|
99
|
+
encoded_source = Engine::Slim.encode(source)
|
100
|
+
expect(encoded_source).not_to be_include 'ul'
|
101
|
+
expect(encoded_source).not_to be_include 'li'
|
102
|
+
expect(encoded_source).not_to be_include 'first'
|
103
|
+
expect(encoded_source).not_to be_include 'link'
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'encodes text content' do
|
107
|
+
source = <<~EOS
|
108
|
+
body
|
109
|
+
h1 id="headline" Welcome to my site.
|
110
|
+
EOS
|
111
|
+
encoded_source = Engine::Slim.encode(source)
|
112
|
+
expect(encoded_source).not_to be_include 'h1'
|
113
|
+
expect(encoded_source).not_to be_include 'id'
|
114
|
+
expect(encoded_source).not_to be_include 'Welcome'
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'encodes dynamic content' do
|
118
|
+
source = <<~EOS
|
119
|
+
body
|
120
|
+
h1 id="headline" = page_headline
|
121
|
+
EOS
|
122
|
+
encoded_source = Engine::Slim.encode(source)
|
123
|
+
expect(encoded_source).to be_include 'page_headline'
|
124
|
+
expect(encoded_source).not_to be_include 'h1'
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'encodes attributes wrapper' do
|
128
|
+
source = <<~EOS
|
129
|
+
body
|
130
|
+
h1(id="logo") = page_logo
|
131
|
+
h2[id="tagline" class="small tagline"] = page_tagline
|
132
|
+
EOS
|
133
|
+
encoded_source = Engine::Slim.encode(source)
|
134
|
+
expect(encoded_source).to be_include 'page_logo'
|
135
|
+
expect(encoded_source).to be_include 'page_tagline'
|
136
|
+
expect(encoded_source).not_to be_include 'h1'
|
137
|
+
expect(encoded_source).not_to be_include 'h2'
|
138
|
+
expect(encoded_source).not_to be_include 'id'
|
139
|
+
expect(encoded_source).not_to be_include 'class'
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'encodes multiple lines attributes wrapper' do
|
143
|
+
source = <<~EOS
|
144
|
+
h2[id="tagline"
|
145
|
+
class="small tagline"] = page_tagline
|
146
|
+
EOS
|
147
|
+
encoded_source = Engine::Slim.encode(source)
|
148
|
+
expect(encoded_source).to be_include 'page_tagline'
|
149
|
+
expect(encoded_source).not_to be_include 'h2'
|
150
|
+
expect(encoded_source).not_to be_include 'id'
|
151
|
+
expect(encoded_source).not_to be_include 'class'
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'encodes ruby attributes' do
|
155
|
+
source = <<~EOS
|
156
|
+
body
|
157
|
+
table
|
158
|
+
- for user in users
|
159
|
+
td id="user_\#{user.id}" class=user.role
|
160
|
+
a href=user_action(user, :edit) Edit \#{user.first_name}
|
161
|
+
a href=(path_to_user user) = user.last_name
|
162
|
+
EOS
|
163
|
+
encoded_source = Engine::Slim.encode(source)
|
164
|
+
expect(encoded_source).to be_include 'for user in users'
|
165
|
+
expect(encoded_source).to be_include 'user.id'
|
166
|
+
expect(encoded_source).to be_include 'user_action(user, :edit)'
|
167
|
+
expect(encoded_source).to be_include 'user.first_name'
|
168
|
+
expect(encoded_source).to be_include '(path_to_user user)'
|
169
|
+
expect(encoded_source).to be_include 'user.last_name'
|
170
|
+
expect(encoded_source).to be_include 'end'
|
171
|
+
expect(encoded_source).not_to be_include 'href'
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'encodes ruby attributes with ==' do
|
175
|
+
source = 'a href==action_path(:start)'
|
176
|
+
encoded_source = Engine::Slim.encode(source)
|
177
|
+
expect(encoded_source).to be_include 'action_path(:start)'
|
178
|
+
expect(encoded_source).not_to be_include 'href'
|
179
|
+
expect(encoded_source).not_to be_include '='
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'encodes text interpolation' do
|
183
|
+
source = <<~EOS
|
184
|
+
body
|
185
|
+
h1 Welcome \#{current_user.name} to the show.
|
186
|
+
EOS
|
187
|
+
encoded_source = Engine::Slim.encode(source)
|
188
|
+
expect(encoded_source).to be_include 'current_user.name;'
|
189
|
+
expect(encoded_source).not_to be_include 'Welcome'
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe '#generate_transform_proc' do
|
194
|
+
it 'generates transform proc' do
|
195
|
+
encoded_source = <<~EOS
|
196
|
+
now = DateTime.now
|
197
|
+
if now > DateTime.parse("December 31, 2006")
|
198
|
+
else
|
199
|
+
end
|
200
|
+
if current_admin?
|
201
|
+
elsif current_user?
|
202
|
+
end
|
203
|
+
DateTime.now - now
|
204
|
+
EOS
|
205
|
+
proc = Engine::Slim.generate_transform_proc(encoded_source)
|
206
|
+
actions = [
|
207
|
+
NodeMutation::Struct::Action.new(50, 55, ''),
|
208
|
+
# first end position is 69
|
209
|
+
NodeMutation::Struct::Action.new(100, 105, ''),
|
210
|
+
# second end position is 111
|
211
|
+
NodeMutation::Struct::Action.new(120, 125, '')
|
212
|
+
]
|
213
|
+
proc.call(actions)
|
214
|
+
expect(actions.first.start).to eq 50
|
215
|
+
expect(actions.first.end).to eq 55
|
216
|
+
expect(actions.second.start).to eq 96
|
217
|
+
expect(actions.second.end).to eq 101
|
218
|
+
expect(actions.third.start).to eq 112
|
219
|
+
expect(actions.third.end).to eq 117
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
@@ -385,6 +385,26 @@ module Synvert::Core
|
|
385
385
|
expect(File).to receive(:write).with('./app/views/posts/_form.html.haml', output)
|
386
386
|
instance.process
|
387
387
|
end
|
388
|
+
|
389
|
+
it 'updates slim file' do
|
390
|
+
instance =
|
391
|
+
Rewriter::Instance.new rewriter, 'app/views/posts/_form.html.slim' do
|
392
|
+
with_node node_type: 'ivar' do
|
393
|
+
replace_with 'post'
|
394
|
+
end
|
395
|
+
end
|
396
|
+
input = <<~EOS
|
397
|
+
= form_for @post do |f|
|
398
|
+
= form_for @post do |f|
|
399
|
+
EOS
|
400
|
+
output = <<~EOS
|
401
|
+
= form_for post do |f|
|
402
|
+
= form_for post do |f|
|
403
|
+
EOS
|
404
|
+
allow(File).to receive(:read).with('./app/views/posts/_form.html.slim', encoding: 'UTF-8').and_return(input)
|
405
|
+
expect(File).to receive(:write).with('./app/views/posts/_form.html.slim', output)
|
406
|
+
instance.process
|
407
|
+
end
|
388
408
|
end
|
389
409
|
|
390
410
|
describe '#test' do
|
@@ -477,6 +497,34 @@ module Synvert::Core
|
|
477
497
|
),
|
478
498
|
]
|
479
499
|
end
|
500
|
+
|
501
|
+
it 'updates slim file' do
|
502
|
+
instance =
|
503
|
+
Rewriter::Instance.new rewriter, 'app/views/posts/_form.html.slim' do
|
504
|
+
with_node node_type: 'ivar' do
|
505
|
+
replace_with 'post'
|
506
|
+
end
|
507
|
+
end
|
508
|
+
input = <<~EOS
|
509
|
+
= form_for @post do |f|
|
510
|
+
= form_for @post do |f|
|
511
|
+
EOS
|
512
|
+
output = <<~EOS
|
513
|
+
= form_for post do |f|
|
514
|
+
= form_for post do |f|
|
515
|
+
EOS
|
516
|
+
allow(File).to receive(:read).with('./app/views/posts/_form.html.slim', encoding: 'UTF-8').and_return(input)
|
517
|
+
result = instance.test
|
518
|
+
expect(result.file_path).to eq 'app/views/posts/_form.html.slim'
|
519
|
+
expect(result.actions).to eq [
|
520
|
+
NodeMutation::Struct::Action.new("= form_for ".length, "= form_for @post".length, 'post'),
|
521
|
+
NodeMutation::Struct::Action.new(
|
522
|
+
"= form_for @post do |f|\n= form_for ".length,
|
523
|
+
"= form_for @post do |f|\n= form_for @post".length,
|
524
|
+
'post'
|
525
|
+
),
|
526
|
+
]
|
527
|
+
end
|
480
528
|
end
|
481
529
|
|
482
530
|
describe '#process_with_node' do
|
@@ -33,7 +33,21 @@ module Synvert::Core
|
|
33
33
|
expect(instance.current_node.type).to eq :block
|
34
34
|
end
|
35
35
|
|
36
|
-
it '
|
36
|
+
it 'call block with child node in array' do
|
37
|
+
run = false
|
38
|
+
type_in_scope = nil
|
39
|
+
scope =
|
40
|
+
Rewriter::GotoScope.new instance, 'body.1' do
|
41
|
+
run = true
|
42
|
+
type_in_scope = node.type
|
43
|
+
end
|
44
|
+
scope.process
|
45
|
+
expect(run).to be_truthy
|
46
|
+
expect(type_in_scope).to eq :send
|
47
|
+
expect(instance.current_node.type).to eq :block
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'calls block multiple times with block body' do
|
37
51
|
count = 0
|
38
52
|
scope =
|
39
53
|
Rewriter::GotoScope.new instance, 'body' do
|
data/synvert-core-ruby.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
22
|
spec.add_runtime_dependency "activesupport", "< 7.0.0"
|
23
|
-
spec.add_runtime_dependency "node_query", ">= 1.12.
|
23
|
+
spec.add_runtime_dependency "node_query", ">= 1.12.1"
|
24
24
|
spec.add_runtime_dependency "node_mutation", ">= 1.14.0"
|
25
25
|
spec.add_runtime_dependency "parser"
|
26
26
|
spec.add_runtime_dependency "parser_node_ext", ">= 1.0.0"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: synvert-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.24.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Huang
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-04-
|
11
|
+
date: 2023-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.12.
|
33
|
+
version: 1.12.1
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.12.
|
40
|
+
version: 1.12.1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: node_mutation
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -115,8 +115,10 @@ files:
|
|
115
115
|
- lib/synvert/core.rb
|
116
116
|
- lib/synvert/core/configuration.rb
|
117
117
|
- lib/synvert/core/engine.rb
|
118
|
+
- lib/synvert/core/engine/elegant.rb
|
118
119
|
- lib/synvert/core/engine/erb.rb
|
119
120
|
- lib/synvert/core/engine/haml.rb
|
121
|
+
- lib/synvert/core/engine/slim.rb
|
120
122
|
- lib/synvert/core/node_ext.rb
|
121
123
|
- lib/synvert/core/rewriter.rb
|
122
124
|
- lib/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action.rb
|
@@ -140,6 +142,7 @@ files:
|
|
140
142
|
- spec/support/parser_helper.rb
|
141
143
|
- spec/synvert/core/engine/erb_spec.rb
|
142
144
|
- spec/synvert/core/engine/haml_spec.rb
|
145
|
+
- spec/synvert/core/engine/slim_spec.rb
|
143
146
|
- spec/synvert/core/node_ext_spec.rb
|
144
147
|
- spec/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action_spec.rb
|
145
148
|
- spec/synvert/core/rewriter/condition/if_exist_condition_spec.rb
|
@@ -176,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
176
179
|
- !ruby/object:Gem::Version
|
177
180
|
version: '0'
|
178
181
|
requirements: []
|
179
|
-
rubygems_version: 3.4.
|
182
|
+
rubygems_version: 3.4.10
|
180
183
|
signing_key:
|
181
184
|
specification_version: 4
|
182
185
|
summary: convert ruby code to better syntax.
|
@@ -185,6 +188,7 @@ test_files:
|
|
185
188
|
- spec/support/parser_helper.rb
|
186
189
|
- spec/synvert/core/engine/erb_spec.rb
|
187
190
|
- spec/synvert/core/engine/haml_spec.rb
|
191
|
+
- spec/synvert/core/engine/slim_spec.rb
|
188
192
|
- spec/synvert/core/node_ext_spec.rb
|
189
193
|
- spec/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action_spec.rb
|
190
194
|
- spec/synvert/core/rewriter/condition/if_exist_condition_spec.rb
|