synvert-core 0.1.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 060a67494f8695693b472fe25ed39d9af6021a28
4
- data.tar.gz: 67485c8861388275535bd8e3a0ab775ae558220d
3
+ metadata.gz: 6ed207188d4ec855b1b3e7f89bbd8fe237fdcfd4
4
+ data.tar.gz: dbe3386bcd2c13ab431afd27111290979ab20e62
5
5
  SHA512:
6
- metadata.gz: a2e3ecbb02ee560b8fed9c0a968bfbc35d2eea5598a94147bbab9a26895813e6de414a94375cbfd5e24987dbe9960f87a1518b7a957e2cbf660a25fe55f16fff
7
- data.tar.gz: e0926950d6b9b55c3ab138a095706dcdbf99cbc92a2789e33db9c83e47c2a8026b4adccd07c6bb2a1c55aebea9ad9ceedce542cd023b993cb05ef1b01882c10a
6
+ metadata.gz: fef1237ad08c20bee81b382f67efa36e0f2d137eb7f4fb5289daf35dfe6053b57a99020e127394d1b7f5f12b9ab4b4983feb01ad6f0ce680db175574cd9d687e
7
+ data.tar.gz: 80c1a8239eea4c895a3c5f5fac37c30f919c70daa60fc4f7f55b789f4e5e43f7329bc5fe3f9aafdebfab6ac3441957eea5c851ccbd0bf7fd9dc73614e9258c98
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.2.0
4
+
5
+ * Add remove_file dsl
6
+ * Add warn dsl
7
+
3
8
  ## 0.1.1
4
9
 
5
10
  * Return empty array if no available rewriters
@@ -76,8 +76,8 @@ class Parser::AST::Node
76
76
  case self.type
77
77
  when :begin
78
78
  self.children
79
- when :block
80
- :begin == self.children[2].type ? self.children[2].children : [self.children[2]]
79
+ when :def, :block
80
+ :begin == self.children[2].type ? self.children[2].body : self.children[2..-1]
81
81
  else
82
82
  raise Synvert::Core::MethodNotSupported.new "body is not handled for #{self.inspect}"
83
83
  end
@@ -13,7 +13,7 @@ module Synvert::Core
13
13
  @node = @instance.current_node
14
14
  end
15
15
 
16
- # Line number of the node.
16
+ # Line number of current node.
17
17
  #
18
18
  # @return [Integer] line number.
19
19
  def line
@@ -16,13 +16,16 @@ module Synvert::Core
16
16
 
17
17
  # Initialize an instance.
18
18
  #
19
+ # @param rewriter [Synvert::Core::Rewriter]
19
20
  # @param file_pattern [String] pattern to find files, e.g. spec/**/*_spec.rb
20
21
  # @param block [Block] block code to find nodes, match conditions and rewrite code.
21
22
  # @return [Synvert::Core::Rewriter::Instance]
22
- def initialize(file_pattern, &block)
23
+ def initialize(rewriter, file_pattern, &block)
24
+ @rewriter = rewriter
23
25
  @actions = []
24
26
  @file_pattern = file_pattern
25
27
  @block = block
28
+ rewriter.helpers.each { |helper| self.singleton_class.send(:define_method, helper[:name], &helper[:block]) }
26
29
  end
27
30
 
28
31
  # Process the instance.
@@ -148,6 +151,13 @@ module Synvert::Core
148
151
  @actions << Rewriter::RemoveAction.new(self)
149
152
  end
150
153
 
154
+ # Parse warn dsl, it creates a [Synvert::Core::Rewriter::Warning] to save warning message.
155
+ #
156
+ # @param message [String] warning message.
157
+ def warn(message)
158
+ @rewriter.add_warning Rewriter::Warning.new(self, message)
159
+ end
160
+
151
161
  private
152
162
 
153
163
  # It changes source code from bottom to top, and it can change source code twice at the same time.
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ module Synvert::Core
4
+ # Warning is used to save warning message.
5
+ class Rewriter::Warning
6
+ # Initialize a warning.
7
+ #
8
+ # @param instance [Synvert::Core::Rewriter::Instance]
9
+ # @param message [String] warning message.
10
+ def initialize(instance, message)
11
+ @file_path = instance.current_file
12
+ @line = instance.current_node.loc.expression.line
13
+ @message = message
14
+ end
15
+
16
+ # Warning message.
17
+ #
18
+ # @return [String] warning message.
19
+ def message
20
+ "#{@file_path}##{@line}: #{@message}"
21
+ end
22
+ end
23
+ end
@@ -23,6 +23,8 @@ module Synvert::Core
23
23
  autoload :ReplaceWithAction, 'synvert/core/rewriter/action'
