transpec 1.2.1 → 1.2.2

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: f1cbae52577334b666b5a02f1c926f8a8ca1af16
4
- data.tar.gz: 181c31e4d34c5b5f4e966d0627fb30fa9d875142
3
+ metadata.gz: 59870e21327ecc3a1a3a436db95ed2f6ba446a66
4
+ data.tar.gz: dbb7b187b7a2d0224727c8bad33ff25e26cb9fe5
5
5
  SHA512:
6
- metadata.gz: 1d41de85a3be6bb7e6d271c170c169358a46a8501e52023b13a1fc74df4633c5be597798359312e805666156e85119b6911d712981ca35fd1a3c8105c616f468
7
- data.tar.gz: c0970c8ed8a6daefe39fc0bf136d54d58872255d0dfdaef1ebf4aff500fd1511e369af3c0c06f81c52153ca5cbcc29a12a884380a59256fff8f9274e4c533cf4
6
+ metadata.gz: 407da45de0345dd8d3e3e857b4e02038aa9c8d379d9dc49c49ae30cb100ba0ade7d82a3cf348001b59c9c0d15debea59203ec0a034fd59039e34895aca80a5d9
7
+ data.tar.gz: 8584f6ffac8f1157e9e78ca6f1d158cc67f603f669480f400c16c8e9f8ea8425f508d65a78a5d3ef8b88072c4df67012cdad477faebd69b31091b2975e6665e2
data/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## Development
4
4
 
