synvert-core 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 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