24
24
  autoload :RemoveAction, 'synvert/core/rewriter/action'
25
25
 
26
+ autoload :Warning, 'synvert/core/rewriter/warning'
27
+
26
28
  autoload :Instance, 'synvert/core/rewriter/instance'
27
29
 
28
30
  autoload :Scope, 'synvert/core/rewriter/scope'
@@ -83,7 +85,11 @@ module Synvert::Core
83
85
  # @return [String] the unique name of rewriter
84
86
  # @!attribute [r] sub_snippets
85
87
  # @return [Array<Synvert::Core::Rewriter>] all rewriters this rewiter calls.
86
- attr_reader :name, :sub_snippets
88
+ # @!attribute [r] helper
89
+ # @return [Array] helper methods.
90
+ # @!attribute [r] warnings
91
+ # @return [Array<Synvert::Core::Rewriter::Warning>] warning messages.
92
+ attr_reader :name, :sub_snippets, :helpers, :warnings
87
93
 
88
94
  # Initialize a rewriter.
89
95
  # When a rewriter is initialized, it is also registered.
@@ -96,6 +102,7 @@ module Synvert::Core
96
102
  @block = block
97
103
  @helpers = []
98
104
  @sub_snippets = []
105
+ @warnings = []
99
106
  self.class.register(@name, self)
100
107
  end
101
108
 
@@ -113,6 +120,13 @@ module Synvert::Core
113
120
  @sandbox = false
114
121
  end
115
122
 
123
+ # Add a warning.
124
+ #
125
+ # @param warning [Synvert::Core::Rewriter::Warning]
126
+ def add_warning(warning)
127
+ @warnings << warning
128
+ end
129
+
116
130
  #######
117
131
  # DSL #
118
132
  #######
@@ -148,9 +162,7 @@ module Synvert::Core
148
162
  return if @sandbox
149
163
 
150
164
  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
165
+ Rewriter::Instance.new(self, file_pattern, &block).process
154
166
  end
155
167
  end
156
168
 
@@ -164,11 +176,21 @@ module Synvert::Core
164
176
  def add_file(filename, content)
165
177
  return if @sandbox
166
178
 
167
- File.open filename, 'w' do |file|
179
+ File.open File.join(Configuration.instance.get(:path), filename), 'w' do |file|
168
180
  file.write content
169
181
  end
170
182
  end
171
183
 
184
+ # Parses remove_file dsl, it removes a file.
185
+ #
186
+ # @param filename [String] file name.
187
+ def remove_file(filename)
188
+ return if @sandbox
189
+
190
+ file_path = File.join(Configuration.instance.get(:path), filename)
191
+ File.delete(file_path) if File.exist?(file_path)
192
+ end
193
+
172
194
  # Parse add_snippet dsl, it calls anther rewriter.
173
195
  #
174
196
  # @param name [String] name of another rewriter.
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Synvert
4
4
  module Core
5
- VERSION = "0.1.1"
5
+ VERSION = "0.2.0"
6
6
  end
7
7
  end
data/spec/spec_helper.rb CHANGED
@@ -19,6 +19,7 @@ RSpec.configure do |config|
19
19
  config.order = 'random'
20
20
 
21
21
  config.before do
22
+ Synvert::Core::Configuration.instance.set :path, '.'
22
23
  Synvert::Core::Configuration.instance.set :skip_files, []
23
24
  end
24
25
  end
@@ -81,6 +81,11 @@ describe Parser::AST::Node do
81
81
  node = parse('foo; bar')
82
82
  expect(node.body).to eq [parse('foo'), parse('bar')]
83
83
  end
84
+
85
+ it 'gets for def node' do
86
+ node = parse('def test; foo; bar; end')
87
+ expect(node.body).to eq [parse('foo'), parse('bar')]
88
+ end
84
89
  end
85
90
 
86
91
  describe "#keys" do
@@ -147,7 +152,10 @@ describe Parser::AST::Node do
147
152
  end
148
153
 
149
154
  describe '#match?' do
150
- let(:instance) { Synvert::Core::Rewriter::Instance.new('file pattern') }
155
+ let(:instance) {
156
+ rewriter = Synvert::Core::Rewriter.new('foobar')
157
+ Synvert::Core::Rewriter::Instance.new(rewriter, 'file pattern')
158
+ }
151
159
 
152
160
  it 'matches class name' do
153
161
  source = 'class Synvert; end'
@@ -1,12 +1,25 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module Synvert::Core
4
+ describe Rewriter::Action do
5
+ subject {
6
+ source = "before_save do\n return false\nend"
7
+ block_node = Parser::CurrentRuby.parse(source).body.first
8
+ instance = double(current_node: block_node)
9
+ Rewriter::Action.new(instance, source)
10
+ }
11
+
12
+ it 'gets line' do
13
+ expect(subject.line).to eq 2
14
+ end
15
+ end
16
+
4
17
  describe Rewriter::ReplaceWithAction do
5
18
  context "replace with single line" do
6
19
  subject {
7
20
  source = "post = FactoryGirl.create_list :post, 2"
8
21
  send_node = Parser::CurrentRuby.parse(source).children[1]
9
- instance = double(:current_node => send_node)
22
+ instance = double(current_node: send_node)
10
23
  Rewriter::ReplaceWithAction.new(instance, 'create_list {{arguments}}')
11
24
  }
12
25
 
@@ -27,7 +40,7 @@ module Synvert::Core
27
40
  subject {
28
41
  source = " its(:size) { should == 1 }"
29
42
  send_node = Parser::CurrentRuby.parse(source)
30
- instance = double(:current_node => send_node)
43
+ instance = double(current_node: send_node)
31
44
  Rewriter::ReplaceWithAction.new(instance, """describe '#size' do
32
45
  subject { super().size }
33
46
  it { {{body}} }
@@ -56,7 +69,7 @@ end""")
56
69
  subject do
57
70
  source = "class User\n has_many :posts\nend"
58
71
  class_node = Parser::CurrentRuby.parse(source)
59
- instance = double(:current_node => class_node)
72
+ instance = double(current_node: class_node)
60
73
  Rewriter::AppendAction.new(instance, "def as_json\n super\nend")
61
74
  end
62
75
 
@@ -77,7 +90,7 @@ end""")
77
90
  subject do
78
91
  source = "gem 'rails'\ngem 'mysql2'"
79
92
  begin_node = Parser::CurrentRuby.parse(source)
80
- instance = double(:current_node => begin_node)
93
+ instance = double(current_node: begin_node)
81
94
  Rewriter::AppendAction.new(instance, "gem 'twitter'")
82
95
  end
83
96
 
@@ -100,7 +113,7 @@ end""")
100
113
  subject {
101
114
  source = "Synvert::Application.configure do\nend"
102
115
  block_node = Parser::CurrentRuby.parse(source)
103
- instance = double(:current_node => block_node)
116
+ instance = double(current_node: block_node)
104
117
  Rewriter::InsertAction.new(instance, 'config.eager_load = true')
105
118
  }
106
119
 
@@ -121,7 +134,7 @@ end""")
121
134
  subject {
122
135
  source = "RSpec.configure do |config|\nend"
123
136
  block_node = Parser::CurrentRuby.parse(source)
124
- instance = double(:current_node => block_node)
137
+ instance = double(current_node: block_node)
125
138
  Rewriter::InsertAction.new(instance, '{{arguments.first}}.include FactoryGirl::Syntax::Methods')
126
139
  }
127
140
 
@@ -142,7 +155,7 @@ end""")
142
155
  subject {
143
156
  source = "class User\n has_many :posts\nend"
144
157
  class_node = Parser::CurrentRuby.parse(source)
145
- instance = double(:current_node => class_node)
158
+ instance = double(current_node: class_node)
146
159
  Rewriter::InsertAction.new(instance, 'include Deletable')
147
160
  }
148
161
 
@@ -163,7 +176,7 @@ end""")
163
176
  subject {
164
177
  source = "class User < ActiveRecord::Base\n has_many :posts\nend"
165
178
  class_node = Parser::CurrentRuby.parse(source)
166
- instance = double(:current_node => class_node)
179
+ instance = double(current_node: class_node)
167
180
  Rewriter::InsertAction.new(instance, 'include Deletable')
168
181
  }
169
182
 
@@ -185,7 +198,7 @@ end""")
185
198
  subject {
186
199
  source = " include Foo"
187
200
  node = Parser::CurrentRuby.parse(source)
188
- instance = double(:current_node => node)
201
+ instance = double(current_node: node)
189
202
  Rewriter::InsertAfterAction.new(instance, 'include Bar')
190
203
  }
191
204
 