5
+ ## v1.2.2
6
+
7
+ * Fix error `singleton can't be dumped (TypeError)` at the end of dynamic analysis ([#17](https://github.com/yujinakayama/transpec/issues/17))
8
+ * Do not copy pseudo files (device, socket, etc.) in dynamic analysis ([#17](https://github.com/yujinakayama/transpec/issues/17))
9
+ * Fix error `undefined method receive_messages_available?` while conversion ([#17](https://github.com/yujinakayama/transpec/issues/17))
10
+
5
11
  ## v1.2.1
6
12
 
7
13
  * Apply `-p/--no-parentheses-matcher-arg` to the conversion of `have(n).items` (`obj.should have(n).items` is now converted to `expect(obj.size).to eq n` with `-p/--no-parentheses-matcher-arg`)
data/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  # Transpec
4
4
 
5
- **Transpec** automatically converts your specs into latest [RSpec](http://rspec.info/) syntax with static and dynamic code analysis.
5
+ **Transpec** automatically converts your specs into the latest [RSpec](http://rspec.info/) syntax with static and dynamic code analysis.
6
6
 
7
- This aims to facilitate smooth transition to RSpec 3, and is now ready for RSpec 2.99 and 3.0 beta!
7
+ This aims to facilitate smooth transition to RSpec 3, and it's now ready for RSpec 2.99 and 3.0 beta!
8
8
 
9
9
  See the following pages for the new RSpec syntax and the plan for RSpec 3:
10
10
 
@@ -154,6 +154,12 @@ $ git commit -eF .git/COMMIT_EDITMSG
154
154
 
155
155
  And you are done!
156
156
 
157
+ ## Upgrade Process to RSpec 3 beta
158
+
159
+ If you are going to use Transpec in the upgrade process to RSpec 3 beta, read the article by [Myron Marston](https://github.com/myronmarston):
160
+
161
+ * [Myron Marston » RSpec 2.99 and 3.0 betas have been released!](http://myronmars.to/n/dev-blog/2013/11/rspec-2-99-and-3-0-betas-have-been-released)
162
+
157
163
  ## Options
158
164
 
159
165
  ### `-f/--force`
data/README.md.erb CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  # Transpec
4
4
 
5
- **Transpec** automatically converts your specs into latest [RSpec](http://rspec.info/) syntax with static and dynamic code analysis.
5
+ **Transpec** automatically converts your specs into the latest [RSpec](http://rspec.info/) syntax with static and dynamic code analysis.
6
6
 
7
- This aims to facilitate smooth transition to RSpec 3, and is now ready for RSpec 2.99 and 3.0 beta!
7
+ This aims to facilitate smooth transition to RSpec 3, and it's now ready for RSpec 2.99 and 3.0 beta!
8
8
 
9
9
  See the following pages for the new RSpec syntax and the plan for RSpec 3:
10
10
 
@@ -127,6 +127,12 @@ $ git commit -eF .git/COMMIT_EDITMSG
127
127
 
128
128
  And you are done!
129
129
 
130
+ ## Upgrade Process to RSpec 3 beta
131
+
132
+ If you are going to use Transpec in the upgrade process to RSpec 3 beta, read the article by [Myron Marston](https://github.com/myronmarston):
133
+
134
+ * [Myron Marston » RSpec 2.99 and 3.0 betas have been released!](http://myronmars.to/n/dev-blog/2013/11/rspec-2-99-and-3-0-betas-have-been-released)
135
+
130
136
  ## Options
131
137
 
132
138
  ### `-f/--force`
data/lib/transpec.rb CHANGED
@@ -16,7 +16,7 @@ module Transpec
16
16
  if rspec_dependency
17
17
  rspec_requirement = rspec_dependency.requirement
18
18
  gem_version = rspec_requirement.requirements.first.find { |r| r.is_a?(Gem::Version) }
19
- RSpecVersion.new(gem_version.to_s)
19
+ RSpecVersion.new(gem_version)
20
20
  else
21
21
  # Using development version of RSpec with Bundler.
22
22
  current_rspec_version
@@ -13,7 +13,7 @@ module Transpec
13
13
  conversion_summary = @report.summary(bullet: '*', separate_by_blank_line: true)
14
14
 
15
15
  <<-END.gsub(/^\s+\|/, '').chomp
16
- |Convert specs to latest RSpec syntax with Transpec
16
+ |Convert specs to the latest RSpec syntax with Transpec
17
17
  |
18
18
  |This conversion is done by Transpec #{Transpec::Version} with the following command:
19
19
  | transpec #{@cli_args.join(' ')}
@@ -5,8 +5,9 @@ require 'transpec/dynamic_analyzer/runtime_data'
5
5
  require 'transpec/file_finder'
6
6
  require 'transpec/project'
7
7
  require 'tmpdir'
8
+ require 'find'
9
+ require 'pathname'
8
10
  require 'fileutils'
9
- require 'ostruct'
10
11
  require 'shellwords'
11
12
  require 'English'
12
13
 
@@ -15,10 +16,10 @@ module Transpec
15
16
  EVAL_TARGET_TYPES = [:object, :context]
16
17
  ANALYSIS_METHOD = 'transpec_analysis'
17
18
  HELPER_FILE = 'transpec_analysis_helper.rb'
18
- RESULT_FILE = 'transpec_analysis_result.dump'
19
+ RESULT_FILE = 'transpec_analysis_result.json'
19
20
  HELPER_SOURCE = <<-END
20
- require 'ostruct'
21
21
  require 'pathname'
22
+ require 'json'
22
23
 
23
24
  module TranspecAnalysis
24
25
  @base_path = Dir.pwd
@@ -38,9 +39,14 @@ module Transpec
38
39
  end
39
40
 
40
41
  at_exit do
42
+ # Use JSON rather than Marshal so that:
43
+ # * Unknown third-party class information won't be serialized.
44
+ # (Such objects are stored as a string.)
45
+ # * Singleton method information won't be serialized.
46
+ # (With Marshal.load, `singleton can't be dumped (TypeError)` will be raised.)
41
47
  path = File.join(@base_path, '#{RESULT_FILE}')
42
48
  File.open(path, 'w') do |file|
43
- Marshal.dump(data, file)
49
+ JSON.dump(data, file)
44
50
  end
45
51
  end
46
52
  end
@@ -52,12 +58,12 @@ module Transpec
52
58
  when :context then context
53
59
  end
54
60
 
55
- eval_data = OpenStruct.new
61
+ eval_data = {}
56
62
 
57
63
  begin
58
- eval_data.result = target.instance_eval(code)
64
+ eval_data[:result] = target.instance_eval(code)
59
65
  rescue Exception => error
60
- eval_data.error = error
66
+ eval_data[:error] = error
61
67
  end
62
68
 
63
69
  [key, eval_data]
@@ -112,8 +118,7 @@ module Transpec
112
118
  run_rspec(paths)
113
119
 
114
120
  File.open(RESULT_FILE) do |file|
115
- hash = Marshal.load(file)
116
- RuntimeData.new(hash)
121
+ RuntimeData.load(file)
117
122
  end
118
123
  end
119
124
  end
@@ -124,7 +129,7 @@ module Transpec
124
129
  @in_copied_project = true
125
130
 
126
131
  Dir.mktmpdir do |tmpdir|
127
- FileUtils.cp_r(@project.path, tmpdir)
132
+ copy_recursively(@project.path, tmpdir)
128
133
  @copied_project_path = File.join(tmpdir, @project.basename)
129
134
  Dir.chdir(@copied_project_path) do
130
135
  yield
@@ -156,5 +161,45 @@ module Transpec
156
161
  end
157
162
  end
158
163
  end
164
+
165
+ def copy_recursively(source_root, destination_root)
166
+ source_root = File.expand_path(source_root)
167
+ source_root_pathname = Pathname.new(source_root)
168
+
169
+ destination_root = File.expand_path(destination_root)
170
+ if File.directory?(destination_root)
171
+ destination_root = File.join(destination_root, File.basename(source_root))
172
+ end
173
+
174
+ Find.find(source_root) do |source_path|
175
+ relative_path = Pathname.new(source_path).relative_path_from(source_root_pathname).to_s
176
+ destination_path = File.join(destination_root, relative_path)
177
+ copy(source_path, destination_path)
178
+ end
179
+ end
180
+
181
+ private
182
+
183
+ def copy(source, destination)
184
+ if File.symlink?(source)
185
+ File.symlink(File.readlink(source), destination)
186
+ elsif File.directory?(source)
187
+ FileUtils.mkdir_p(destination)
188
+ elsif File.file?(source)
189
+ FileUtils.copy_file(source, destination)
190
+ end
191
+
192
+ copy_permission(source, destination) if File.exist?(destination)
193
+ end
194
+
195
+ def copy_permission(source, destination)
196
+ source_mode = File.lstat(source).mode
197
+ begin
198
+ File.lchmod(source_mode, destination)
199
+ rescue NotImplementedError, Errno::ENOSYS
200
+ # Should not change mode of symlink's destination.
201
+ File.chmod(source_mode, destination) unless File.symlink?(destination)
202
+ end
203
+ end
159
204
  end
160
205
  end
@@ -1,18 +1,26 @@
1
1
  # coding: utf-8
2
2
 
3
+ require 'json'
4
+ require 'ostruct'
3
5
  require 'pathname'
4
6
 
5
7
  module Transpec
6
8
  class DynamicAnalyzer
7
9
  class RuntimeData
8
- attr_reader :hash
10
+ attr_reader :data
9
11
 
10
- def initialize(hash = {})
11
- @hash = hash
12
+ def self.load(string_or_io)
13
+ options = { object_class: CompatibleOpenStruct, symbolize_names: true }
14
+ data = JSON.load(string_or_io, nil, options)
15
+ new(data)
16
+ end
17
+
18
+ def initialize(data = CompatibleOpenStruct.new)
19
+ @data = data
12
20
  end
13
21
 
14
22
  def [](node)
15
- @hash[node_id(node)]
23
+ @data[node_id(node)]
16
24
  end
17
25
 
18
26
  def node_id(node)
@@ -22,6 +30,21 @@ module Transpec
22
30
  relative_path = Pathname.new(absolute_path).relative_path_from(Pathname.pwd).to_s
23
31
  [relative_path, source_range.begin_pos, source_range.end_pos].join('_')
24
32
  end
33
+
34
+ class CompatibleOpenStruct < OpenStruct
35
+ # OpenStruct#[] is available from Ruby 2.0.
36
+ unless method_defined?(:[])
37
+ def [](key)
38
+ __send__(key)
39
+ end
40
+ end
41
+
42
+ unless method_defined?(:[]=)
43
+ def []=(key, value)
44
+ __send__("#{key}=", value)
45
+ end
46
+ end
47
+ end
25
48
  end
26
49
  end
27
50
  end
@@ -3,7 +3,11 @@
3
3
  require 'transpec'
4
4
 
5
5
  module Transpec
6
- class RSpecVersion < Gem::Version
6
+ # Gem::Version caches its instances with class variable @@all,
7
+ # so we should not inherit it.
8
+ class RSpecVersion
9
+ include Comparable
10
+
7
11
  # http://www.ruby-doc.org/stdlib-2.0.0/libdoc/rubygems/rdoc/Gem/Version.html
8
12
  #
9
13
  # If any part contains letters (currently only a-z are supported) then that version is
@@ -11,15 +15,33 @@ module Transpec
11
15
  # Prerelease parts are sorted alphabetically using the normal Ruby string sorting rules.
12
16
  # If a prerelease part contains both letters and numbers, it will be broken into multiple parts
13
17
  # to provide expected sort behavior (1.0.a10 becomes 1.0.a.10, and is greater than 1.0.a9).
14
- VERSION_2_99 = new('2.99.aaaaaaaaaa')
15
- VERSION_3_0 = new('3.0.aaaaaaaaaa')
18
+ GEM_VERSION_2_99 = Gem::Version.new('2.99.aaaaaaaaaa')
19
+ GEM_VERSION_3_0 = Gem::Version.new('3.0.aaaaaaaaaa')
20
+
21
+ attr_reader :gem_version
22
+
23
+ def initialize(version)
24
+ @gem_version = if version.is_a?(Gem::Version)
25
+ version
26
+ else
27
+ Gem::Version.new(version)
28
+ end
29
+ end
16
30
 
17
31
  def be_truthy_available?
18
- self >= VERSION_2_99
32
+ @gem_version >= GEM_VERSION_2_99
19
33
  end
20
34
 
21
35
  def receive_messages_available?
22
- self >= VERSION_3_0
36
+ @gem_version >= GEM_VERSION_3_0
37
+ end
38
+
39
+ def <=>(other)
40
+ @gem_version <=> other.gem_version
41
+ end
42
+
43
+ def to_s
44
+ @gem_version.to_s
23
45
  end
24
46
  end
25
47
  end
@@ -98,8 +98,9 @@ module Transpec
98
98
 
99
99
  def query_method
100
100
  node_data = runtime_node_data(@expectation.subject_node)
101
- if node_data
102
- (QUERY_METHOD_PRIORITIES & node_data[:available_query_methods].result).first
101
+ if node_data && node_data[:available_query_methods].result.is_a?(Array)
102
+ available_query_methods = node_data[:available_query_methods].result.map(&:to_sym)
103
+ (QUERY_METHOD_PRIORITIES & available_query_methods).first
103
104
  else
104
105
  default_query_method
105
106
  end
@@ -5,7 +5,7 @@ module Transpec
5
5
  module Version
6
6
  MAJOR = 1
7
7
  MINOR = 2
8
- PATCH = 1
8
+ PATCH = 2
9
9
 
10
10
  def self.to_s
11
11
  [MAJOR, MINOR, PATCH].join('.')
@@ -48,7 +48,8 @@ module CacheHelper
48
48
  def cache_dir
49
49
  @cache_dir ||= begin
50
50
  project_root = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
51
- cache_dir = File.join(project_root, 'tmp', 'spec_cache')
51
+ ruby_version = "#{RUBY_ENGINE}#{RUBY_VERSION}"
52
+ cache_dir = File.join(project_root, 'tmp', 'spec_cache', ruby_version)
52
53
 
53
54
  unless Dir.exist?(cache_dir)
54
55
  require 'fileutils'
@@ -27,7 +27,7 @@ module Transpec
27
27
  let(:lines) { commit_message.to_s.lines.to_a }
28
28
 
29
29
  it 'has concise summary at first line' do
30
- lines[0].chomp.should == 'Convert specs to latest RSpec syntax with Transpec'
30
+ lines[0].chomp.should == 'Convert specs to the latest RSpec syntax with Transpec'
31
31
  end
32
32
 
33
33
  it 'has blank line at second line' do
@@ -167,14 +167,71 @@ module Transpec
167
167
 
168
168
  subject(:element) { runtime_data[target_node] }
169
169
 
170
- it 'is a hash' do
171
- should be_a(Hash)
170
+ it 'is an OpenStruct' do
171
+ should be_a(OpenStruct)
172
172
  end
173
173
 
174
174
  it 'has result of requested analysis' do
175
- element[:available_query_methods].result.should =~ [:size, :count, :length]
175
+ element[:available_query_methods].result.should =~ %w(size count length)
176
176
  end
177
177
  end
178
178
  end
179
+
180
+ describe '#copy_recursively' do
181
+ it 'copies files recursively' do
182
+ [
183
+ 'src/file1',
184
+ 'src/file2',
185
+ 'src/dir1/file',
186
+ 'src/dir2/file'
187
+ ].each do |path|
188
+ create_file(path, '')
189
+ end
190
+
191
+ dynamic_analyzer.copy_recursively('src', 'dst')
192
+
193
+ [
194
+ 'dst/file1',
195
+ 'dst/file2',
196
+ 'dst/dir1/file',
197
+ 'dst/dir2/file'
198
+ ].each do |path|
199
+ File.exist?(path).should be_true
200
+ end
201
+ end
202
+
203
+ it 'copies only directories, files and symlinks' do
204
+ create_file('src/file', '')
205
+ File.symlink('file', 'src/symlink')
206
+ Dir.mkdir('src/dir')
207
+ system('mkfifo', 'src/fifo')
208
+
209
+ dynamic_analyzer.copy_recursively('src', 'dst')
210
+
211
+ File.file?('dst/file').should be_true
212
+ File.symlink?('dst/symlink').should be_true
213
+ File.directory?('dst/dir').should be_true
214
+ File.exist?('dst/fifo').should be_false
215
+ end
216
+
217
+ def permission(path)
218
+ format('%o', File.lstat(path).mode)[-4..-1]
219
+ end
220
+
221
+ it 'preserves permission' do
222
+ create_file('src/file', '')
223
+ File.chmod(0755, 'src/file')
224
+
225
+ File.symlink('file', 'src/symlink')
226
+
227
+ Dir.mkdir('src/dir')
228
+ File.chmod(0600, 'src/dir')
229
+
230
+ dynamic_analyzer.copy_recursively('src', 'dst')
231
+
232
+ permission('dst/file').should == '0755'
233
+ permission('dst/dir').should == '0600'
234
+ end
235
+ end
179
236
  end
180
237
  end
@@ -64,6 +64,13 @@ class TranspecTest
64
64
  next if ['.', '..', 'tmp'].include?(entry)
65
65
  FileUtils.cp_r(entry, project_dir)
66
66
  end
67
+
68
+ spec_cache_dir = File.join('tmp', 'spec_cache')
69
+
70
+ if Dir.exist?(spec_cache_dir)
71
+ Dir.mkdir(File.join(project_dir, 'tmp'))
72
+ FileUtils.cp_r(spec_cache_dir, File.join(project_dir, spec_cache_dir))
73
+ end
67
74
  end
68
75
 
69
76
  bundle_install
data/tasks/readme.rake CHANGED
@@ -5,13 +5,6 @@ task :readme do
5
5
  require 'erb'
6
6
  require 'transpec/cli'
7
7
 
8
- gem_specification = Gem::Specification.load('transpec.gemspec')
9
- rspec_dependency = gem_specification.dependencies.find { |d| d.name == 'rspec' }
10
- rspec_requirement = rspec_dependency.requirement
11
- # rubocop:disable UselessAssignment
12
- rspec_version = rspec_requirement.requirements.first.find { |r| r.is_a?(Gem::Version) }
13
- # rubocop:enable UselessAssignment
14
-
15
8
  erb = ERB.new(File.read('README.md.erb'), nil, '-')
16
9
  content = erb.result(binding)
17
10
  File.write('README.md', content)
data/transpec.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.authors = ['Yuji Nakayama']
11
11
  spec.email = ['nkymyj@gmail.com']
12
12
  spec.summary = 'A RSpec syntax converter'
13
- spec.description = 'Transpec converts your specs into latest RSpec syntax ' +
13
+ spec.description = 'Transpec converts your specs into the latest RSpec syntax ' +
14
14
  'with static and dynamic code analysis.'
15
15
  spec.homepage = 'https://github.com/yujinakayama/transpec'
16
16
  spec.license = 'MIT'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: transpec
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuji Nakayama
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-09 00:00:00.000000000 Z
11
+ date: 2013-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -164,8 +164,8 @@ dependencies:
164
164
  - - ~>
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0.3'
167
- description: Transpec converts your specs into latest RSpec syntax with static and
168
- dynamic code analysis.
167
+ description: Transpec converts your specs into the latest RSpec syntax with static
168
+ and dynamic code analysis.
169
169
  email:
170
170
  - nkymyj@gmail.com
171
171
  executables: