synvert 0.0.17 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +0 -1
- data/CHANGELOG.md +4 -0
- data/README.md +7 -26
- data/bin/synvert +0 -1
- data/lib/synvert/cli.rb +26 -14
- data/lib/synvert/snippet.rb +17 -0
- data/lib/synvert/version.rb +1 -1
- data/lib/synvert.rb +3 -11
- data/synvert.gemspec +2 -3
- metadata +6 -85
- data/lib/synvert/configuration.rb +0 -25
- data/lib/synvert/exceptions.rb +0 -13
- data/lib/synvert/node_ext.rb +0 -319
- data/lib/synvert/rewriter/action.rb +0 -224
- data/lib/synvert/rewriter/condition.rb +0 -56
- data/lib/synvert/rewriter/gem_spec.rb +0 -42
- data/lib/synvert/rewriter/instance.rb +0 -185
- data/lib/synvert/rewriter/scope.rb +0 -46
- data/lib/synvert/rewriter.rb +0 -200
- data/lib/synvert/snippets/check_syntax.rb +0 -5
- data/lib/synvert/snippets/factory_girl/syntax_methods.rb +0 -98
- data/lib/synvert/snippets/rails/convert_dynamic_finders.rb +0 -93
- data/lib/synvert/snippets/rails/strong_parameters.rb +0 -93
- data/lib/synvert/snippets/rails/upgrade_3_0_to_3_1.rb +0 -135
- data/lib/synvert/snippets/rails/upgrade_3_1_to_3_2.rb +0 -42
- data/lib/synvert/snippets/rails/upgrade_3_2_to_4_0.rb +0 -230
- data/lib/synvert/snippets/rspec/be_close_to_be_within.rb +0 -18
- data/lib/synvert/snippets/rspec/block_to_expect.rb +0 -22
- data/lib/synvert/snippets/rspec/boolean_matcher.rb +0 -20
- data/lib/synvert/snippets/rspec/collection_matcher.rb +0 -34
- data/lib/synvert/snippets/rspec/its_to_it.rb +0 -89
- data/lib/synvert/snippets/rspec/message_expectation.rb +0 -41
- data/lib/synvert/snippets/rspec/method_stub.rb +0 -84
- data/lib/synvert/snippets/rspec/negative_error_expectation.rb +0 -21
- data/lib/synvert/snippets/rspec/new_syntax.rb +0 -18
- data/lib/synvert/snippets/rspec/one_liner_expectation.rb +0 -71
- data/lib/synvert/snippets/rspec/should_to_expect.rb +0 -50
- data/lib/synvert/snippets/rspec/stub_and_mock_to_double.rb +0 -22
- data/lib/synvert/snippets/ruby/new_hash_syntax.rb +0 -21
- data/lib/synvert/snippets/ruby/new_lambda_syntax.rb +0 -20
- data/spec/spec_helper.rb +0 -26
- data/spec/support/parser_helper.rb +0 -5
- data/spec/synvert/node_ext_spec.rb +0 -201
- data/spec/synvert/rewriter/action_spec.rb +0 -225
- data/spec/synvert/rewriter/condition_spec.rb +0 -106
- data/spec/synvert/rewriter/gem_spec_spec.rb +0 -52
- data/spec/synvert/rewriter/instance_spec.rb +0 -163
- data/spec/synvert/rewriter/scope_spec.rb +0 -42
- data/spec/synvert/rewriter_spec.rb +0 -153
- data/spec/synvert/snippets/factory_girl/syntax_methods_spec.rb +0 -154
- data/spec/synvert/snippets/rails/convert_dynamic_finders_spec.rb +0 -83
- data/spec/synvert/snippets/rails/strong_parameters_spec.rb +0 -132
- data/spec/synvert/snippets/rails/upgrade_3_0_to_3_1_spec.rb +0 -88
- data/spec/synvert/snippets/rails/upgrade_3_1_to_3_2_spec.rb +0 -41
- data/spec/synvert/snippets/rails/upgrade_3_2_to_4_0_spec.rb +0 -299
- data/spec/synvert/snippets/rspec/new_syntax_spec.rb +0 -183
- data/spec/synvert/snippets/ruby/new_hash_syntax_spec.rb +0 -27
- data/spec/synvert/snippets/ruby/new_lambda_syntax_spec.rb +0 -27
@@ -1,185 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Synvert
|
4
|
-
# Instance is an execution unit, it finds specified ast nodes,
|
5
|
-
# checks if the nodes match some conditions, then add, replace or remove code.
|
6
|
-
#
|
7
|
-
# One instance can contains one or many [Synvert::Rewriter::Scope] and [Synvert::Rewriter::Condition].
|
8
|
-
class Rewriter::Instance
|
9
|
-
# @!attribute [rw] current_node
|
10
|
-
# @return current parsing node
|
11
|
-
# @!attribute [rw] current_source
|
12
|
-
# @return current source code of file
|
13
|
-
# @!attribute [rw] current_file
|
14
|
-
# @return current filename
|
15
|
-
attr_accessor :current_node, :current_source, :current_file
|
16
|
-
|
17
|
-
# Initialize an instance.
|
18
|
-
#
|
19
|
-
# @param file_pattern [String] pattern to find files, e.g. spec/**/*_spec.rb
|
20
|
-
# @param block [Block] block code to find nodes, match conditions and rewrite code.
|
21
|
-
# @return [Synvert::Rewriter::Instance]
|
22
|
-
def initialize(file_pattern, &block)
|
23
|
-
@actions = []
|
24
|
-
@file_pattern = file_pattern
|
25
|
-
@block = block
|
26
|
-
end
|
27
|
-
|
28
|
-
# Process the instance.
|
29
|
-
# It finds all files, for each file, it executes the block code, gets all rewrite actions,
|
30
|
-
# and rewrite source code back to original file.
|
31
|
-
def process
|
32
|
-
parser = Parser::CurrentRuby.new
|
33
|
-
file_pattern = File.join(Configuration.instance.get(:path), @file_pattern)
|
34
|
-
Dir.glob(file_pattern).each do |file_path|
|
35
|
-
unless Configuration.instance.get(:skip_files).include? file_path
|
36
|
-
begin
|
37
|
-
source = File.read(file_path)
|
38
|
-
buffer = Parser::Source::Buffer.new file_path
|
39
|
-
buffer.source = source
|
40
|
-
|
41
|
-
parser.reset
|
42
|
-
ast = parser.parse buffer
|
43
|
-
|
44
|
-
@current_file = file_path
|
45
|
-
@current_source = source
|
46
|
-
@current_node = ast
|
47
|
-
instance_eval &@block
|
48
|
-
@current_node = ast
|
49
|
-
|
50
|
-
@actions.sort!
|
51
|
-
check_conflict_actions
|
52
|
-
@actions.reverse.each do |action|
|
53
|
-
source[action.begin_pos...action.end_pos] = action.rewritten_code
|
54
|
-
source = remove_code_or_whole_line(source, action.line)
|
55
|
-
end
|
56
|
-
@actions = []
|
57
|
-
|
58
|
-
File.write file_path, source
|
59
|
-
end while !@conflict_actions.empty?
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
# Gets current node, it allows to get current node in block code.
|
65
|
-
#
|
66
|
-
# @return [Parser::AST::Node]
|
67
|
-
def node
|
68
|
-
@current_node
|
69
|
-
end
|
70
|
-
|
71
|
-
#######
|
72
|
-
# DSL #
|
73
|
-
#######
|
74
|
-
|
75
|
-
# Parse within_node dsl, it creates a [Synvert::Rewriter::Scope] to find matching ast nodes,
|
76
|
-
# then continue operating on each matching ast node.
|
77
|
-
#
|
78
|
-
# @param rules [Hash] rules to find mathing ast nodes.
|
79
|
-
# @param block [Block] block code to continue operating on the matching nodes.
|
80
|
-
def within_node(rules, &block)
|
81
|
-
Rewriter::Scope.new(self, rules, &block).process
|
82
|
-
end
|
83
|
-
|
84
|
-
alias with_node within_node
|
85
|
-
|
86
|
-
# Parse if_exist_node dsl, it creates a [Synvert::Rewriter::IfExistCondition] to check
|
87
|
-
# if matching nodes exist in the child nodes, if so, then continue operating on each matching ast node.
|
88
|
-
#
|
89
|
-
# @param rules [Hash] rules to check mathing ast nodes.
|
90
|
-
# @param block [Block] block code to continue operating on the matching nodes.
|
91
|
-
def if_exist_node(rules, &block)
|
92
|
-
Rewriter::IfExistCondition.new(self, rules, &block).process
|
93
|
-
end
|
94
|
-
|
95
|
-
# Parse unless_exist_node dsl, it creates a [Synvert::Rewriter::UnlessExistCondition] to check
|
96
|
-
# if matching nodes doesn't exist in the child nodes, if so, then continue operating on each matching ast node.
|
97
|
-
#
|
98
|
-
# @param rules [Hash] rules to check mathing ast nodes.
|
99
|
-
# @param block [Block] block code to continue operating on the matching nodes.
|
100
|
-
def unless_exist_node(rules, &block)
|
101
|
-
Rewriter::UnlessExistCondition.new(self, rules, &block).process
|
102
|
-
end
|
103
|
-
|
104
|
-
# Parse if_only_exist_node dsl, it creates a [Synvert::Rewriter::IfOnlyExistCondition] to check
|
105
|
-
# if current node has only one child node and the child node matches rules,
|
106
|
-
# if so, then continue operating on each matching ast node.
|
107
|
-
#
|
108
|
-
# @param rules [Hash] rules to check mathing ast nodes.
|
109
|
-
# @param block [Block] block code to continue operating on the matching nodes.
|
110
|
-
def if_only_exist_node(rules, &block)
|
111
|
-
Rewriter::IfOnlyExistCondition.new(self, rules, &block).process
|
112
|
-
end
|
113
|
-
|
114
|
-
# Parse append dsl, it creates a [Synvert::Rewriter::AppendAction] to
|
115
|
-
# append the code to the bottom of current node body.
|
116
|
-
#
|
117
|
-
# @param code [String] code need to be appended.
|
118
|
-
def append(code)
|
119
|
-
@actions << Rewriter::AppendAction.new(self, code)
|
120
|
-
end
|
121
|
-
|
122
|
-
# Parse insert dsl, it creates a [Synvert::Rewriter::InsertAction] to
|
123
|
-
# insert the code to the top of current node body.
|
124
|
-
#
|
125
|
-
# @param code [String] code need to be inserted.
|
126
|
-
def insert(code)
|
127
|
-
@actions << Rewriter::InsertAction.new(self, code)
|
128
|
-
end
|
129
|
-
|
130
|
-
# Parse insert_after dsl, it creates a [Synvert::Rewriter::InsertAfterAction] to
|
131
|
-
# insert the code next to the current node.
|
132
|
-
#
|
133
|
-
# @param code [String] code need to be inserted.
|
134
|
-
def insert_after(node)
|
135
|
-
@actions << Rewriter::InsertAfterAction.new(self, node)
|
136
|
-
end
|
137
|
-
|
138
|
-
# Parse replace_with dsl, it creates a [Synvert::Rewriter::ReplaceWithAction] to
|
139
|
-
# replace current node with code.
|
140
|
-
#
|
141
|
-
# @param code [String] code need to be replaced with.
|
142
|
-
def replace_with(code)
|
143
|
-
@actions << Rewriter::ReplaceWithAction.new(self, code)
|
144
|
-
end
|
145
|
-
|
146
|
-
# Parse remove dsl, it creates a [Synvert::Rewriter::RemoveAction] to current node.
|
147
|
-
def remove
|
148
|
-
@actions << Rewriter::RemoveAction.new(self)
|
149
|
-
end
|
150
|
-
|
151
|
-
private
|
152
|
-
|
153
|
-
# It changes source code from bottom to top, and it can change source code twice at the same time.
|
154
|
-
# So if there is an overlap between two actions, it removes the conflict actions and operate them in the next loop.
|
155
|
-
def check_conflict_actions
|
156
|
-
i = @actions.length - 1
|
157
|
-
@conflict_actions = []
|
158
|
-
while i > 0
|
159
|
-
if @actions[i].begin_pos <= @actions[i - 1].end_pos
|
160
|
-
@conflict_actions << @actions.delete_at(i)
|
161
|
-
end
|
162
|
-
i -= 1
|
163
|
-
end
|
164
|
-
@conflict_actions
|
165
|
-
end
|
166
|
-
|
167
|
-
# It checks if code is removed and that line is empty.
|
168
|
-
#
|
169
|
-
# @param source [String] source code of file
|
170
|
-
# @param line [String] the line number
|
171
|
-
def remove_code_or_whole_line(source, line)
|
172
|
-
newline_at_end_of_line = source[-1] == "\n"
|
173
|
-
source_arr = source.split("\n")
|
174
|
-
if source_arr[line - 1] && source_arr[line - 1].strip.empty?
|
175
|
-
source_arr.delete_at(line - 1)
|
176
|
-
if source_arr[line - 2] && source_arr[line - 2].strip.empty? && source_arr[line - 1] && source_arr[line - 1].strip.empty?
|
177
|
-
source_arr.delete_at(line - 1)
|
178
|
-
end
|
179
|
-
source_arr.join("\n") + (newline_at_end_of_line ? "\n" : '')
|
180
|
-
else
|
181
|
-
source
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Synvert
|
4
|
-
# Scope finds the child nodes which match rules.
|
5
|
-
class Rewriter::Scope
|
6
|
-
# Initialize a scope
|
7
|
-
#
|
8
|
-
# @param instance [Synvert::Rewriter::Instance]
|
9
|
-
# @param rules [Hash]
|
10
|
-
# @param block [Block]
|
11
|
-
def initialize(instance, rules, &block)
|
12
|
-
@instance = instance
|
13
|
-
@rules = rules
|
14
|
-
@block = block
|
15
|
-
end
|
16
|
-
|
17
|
-
# Find the matching nodes. It checks the current node and iterates all child nodes,
|
18
|
-
# then run the block code for each matching node.
|
19
|
-
def process
|
20
|
-
current_node = @instance.current_node
|
21
|
-
return unless current_node
|
22
|
-
process_with_node current_node do
|
23
|
-
matching_nodes = []
|
24
|
-
matching_nodes << current_node if current_node.match? @instance, @rules
|
25
|
-
current_node.recursive_children do |child_node|
|
26
|
-
matching_nodes << child_node if child_node.match? @instance, @rules
|
27
|
-
end
|
28
|
-
matching_nodes.each do |matching_node|
|
29
|
-
process_with_node matching_node do
|
30
|
-
@instance.instance_eval &@block
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
# Set instance current node properly and process.
|
39
|
-
# @param node [Parser::AST::Node]
|
40
|
-
def process_with_node(node)
|
41
|
-
@instance.current_node = node
|
42
|
-
yield
|
43
|
-
@instance.current_node = node
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
data/lib/synvert/rewriter.rb
DELETED
@@ -1,200 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Synvert
|
4
|
-
# Rewriter is the top level namespace in a snippet.
|
5
|
-
#
|
6
|
-
# One Rewriter can contain one or many [Synvert::Rewriter::Instance],
|
7
|
-
# which define the behavior what files and what codes to detect and rewrite to what code.
|
8
|
-
#
|
9
|
-
# Synvert::Rewriter.new 'factory_girl_short_syntax', 'use FactoryGirl short syntax' do
|
10
|
-
# if_gem 'factory_girl', {gte: '2.0.0'}
|
11
|
-
#
|
12
|
-
# within_files 'spec/**/*.rb' do
|
13
|
-
# with_node type: 'send', receiver: 'FactoryGirl', message: 'create' do
|
14
|
-
# replace_with "create({{arguments}})"
|
15
|
-
# end
|
16
|
-
# end
|
17
|
-
# end
|
18
|
-
class Rewriter
|
19
|
-
autoload :Action, 'synvert/rewriter/action'
|
20
|
-
autoload :AppendAction, 'synvert/rewriter/action'
|
21
|
-
autoload :InsertAction, 'synvert/rewriter/action'
|
22
|
-
autoload :InsertAfterAction, 'synvert/rewriter/action'
|
23
|
-
autoload :ReplaceWithAction, 'synvert/rewriter/action'
|
24
|
-
autoload :RemoveAction, 'synvert/rewriter/action'
|
25
|
-
|
26
|
-
autoload :Instance, 'synvert/rewriter/instance'
|
27
|
-
|
28
|
-
autoload :Scope, 'synvert/rewriter/scope'
|
29
|
-
|
30
|
-
autoload :Condition, 'synvert/rewriter/condition'
|
31
|
-
autoload :IfExistCondition, 'synvert/rewriter/condition'
|
32
|
-
autoload :UnlessExistCondition, 'synvert/rewriter/condition'
|
33
|
-
autoload :IfOnlyExistCondition, 'synvert/rewriter/condition'
|
34
|
-
|
35
|
-
autoload :GemSpec, 'synvert/rewriter/gem_spec'
|
36
|
-
|
37
|
-
class <<self
|
38
|
-
# Register a rewriter with its name.
|
39
|
-
#
|
40
|
-
# @param name [String] the unique rewriter name.
|
41
|
-
# @param rewriter [Synvert::Rewriter] the rewriter to register.
|
42
|
-
def register(name, rewriter)
|
43
|
-
@rewriters ||= {}
|
44
|
-
@rewriters[name] = rewriter
|
45
|
-
end
|
46
|
-
|
47
|
-
# Fetch a rewriter by name.
|
48
|
-
#
|
49
|
-
# @param name [String] rewrtier name.
|
50
|
-
# @return [Synvert::Rewriter] the matching rewriter.
|
51
|
-
def fetch(name)
|
52
|
-
@rewriters[name]
|
53
|
-
end
|
54
|
-
|
55
|
-
# Get a registered rewriter by name and process that rewriter.
|
56
|
-
#
|
57
|
-
# @param name [String] the rewriter name.
|
58
|
-
# @return [Synvert::Rewriter] the registered rewriter.
|
59
|
-
# @raise [Synvert::RewriterNotFound] if the registered rewriter is not found.
|
60
|
-
def call(name)
|
61
|
-
if (rewriter = @rewriters[name])
|
62
|
-
rewriter.process
|
63
|
-
rewriter
|
64
|
-
else
|
65
|
-
raise RewriterNotFound.new "Rewriter #{name} not found"
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
# Get all available rewriters
|
70
|
-
#
|
71
|
-
# @return [Array<Synvert::Rewriter>]
|
72
|
-
def availables
|
73
|
-
@rewriters.values
|
74
|
-
end
|
75
|
-
|
76
|
-
# Clear all registered rewriters.
|
77
|
-
def clear
|
78
|
-
@rewriters.clear
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
# @!attribute [r] name
|
83
|
-
# @return [String] the unique name of rewriter
|
84
|
-
# @!attribute [r] sub_snippets
|
85
|
-
# @return [Array<Synvert::Rewriter>] all rewriters this rewiter calls.
|
86
|
-
attr_reader :name, :sub_snippets
|
87
|
-
|
88
|
-
# Initialize a rewriter.
|
89
|
-
# When a rewriter is initialized, it is also registered.
|
90
|
-
#
|
91
|
-
# @param name [String] name of the rewriter.
|
92
|
-
# @param block [Block] a block defines the behaviors of the rewriter, block code won't be called when initialization.
|
93
|
-
# @return [Synvert::Rewriter]
|
94
|
-
def initialize(name, &block)
|
95
|
-
@name = name.to_s
|
96
|
-
@block = block
|
97
|
-
@helpers = []
|
98
|
-
@sub_snippets = []
|
99
|
-
self.class.register(@name, self)
|
100
|
-
end
|
101
|
-
|
102
|
-
# Process the rewriter.
|
103
|
-
# It will call the block.
|
104
|
-
def process
|
105
|
-
self.instance_eval &@block
|
106
|
-
end
|
107
|
-
|
108
|
-
# Process rewriter with sandbox mode.
|
109
|
-
# It will call the block but doesn't change any file.
|
110
|
-
def process_with_sandbox
|
111
|
-
@sandbox = true
|
112
|
-
self.process
|
113
|
-
@sandbox = false
|
114
|
-
end
|
115
|
-
|
116
|
-
#######
|
117
|
-
# DSL #
|
118
|
-
#######
|
119
|
-
|
120
|
-
# Parse description dsl, it sets description of the rewrite.
|
121
|
-
# Or get description.
|
122
|
-
#
|
123
|
-
# @param description [String] rewriter description.
|
124
|
-
# @return rewriter description.
|
125
|
-
def description(description=nil)
|
126
|
-
if description
|
127
|
-
@description = description
|
128
|
-
else
|
129
|
-
@description
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
# Parse if_gem dsl, it compares version of the specified gem.
|
134
|
-
#
|
135
|
-
# @param name [String] gem name.
|
136
|
-
# @param comparator [Hash] equal, less than or greater than specified version, e.g. {gte: '2.0.0'},
|
137
|
-
# key can be eq, lt, gt, lte, gte or ne.
|
138
|
-
def if_gem(name, comparator)
|
139
|
-
@gem_spec = Rewriter::GemSpec.new(name, comparator)
|
140
|
-
end
|
141
|
-
|
142
|
-
# Parse within_files dsl, it finds specified files.
|
143
|
-
# It creates a [Synvert::Rewriter::Instance] to rewrite code.
|
144
|
-
#
|
145
|
-
# @param file_pattern [String] pattern to find files, e.g. spec/**/*_spec.rb
|
146
|
-
# @param block [Block] the block to rewrite code in the matching files.
|
147
|
-
def within_files(file_pattern, &block)
|
148
|
-
return if @sandbox
|
149
|
-
|
150
|
-
if !@gem_spec || @gem_spec.match?
|
151
|
-
instance = Rewriter::Instance.new(file_pattern, &block)
|
152
|
-
@helpers.each { |helper| instance.singleton_class.send(:define_method, helper[:name], &helper[:block]) }
|
153
|
-
instance.process
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
# Parse within_file dsl, it finds a specifiled file.
|
158
|
-
alias within_file within_files
|
159
|
-
|
160
|
-
# Parses add_file dsl, it adds a new file.
|
161
|
-
#
|
162
|
-
# @param filename [String] file name of newly created file.
|
163
|
-
# @param content [String] file body of newly created file.
|
164
|
-
def add_file(filename, content)
|
165
|
-
return if @sandbox
|
166
|
-
|
167
|
-
File.open filename, 'w' do |file|
|
168
|
-
file.write content
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
# Parse add_snippet dsl, it calls anther rewriter.
|
173
|
-
#
|
174
|
-
# @param name [String] name of another rewriter.
|
175
|
-
def add_snippet(name)
|
176
|
-
@sub_snippets << self.class.call(name.to_s)
|
177
|
-
end
|
178
|
-
|
179
|
-
# Parse helper_method dsl, it defines helper method for [Synvert::Rewriter::Instance].
|
180
|
-
#
|
181
|
-
# @param name [String] helper method name.
|
182
|
-
# @param block [Block] helper method block.
|
183
|
-
def helper_method(name, &block)
|
184
|
-
@helpers << {name: name, block: block}
|
185
|
-
end
|
186
|
-
|
187
|
-
# Parse todo dsl, it sets todo of the rewriter.
|
188
|
-
# Or get todo.
|
189
|
-
#
|
190
|
-
# @param todo_list [String] rewriter todo.
|
191
|
-
# @return [String] rewriter todo.
|
192
|
-
def todo(todo=nil)
|
193
|
-
if todo
|
194
|
-
@todo = todo
|
195
|
-
else
|
196
|
-
@todo
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
200
|
-
end
|
@@ -1,98 +0,0 @@
|
|
1
|
-
Synvert::Rewriter.new "factory_girl_short_syntax" do
|
2
|
-
description <<-EOF
|
3
|
-
Uses FactoryGirl short syntax.
|
4
|
-
|
5
|
-
1. it adds FactoryGirl::Syntax::methods module to RSpec, Test::Unit, Cucumber, Spainach, MiniTest, MiniTest::Spec, minitest-rails.
|
6
|
-
|
7
|
-
# rspec
|
8
|
-
RSpec.configure do |config|
|
9
|
-
config.include FactoryGirl::Syntax::Methods
|
10
|
-
end
|
11
|
-
|
12
|
-
# Test::Unit
|
13
|
-
class Test::Unit::TestCase
|
14
|
-
include FactoryGirl::Syntax::Methods
|
15
|
-
end
|
16
|
-
|
17
|
-
# Cucumber
|
18
|
-
World(FactoryGirl::Syntax::Methods)
|
19
|
-
|
20
|
-
# Spinach
|
21
|
-
class Spinach::FeatureSteps
|
22
|
-
include FactoryGirl::Syntax::Methods
|
23
|
-
end
|
24
|
-
|
25
|
-
# MiniTest
|
26
|
-
class MiniTest::Unit::TestCase
|
27
|
-
include FactoryGirl::Syntax::Methods
|
28
|
-
end
|
29
|
-
|
30
|
-
# MiniTest::Spec
|
31
|
-
class MiniTest::Spec
|
32
|
-
include FactoryGirl::Syntax::Methods
|
33
|
-
end
|
34
|
-
|
35
|
-
# minitest-rails
|
36
|
-
class MiniTest::Rails::ActiveSupport::TestCase
|
37
|
-
include FactoryGirl::Syntax::Methods
|
38
|
-
end
|
39
|
-
|
40
|
-
2. it converts to short syntax.
|
41
|
-
|
42
|
-
FactoryGirl.create(...) => create(...)
|
43
|
-
FactoryGirl.build(...) => build(...)
|
44
|
-
FactoryGirl.attributes_for(...) => attributes_for(...)
|
45
|
-
FactoryGirl.build_stubbed(...) => build_stubbed(...)
|
46
|
-
FactoryGirl.create_list(...) => create_list(...)
|
47
|
-
FactoryGirl.build_list(...) => build_list(...)
|
48
|
-
FactoryGirl.create_pair(...) => create_pair(...)
|
49
|
-
FactoryGirl.build_pair(...) => build_pair(...)
|
50
|
-
EOF
|
51
|
-
|
52
|
-
if_gem 'factory_girl', {gte: '2.0.0'}
|
53
|
-
|
54
|
-
# insert include FactoryGirl::Syntax::Methods
|
55
|
-
within_file 'spec/spec_helper.rb' do
|
56
|
-
within_node type: 'block', caller: {receiver: 'RSpec', message: 'configure'} do
|
57
|
-
unless_exist_node type: 'send', message: 'include', arguments: ['FactoryGirl::Syntax::Methods'] do
|
58
|
-
insert "{{arguments.first}}.include FactoryGirl::Syntax::Methods"
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
# insert include FactoryGirl::Syntax::Methods
|
64
|
-
within_file 'test/test_helper.rb' do
|
65
|
-
%w(Test::Unit::TestCase ActiveSupport::TestCase MiniTest::Unit::TestCase MiniTest::Spec MiniTest::Rails::ActiveSupport::TestCase).each do |class_name|
|
66
|
-
within_node type: 'class', name: class_name do
|
67
|
-
unless_exist_node type: 'send', message: 'include', arguments: ['FactoryGirl::Syntax::Methods'] do
|
68
|
-
insert "include FactoryGirl::Syntax::Methods"
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
# insert World(FactoryGirl::Syntax::Methods)
|
75
|
-
within_file 'features/support/env.rb' do
|
76
|
-
unless_exist_node type: 'send', message: 'World', arguments: ['FactoryGirl::Syntax::Methods'] do
|
77
|
-
insert "World(FactoryGirl::Syntax::Methods)"
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
# FactoryGirl.create(...) => create(...)
|
82
|
-
# FactoryGirl.build(...) => build(...)
|
83
|
-
# FactoryGirl.attributes_for(...) => attributes_for(...)
|
84
|
-
# FactoryGirl.build_stubbed(...) => build_stubbed(...)
|
85
|
-
# FactoryGirl.create_list(...) => create_list(...)
|
86
|
-
# FactoryGirl.build_list(...) => build_list(...)
|
87
|
-
# FactoryGirl.create_pair(...) => create_pair(...)
|
88
|
-
# FactoryGirl.build_pair(...) => build_pair(...)
|
89
|
-
%w(test/**/*.rb spec/**/*.rb features/**/*.rb).each do |file_pattern|
|
90
|
-
within_files file_pattern do
|
91
|
-
%w(create build attributes_for build_stubbed create_list build_list create_pair build_pair).each do |message|
|
92
|
-
with_node type: 'send', receiver: 'FactoryGirl', message: message do
|
93
|
-
replace_with "#{message}({{arguments}})"
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
@@ -1,93 +0,0 @@
|
|
1
|
-
Synvert::Rewriter.new "convert_rails_dynamic_finders" do
|
2
|
-
description <<-EOF
|
3
|
-
It converts rails dynamic finders to arel syntax.
|
4
|
-
|
5
|
-
find_all_by_... => where(...)
|
6
|
-
find_by_... => where(...).first
|
7
|
-
find_last_by_... => where(...).last
|
8
|
-
scoped_by_... => where(...)
|
9
|
-
find_or_initialize_by_... => find_or_initialize_by(...)
|
10
|
-
find_or_create_by_... => find_or_create_by(...)
|
11
|
-
EOF
|
12
|
-
|
13
|
-
helper_method 'dynamic_finder_to_hash' do |prefix|
|
14
|
-
fields = node.message.to_s[prefix.length..-1].split("_and_")
|
15
|
-
if fields.length == node.arguments.length && :hash != node.arguments.first.type
|
16
|
-
fields.length.times.map { |i|
|
17
|
-
fields[i] + ": " + node.arguments[i].source(self)
|
18
|
-
}.join(", ")
|
19
|
-
else
|
20
|
-
"{{arguments}}"
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
within_files '**/*.rb' do
|
25
|
-
# find_all_by_... => where(...)
|
26
|
-
with_node type: 'send', message: /^find_all_by_/ do
|
27
|
-
hash_params = dynamic_finder_to_hash("find_all_by_")
|
28
|
-
if node.receiver
|
29
|
-
replace_with "{{receiver}}.where(#{hash_params})"
|
30
|
-
else
|
31
|
-
replace_with "where(#{hash_params})"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
# find_by_... => where(...).first
|
36
|
-
with_node type: 'send', message: /^find_by_/ do
|
37
|
-
if :find_by_id == node.message
|
38
|
-
if node.receiver
|
39
|
-
replace_with "{{receiver}}.find({{arguments}})"
|
40
|
-
else
|
41
|
-
replace_with "find({{arguments}}"
|
42
|
-
end
|
43
|
-
elsif :find_by_sql != node.message
|
44
|
-
hash_params = dynamic_finder_to_hash("find_by_")
|
45
|
-
if node.receiver
|
46
|
-
replace_with "{{receiver}}.where(#{hash_params}).first"
|
47
|
-
else
|
48
|
-
replace_with "where(#{hash_params}).first"
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# find_last_by_... => where(...).last
|
54
|
-
with_node type: 'send', message: /^find_last_by_/ do
|
55
|
-
hash_params = dynamic_finder_to_hash("find_last_by_")
|
56
|
-
if node.receiver
|
57
|
-
replace_with "{{receiver}}.where(#{hash_params}).last"
|
58
|
-
else
|
59
|
-
replace_with "where(#{hash_params}).last"
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
# scoped_by_... => where(...)
|
64
|
-
with_node type: 'send', message: /^scoped_by_/ do
|
65
|
-
hash_params = dynamic_finder_to_hash("scoped_by_")
|
66
|
-
if node.receiver
|
67
|
-
replace_with "{{receiver}}.where(#{hash_params})"
|
68
|
-
else
|
69
|
-
replace_with "where(#{hash_params})"
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
# find_or_initialize_by_... => find_or_initialize_by(...)
|
74
|
-
with_node type: 'send', message: /^find_or_initialize_by_/ do
|
75
|
-
hash_params = dynamic_finder_to_hash("find_or_initialize_by_")
|
76
|
-
if node.receiver
|
77
|
-
replace_with "{{receiver}}.find_or_initialize_by(#{hash_params})"
|
78
|
-
else
|
79
|
-
replace_with "find_or_initialize_by(#{hash_params})"
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
# find_or_create_by_... => find_or_create_by(...)
|
84
|
-
with_node type: 'send', message: /^find_or_create_by_/ do
|
85
|
-
hash_params = dynamic_finder_to_hash("find_or_create_by_")
|
86
|
-
if node.receiver
|
87
|
-
replace_with "{{receiver}}.find_or_create_by(#{hash_params})"
|
88
|
-
else
|
89
|
-
replace_with "find_or_create_by(#{hash_params})"
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|