@@ -206,7 +219,7 @@ end""")
206
219
  subject {
207
220
  source = "user = User.new params[:user]\nuser.save\nrender\n"
208
221
  send_node = Parser::CurrentRuby.parse(source).children[1]
209
- instance = double(:current_node => send_node)
222
+ instance = double(current_node: send_node)
210
223
  Rewriter::RemoveAction.new(instance)
211
224
  }
212
225
 
@@ -2,7 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  module Synvert::Core
4
4
  describe Rewriter::GemSpec do
5
- before { Configuration.instance.set :path, '.' }
6
5
  let(:gemfile_lock_content) { """
7
6
  GEM
8
7
  remote: https://rubygems.org/
@@ -2,7 +2,10 @@ require 'spec_helper'
2
2
 
3
3
  module Synvert::Core
4
4
  describe Rewriter::Instance do
5
- let(:instance) { Rewriter::Instance.new('file pattern') }
5
+ let(:instance) {
6
+ rewriter = Rewriter.new('foobar')
7
+ Rewriter::Instance.new(rewriter, 'file pattern')
8
+ }
6
9
 
7
10
  it 'parses within_node' do
8
11
  scope = double()
@@ -69,11 +72,16 @@ module Synvert::Core
69
72
  instance.remove
70
73
  end
71
74
 
75
+ it 'parses warn' do
76
+ expect(Rewriter::Warning).to receive(:new).with(instance, 'foobar')
77
+ instance.warn 'foobar'
78
+ end
79
+
72
80
  describe '#process' do
73
- before { Configuration.instance.set :path, '.' }
81
+ let(:rewriter) { Rewriter.new('foobar') }
74
82
 
75
83
  it 'FactoryGirl uses short syntax' do
76
- instance = Rewriter::Instance.new 'spec/**/*_spec.rb' do
84
+ instance = Rewriter::Instance.new rewriter, 'spec/**/*_spec.rb' do
77
85
  with_node type: 'send', receiver: 'FactoryGirl', message: 'create' do
78
86
  replace_with 'create {{arguments}}'
79
87
  end
@@ -99,7 +107,7 @@ end
99
107
  end
100
108
 
101
109
  it 'includes FactoryGirl::Syntax::Methods' do
102
- instance = Rewriter::Instance.new 'spec/spec_helper.rb' do
110
+ instance = Rewriter::Instance.new rewriter, 'spec/spec_helper.rb' do
103
111
  with_node type: 'block', caller: {receiver: 'RSpec', message: 'configure'} do
104
112
  unless_exist_node type: 'send', message: 'include', arguments: ['FactoryGirl::Syntax::Methods'] do
105
113
  insert "{{arguments.first}}.include FactoryGirl::Syntax::Methods"
@@ -122,7 +130,7 @@ end
122
130
  end
123
131
 
124
132
  it 'does not include FactoryGirl::Syntax::Methods' do
125
- instance = Rewriter::Instance.new 'spec/spec_helper.rb' do
133
+ instance = Rewriter::Instance.new rewriter, 'spec/spec_helper.rb' do
126
134
  with_node type: 'block', caller: {receiver: 'RSpec', message: 'configure'} do
127
135
  unless_exist_node type: 'send', message: 'include', arguments: ['FactoryGirl::Syntax::Methods'] do
128
136
  insert "{{arguments.first}}.include FactoryGirl::Syntax::Methods"
@@ -146,7 +154,7 @@ end
146
154
  end
147
155
 
148
156
  it 'process nested send nodes' do
149
- instance = Rewriter::Instance.new 'config/*.rb' do
157
+ instance = Rewriter::Instance.new rewriter, 'config/*.rb' do
150
158
  with_node type: 'send', receiver: {type: 'send', receiver: {type: 'send', message: 'config'}, message: 'active_record'}, message: 'identity_map=' do
151
159
  remove
152
160
  end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ module Synvert::Core
4
+ describe Rewriter::Warning do
5
+ subject {
6
+ source = "def test\n debugger\nend"
7
+ send_node = Parser::CurrentRuby.parse(source).body.first
8
+ instance = double(current_node: send_node, current_file: 'app/test.rb')
9
+ Rewriter::Warning.new(instance, 'remove debugger')
10
+ }
11
+
12
+ it 'gets message with filename and line number' do
13
+ expect(subject.message).to eq 'app/test.rb#2: remove debugger'
14
+ end
15
+ end
16
+ end
@@ -61,7 +61,7 @@ module Synvert::Core
61
61
  describe 'parses add_file' do
62
62
  it 'creates a new file' do
63
63
  rewriter = Rewriter.new 'rewriter2' do
64
- add_file './foo.bar', 'FooBar'
64
+ add_file 'foo.bar', 'FooBar'
65
65
  end
66
66
  rewriter.process
67
67
  expect(File.read './foo.bar').to eq 'FooBar'
@@ -70,13 +70,42 @@ module Synvert::Core
70
70
 
71
71
  it 'does nothing in sandbox mode' do
72
72
  rewriter = Rewriter.new 'rewriter2' do
73
- add_file './foo.bar', 'FooBar'
73
+ add_file 'foo.bar', 'FooBar'
74
74
  end
75
75
  rewriter.process_with_sandbox
76
76
  expect(File.exist?('./foo.bar')).to be_false
77
77
  end
78
78
  end
79
79
 
80
+ describe 'parses remove_file' do
81
+ it 'removes a file' do
82
+ FileUtils.touch './foo.bar'
83
+ rewriter = Rewriter.new 'rewriter2' do
84
+ remove_file 'foo.bar'
85
+ end
86
+ rewriter.process
87
+ expect(File.exist? './foo.bar').to be_false
88
+ end
89
+
90
+ it 'does nothing if file not exist' do
91
+ rewriter = Rewriter.new 'rewriter2' do
92
+ remove_file 'foo.bar'
93
+ end
94
+ rewriter.process
95
+ expect(File.exist? './foo.bar').to be_false
96
+ end
97
+
98
+ it 'does nothing in sandbox mode' do
99
+ FileUtils.touch './foo.bar'
100
+ rewriter = Rewriter.new 'rewriter2' do
101
+ add_file 'foo.bar', 'FooBar'
102
+ end
103
+ rewriter.process_with_sandbox
104
+ expect(File.exist?('./foo.bar')).to be_true
105
+ FileUtils.rm './foo.bar'
106
+ end
107
+ end
108
+
80
109
  describe 'parses add_snippet' do
81
110
  it 'processes the rewritter' do
82
111
  rewriter1 = Rewriter.new 'rewriter1'
@@ -106,16 +135,13 @@ module Synvert::Core
106
135
  end
107
136
 
108
137
  it 'parses helper_method' do
109
- instance = double
110
- expect(Rewriter::Instance).to receive(:new).and_return(instance)
111
- expect(instance).to receive(:process)
112
138
  rewriter = Rewriter.new 'name' do
113
139
  helper_method 'dynamic_helper' do |arg1, arg2|
114
140
  'dynamic result'
115
141
  end
116
- within_file 'spec/spec_helper.rb' do; end
117
142
  end
118
143
  rewriter.process
144
+ instance = Rewriter::Instance.new(rewriter, '*.rb')
119
145
  expect(instance.dynamic_helper('arg1', 'arg2')).to eq 'dynamic result'
120
146
  end
121
147
 
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: 0.1.1
4
+ version: 0.2.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: 2014-05-04 00:00:00.000000000 Z
11
+ date: 2014-05-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -105,6 +105,7 @@ files:
105
105
  - lib/synvert/core/rewriter/gem_spec.rb
106
106
  - lib/synvert/core/rewriter/instance.rb
107
107
  - lib/synvert/core/rewriter/scope.rb
108
+ - lib/synvert/core/rewriter/warning.rb
108
109
  - lib/synvert/core/version.rb
109
110
  - spec/spec_helper.rb
110
111
  - spec/support/parser_helper.rb
@@ -115,6 +116,7 @@ files:
115
116
  - spec/synvert/core/rewriter/gem_spec_spec.rb
116
117
  - spec/synvert/core/rewriter/instance_spec.rb
117
118
  - spec/synvert/core/rewriter/scope_spec.rb
119
+ - spec/synvert/core/rewriter/warning_spec.rb
118
120
  - spec/synvert/core/rewriter_spec.rb
119
121
  - synvert-core.gemspec
120
122
  homepage: https://github.com/xinminlabs/synvert-core
@@ -151,4 +153,5 @@ test_files:
151
153
  - spec/synvert/core/rewriter/gem_spec_spec.rb
152
154
  - spec/synvert/core/rewriter/instance_spec.rb
153
155
  - spec/synvert/core/rewriter/scope_spec.rb
156
+ - spec/synvert/core/rewriter/warning_spec.rb
154
157
  - spec/synvert/core/rewriter_spec.rb