transpec 1.1.2 → 1.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: e4b8ad9709db52ce5becc1fe21c78454138667a5
4
- data.tar.gz: 91977cdc9490c4fd3878769d0308cc01f551a7ff
3
+ metadata.gz: e113c8ac0e1041e1b1704f1119af7e1dc57567ad
4
+ data.tar.gz: 5f531ea384b0ff31c32126bf03cc88d69474c2bd
5
5
  SHA512:
6
- metadata.gz: 1656fc0b87a530e09d986213f76cb3ec52efd78d7fc5106ddb4d555461f8699ad10f2bd23c4fe4b8ca49a3fe78bd926b2123231e95a9cefc6ce69bf9cc5ec6db
7
- data.tar.gz: efa265154035cc620e19e4b7ce0e87345337c152f34f737a87c85820d96e02421002b5f596292ab9ceba1810292f8dfb3b53314168050719c69e195905eef2b3
6
+ metadata.gz: 4dda416fa2df40afd219d2b78b0c7420c0850cec9c31d3607fec6c3623bf38a712a778c428fda819a9b1cf1d8370be8a43042e40763e299ad65fd306e5525d2a
7
+ data.tar.gz: 67de6752f2ea60e243c850efa449a807be0d52cb8f4d3d25182b89c52599788f8e40b244c7f5ec20dc980b4e46634a338c37fd3989789309d7ab248ff4522c4c
data/.gitignore CHANGED
@@ -12,7 +12,6 @@ lib/bundler/man
12
12
  pkg
13
13
  rdoc
14
14
  spec/reports
15
- spec/cache
16
15
  test/tmp
17
16
  test/version_tmp
18
17
  tmp
data/.rubocop.yml CHANGED
@@ -50,4 +50,4 @@ IndentationWidth:
50
50
 
51
51
  # TODO: Shorten to 100.
52
52
  ClassLength:
53
- Max: 194
53
+ Max: 150
data/CHANGELOG.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # Changelog
2
2
 
3
- ## Master
3
+ ## Development
4
+
5
+ ## v1.2.0
6
+
7
+ * Transpec is now ready for RSpec 2.99 and 3.0 beta!
8
+ * Support conversion to `allow(obj).to receive_messages(:message => value)` ([#6](https://github.com/yujinakayama/transpec/issues/6))
9
+ * Support conversion to `be_truthy` / `be_falsey` ([#8](https://github.com/yujinakayama/transpec/issues/8))
10
+ * Add `-b/--boolean-matcher` option that allows to specify matcher type that `be_true` and `be_false` will be converted to
11
+ * Abort if a target project's `rspec` gem dependency is older than the version required by Transpec
4
12
 
5
13
  ## v1.1.2
6
14
 
@@ -12,7 +20,7 @@
12
20
 
13
21
  ## v1.1.0
14
22
 
15
- * Support conversion of `its` (#9)
23
+ * Support conversion of `its` ([#9](https://github.com/yujinakayama/transpec/issues/9))
16
24
 
17
25
  ## v1.0.0
18
26
 
data/Guardfile CHANGED
@@ -1,7 +1,7 @@
1
1
  # A sample Guardfile
2
2
  # More info at https://github.com/guard/guard#readme
3
3
 
4
- guard :rspec, all_after_pass: true, all_on_start: true, keep_failed: true do
4
+ guard :rspec, all_after_pass: true, all_on_start: true, keep_failed: true, cmd: 'bundle exec rspec' do
5
5
  watch(%r{^spec/.+_spec\.rb$})
6
6
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
7
7
  watch('spec/spec_helper.rb') { "spec" }
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  **Transpec** automatically converts your specs into latest [RSpec](http://rspec.info/) syntax with static and dynamic code analysis.
6
6
 
7
- This aims to facilitate smooth transition to RSpec 3.
7
+ This aims to facilitate smooth transition to RSpec 3, and Transpec is 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
 
@@ -354,6 +354,39 @@ expect([1, 2, 3]).to match_array([2, 1, 3])
354
354
 
355
355
  * See also: [(Almost) All Matchers Are Supported - RSpec's New Expectation Syntax](http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax#almost_all_matchers_are_supported)
356
356
 
357
+ ### Boolean matchers
358
+
359
+ **This conversion is available only if your project has `rspec` gem dependency `2.99` or later.**
360
+
361
+ ```ruby
362
+ # Targets
363
+ expect(obj).to be_true
364
+ expect(obj).to be_false
365
+
366
+ # Converted
367
+ expect(obj).to be_truthy
368
+ expect(obj).to be_falsey
369
+
370
+ # With `--boolean-matcher truthy,falsy`
371
+ # be_falsy is just an alias of be_falsey.
372
+ expect(obj).to be_truthy
373
+ expect(obj).to be_falsy
374
+
375
+ # With `--boolean-matcher true,false`
376
+ expect(obj).to be true
377
+ expect(obj).to be false
378
+ ```
379
+
380
+ * `be_true` matcher passes if expectation subject is _truthy_ in conditional semantics. (i.e. all objects except `false` and `nil`)
381
+ * `be_false` matcher passes if expectation subject is _falsey_ in conditional semantics. (i.e. `false` or `nil`)
382
+ * `be_truthy` and `be_falsey` matchers are renamed version of `be_true` and `be_false` and their behaviors are same.
383
+ * `be true` and `be false` are not new things. These are combinations of `be` matcher and boolean literals. These pass if expectation subject is exactly equal to boolean value.
384
+
385
+ So, converting `be_true`/`be_false` to `be_truthy`/`be_falsey` never breaks your specs and this is the Transpec's default. If you are willing to test boolean values strictly, you can convert them to `be true`/`be false` with `--boolean-matcher true,false` option. Note that this may break your specs if your library codes don't return exact boolean values.
386
+
387
+ * Disabled by: `--keep deprecated`
388
+ * See also: [Consider renaming `be_true` and `be_false` to `be_truthy` and `be_falsey` · rspec/rspec-expectations](https://github.com/rspec/rspec-expectations/issues/283)
389
+
357
390
  ### `be_close` matcher
358
391
 
359
392
  ```ruby
@@ -485,14 +518,20 @@ allow(obj).to receive(:foo)
485
518
 
486
519
  allow(obj).to receive(:foo)
487
520
 
521
+ # If the target project's rspec gem dependency is prior to 3.0
488
522
  allow(obj).to receive(:foo).and_return(1)
489
523
  allow(obj).to receive(:bar).and_return(2)
490
524
 
525
+ # If the target project's rspec gem dependency is 3.0 or later
526
+ allow(obj).to receive_messages(:foo => 1, :bar => 2)
527
+
491
528
  allow_any_instance_of(SomeClass).to receive(:foo)
492
529
  ```
493
530
 
494
531
  * Disabled by: `--keep stub`
495
- * See also: [RSpec's new message expectation syntax - Tea is awesome.](http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/)
532
+ * See also:
533
+ * [RSpec's new message expectation syntax - Tea is awesome.](http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/)
534
+ * [allow receive with multiple methods · rspec/rspec-mocks](https://github.com/rspec/rspec-mocks/issues/368)
496
535
 
497
536
  ### Deprecated method stub aliases
498
537
 
data/README.md.erb CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  **Transpec** automatically converts your specs into latest [RSpec](http://rspec.info/) syntax with static and dynamic code analysis.
6
6
 
7
- This aims to facilitate smooth transition to RSpec 3.
7
+ This aims to facilitate smooth transition to RSpec 3, and Transpec is 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
 
@@ -82,7 +82,7 @@ $ gem install transpec
82
82
 
83
83
  Before converting your specs:
84
84
 
85
- * Make sure your project has `rspec` gem dependency `<%= rspec_version %>` or later. If not, change your `*.gemspec` or `Gemfile` to do so.
85
+ * Make sure your project has `rspec` gem dependency `<%= Transpec.required_rspec_version %>` or later. If not, change your `*.gemspec` or `Gemfile` to do so.
86
86
  * Run `rspec` and check if all the specs pass.
87
87
  * Ensure the Git repository is clean. (You don't want to mix up your changes and Transpec's changes, right?)
88
88
 
@@ -350,6 +350,39 @@ expect([1, 2, 3]).to match_array([2, 1, 3])
350
350
 
351
351
  * See also: [(Almost) All Matchers Are Supported - RSpec's New Expectation Syntax](http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax#almost_all_matchers_are_supported)
352
352
 
353
+ ### Boolean matchers
354
+
355
+ **This conversion is available only if your project has `rspec` gem dependency `2.99` or later.**
356
+
357
+ ```ruby
358
+ # Targets
359
+ expect(obj).to be_true
360
+ expect(obj).to be_false
361
+
362
+ # Converted
363
+ expect(obj).to be_truthy
364
+ expect(obj).to be_falsey
365
+
366
+ # With `--boolean-matcher truthy,falsy`
367
+ # be_falsy is just an alias of be_falsey.
368
+ expect(obj).to be_truthy
369
+ expect(obj).to be_falsy
370
+
371
+ # With `--boolean-matcher true,false`
372
+ expect(obj).to be true
373
+ expect(obj).to be false
374
+ ```
375
+
376
+ * `be_true` matcher passes if expectation subject is _truthy_ in conditional semantics. (i.e. all objects except `false` and `nil`)
377
+ * `be_false` matcher passes if expectation subject is _falsey_ in conditional semantics. (i.e. `false` or `nil`)
378
+ * `be_truthy` and `be_falsey` matchers are renamed version of `be_true` and `be_false` and their behaviors are same.
379
+ * `be true` and `be false` are not new things. These are combinations of `be` matcher and boolean literals. These pass if expectation subject is exactly equal to boolean value.
380
+
381
+ So, converting `be_true`/`be_false` to `be_truthy`/`be_falsey` never breaks your specs and this is the Transpec's default. If you are willing to test boolean values strictly, you can convert them to `be true`/`be false` with `--boolean-matcher true,false` option. Note that this may break your specs if your library codes don't return exact boolean values.
382
+
383
+ * Disabled by: `--keep deprecated`
384
+ * See also: [Consider renaming `be_true` and `be_false` to `be_truthy` and `be_falsey` · rspec/rspec-expectations](https://github.com/rspec/rspec-expectations/issues/283)
385
+
353
386
  ### `be_close` matcher
354
387
 
355
388
  ```ruby
@@ -481,14 +514,20 @@ allow(obj).to receive(:foo)
481
514
 
482
515
  allow(obj).to receive(:foo)
483
516
 
517
+ # If the target project's rspec gem dependency is prior to 3.0
484
518
  allow(obj).to receive(:foo).and_return(1)
485
519
  allow(obj).to receive(:bar).and_return(2)
486
520
 
521
+ # If the target project's rspec gem dependency is 3.0 or later
522
+ allow(obj).to receive_messages(:foo => 1, :bar => 2)
523
+
487
524
  allow_any_instance_of(SomeClass).to receive(:foo)
488
525
  ```
489
526
 
490
527
  * Disabled by: `--keep stub`
491
- * See also: [RSpec's new message expectation syntax - Tea is awesome.](http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/)
528
+ * See also:
529
+ * [RSpec's new message expectation syntax - Tea is awesome.](http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/)
530
+ * [allow receive with multiple methods · rspec/rspec-mocks](https://github.com/rspec/rspec-mocks/issues/368)
492
531
 
493
532
  ### Deprecated method stub aliases
494
533
 
data/lib/transpec/cli.rb CHANGED
@@ -6,18 +6,20 @@ require 'transpec/converter'
6
6
  require 'transpec/dynamic_analyzer'
7
7
  require 'transpec/file_finder'
8
8
  require 'transpec/option_parser'
9
+ require 'transpec/project'
9
10
  require 'transpec/report'
10
11
  require 'rainbow'
11
12
 
12
13
  module Transpec
13
14
  class CLI
14
- attr_reader :configuration
15
+ attr_reader :project, :configuration, :report
15
16
 
16
17
  def self.run(args = ARGV)
17
18
  new.run(args)
18
19
  end
19
20
 
20
21
  def initialize
22
+ @project = Project.new
21
23
  @configuration = Configuration.new
22
24
  @report = Report.new
23
25
  end
@@ -60,7 +62,7 @@ module Transpec
60
62
  def convert_file(file_path, runtime_data = nil)
61
63
  puts "Converting #{file_path}"
62
64
 
63
- converter = Converter.new(@configuration, runtime_data, @report)
65
+ converter = Converter.new(@configuration, @project.rspec_version, runtime_data, @report)
64
66
  converter.convert_file!(file_path)
65
67
 
66
68
  @report.invalid_context_errors.concat(converter.invalid_context_errors)
@@ -76,11 +78,16 @@ module Transpec
76
78
  private
77
79
 
78
80
  def fail_if_should_not_continue!
79
- return if @configuration.forced?
80
- return unless Git.command_available?
81
- return unless Git.inside_of_repository?
82
- return if Git.clean?
83
- fail 'The current Git repository is not clean. Aborting.'
81
+ unless @configuration.forced?
82
+ if Git.command_available? && Git.inside_of_repository? && !Git.clean?
83
+ fail 'The current Git repository is not clean. Aborting.'
84
+ end
85
+ end
86
+
87
+ if @project.rspec_version < Transpec.required_rspec_version
88
+ fail "Your project must have rspec gem dependency #{Transpec.required_rspec_version} " +
89
+ "or later but currently it's #{@project.rspec_version}. Aborting."
90
+ end
84
91
  end
85
92
 
86
93
  def display_summary
@@ -109,6 +116,8 @@ module Transpec
109
116
  end
110
117
 
111
118
  def display_final_guide
119
+ return if @report.records.empty?
120
+
112
121
  puts
113
122
  puts "Done! Now run #{'rspec'.bright} and check if all the converted specs pass."
114
123
  end
@@ -3,6 +3,8 @@
3
3
  module Transpec
4
4
  class Configuration
5
5
  NEGATIVE_FORMS_OF_TO = ['not_to', 'to_not'].freeze
6
+ FORMS_OF_BE_FALSEY = ['be_falsey', 'be_falsy'].freeze
7
+ BOOLEAN_MATCHER_TYPES = [:conditional, :exact].freeze
6
8
 
7
9
  PREDICATES = [
8
10
  [:convert_should, true],
@@ -22,7 +24,7 @@ module Transpec
22
24
  alias_method predicate.to_s + '?', predicate
23
25
  end
24
26
 
25
- attr_accessor :negative_form_of_to, :rspec_command
27
+ attr_accessor :negative_form_of_to, :boolean_matcher_type, :form_of_be_falsey, :rspec_command
26
28
 
27
29
  def initialize
28
30
  PREDICATES.each do |predicate, default_value|
@@ -30,16 +32,32 @@ module Transpec
30
32
  end
31
33
 
32
34
  self.negative_form_of_to = 'not_to'
35
+ self.boolean_matcher_type = :conditional
36
+ self.form_of_be_falsey = 'be_falsey'
33
37
  end
34
38
 
35
39
  def negative_form_of_to=(form)
36
- unless NEGATIVE_FORMS_OF_TO.include?(form.to_s)
37
- message = 'Negative form of "to" must be either '
38
- message << NEGATIVE_FORMS_OF_TO.map(&:inspect).join(' or ')
39
- fail ArgumentError, message
40
- end
41
-
40
+ validate!(form.to_s, NEGATIVE_FORMS_OF_TO, 'Negative form of "to"')
42
41
  @negative_form_of_to = form.to_s.freeze
43
42
  end
43
+
44
+ def boolean_matcher_type=(type)
45
+ validate!(type.to_sym, BOOLEAN_MATCHER_TYPES, 'Boolean matcher type')
46
+ @boolean_matcher_type = type.to_sym
47
+ end
48
+
49
+ def form_of_be_falsey=(form)
50
+ validate!(form.to_s, FORMS_OF_BE_FALSEY, 'Form of "be_falsey"')
51
+ @form_of_be_falsey = form.to_s.freeze
52
+ end
53
+
54
+ private
55
+
56
+ def validate!(arg, valid_values, subject)
57
+ return if valid_values.include?(arg)
58
+ message = "#{subject} must be either "
59
+ message << valid_values.map(&:inspect).join(' or ')
60
+ fail ArgumentError, message
61
+ end
44
62
  end
45
63
  end
@@ -3,7 +3,9 @@
3
3
  require 'transpec/base_rewriter'
4
4
  require 'transpec/configuration'
5
5
  require 'transpec/report'
6
+ require 'transpec/rspec_version'
6
7
  require 'transpec/syntax'
8
+ require 'transpec/syntax/be_boolean'
7
9
  require 'transpec/syntax/be_close'
8
10
  require 'transpec/syntax/double'
9
11
  require 'transpec/syntax/expect'
@@ -16,13 +18,14 @@ require 'transpec/syntax/should_receive'
16
18
 
17
19
  module Transpec
18
20
  class Converter < BaseRewriter
19
- attr_reader :configuration, :runtime_data, :report, :invalid_context_errors
21
+ attr_reader :configuration, :rspec_version, :runtime_data, :report, :invalid_context_errors
20
22
 
21
23
  alias_method :convert_file!, :rewrite_file!
22
24
  alias_method :convert, :rewrite
23
25
 
24
- def initialize(configuration = nil, runtime_data = nil, report = nil)
26
+ def initialize(configuration = nil, rspec_version = nil, runtime_data = nil, report = nil)
25
27
  @configuration = configuration || Configuration.new
28
+ @rspec_version = rspec_version || Transpec.current_rspec_version
26
29
  @runtime_data = runtime_data
27
30
  @report = report || Report.new
28
31
  @invalid_context_errors = []
@@ -92,7 +95,7 @@ module Transpec
92
95
 
93
96
  def process_method_stub(method_stub)
94
97
  if @configuration.convert_stub?
95
- method_stub.allowize!
98
+ method_stub.allowize!(@rspec_version.receive_messages_available?)
96
99
  elsif @configuration.convert_deprecated_method?
97
100
  method_stub.convert_deprecated_method!
98
101
  end
@@ -100,6 +103,18 @@ module Transpec
100
103
  method_stub.remove_allowance_for_no_message! if @configuration.convert_deprecated_method?
101
104
  end
102
105
 
106
+ def process_be_boolean(be_boolean)
107
+ return unless @rspec_version.be_truthy_available?
108
+ return unless @configuration.convert_deprecated_method?
109
+
110
+ case @configuration.boolean_matcher_type
111
+ when :conditional
112
+ be_boolean.convert_to_conditional_matcher!(@configuration.form_of_be_falsey)
113
+ when :exact
114
+ be_boolean.convert_to_exact_matcher!
115
+ end
116
+ end
117
+
103
118
  def process_be_close(be_close)
104
119
  be_close.convert_to_be_within! if @configuration.convert_deprecated_method?
105
120
  end
@@ -1,8 +1,9 @@
1
1
  # coding: utf-8
2
2
 
3
- require 'transpec/file_finder'
4
3
  require 'transpec/dynamic_analyzer/rewriter'
5
4
  require 'transpec/dynamic_analyzer/runtime_data'
5
+ require 'transpec/file_finder'
6
+ require 'transpec/project'
6
7
  require 'tmpdir'
7
8
  require 'fileutils'
8
9
  require 'ostruct'
@@ -71,11 +72,11 @@ module Transpec
71
72
  end
72
73
  END
73
74
 
74
- attr_reader :project_path, :rspec_command, :silent
75
+ attr_reader :project, :rspec_command, :silent
75
76
  alias_method :silent?, :silent
76
77
 
77
78
  def initialize(options = {})
78
- @project_path = options[:project_path] || Dir.pwd
79
+ @project = options[:project] || Project.new
79
80
  @rspec_command = options[:rspec_command] || default_rspec_command
80
81
  @silent = options[:silent] || false
81
82
 
@@ -87,17 +88,13 @@ module Transpec
87
88
  end
88
89
 
89
90
  def default_rspec_command
90
- if project_requires_bundler?
91
+ if @project.require_bundler?
91
92
  'bundle exec rspec'
92
93
  else
93
94
  'rspec'
94
95
  end
95
96
  end
96
97
 
97
- def project_requires_bundler?
98
- File.exist?('Gemfile')
99
- end
100
-
101
98
  def analyze(paths = [])
102
99
  in_copied_project do
103
100
  rewriter = Rewriter.new
@@ -127,8 +124,8 @@ module Transpec
127
124
  @in_copied_project = true
128
125
 
129
126
  Dir.mktmpdir do |tmpdir|
130
- FileUtils.cp_r(@project_path, tmpdir)
131
- @copied_project_path = File.join(tmpdir, File.basename(@project_path))
127
+ FileUtils.cp_r(@project.path, tmpdir)
128
+ @copied_project_path = File.join(tmpdir, @project.basename)
132
129
  Dir.chdir(@copied_project_path) do
133
130
  yield
134
131
  end
@@ -138,7 +135,7 @@ module Transpec
138
135
  end
139
136
 
140
137
  def run_rspec(paths)
141
- with_bundler_clean_env do
138
+ @project.with_bundler_clean_env do
142
139
  ENV['SPEC_OPTS'] = ['-r', "./#{HELPER_FILE}"].shelljoin
143
140
 
144
141
  command = "#{rspec_command} #{paths.shelljoin}"
@@ -159,17 +156,5 @@ module Transpec
159
156
  end
160
157
  end
161
158
  end
162
-
163
- def with_bundler_clean_env
164
- if defined?(Bundler) && project_requires_bundler?
165
- Bundler.with_clean_env do
166
- # Bundler.with_clean_env cleans environment variables
167
- # which are set after bundler is loaded.
168
- yield
169
- end
170
- else
171
- yield
172
- end
173
- end
174
159
  end
175
160
  end
@@ -8,7 +8,7 @@ require 'rainbow'
8
8
 
9
9
  module Transpec
10
10
  class OptionParser
11
- CONFIG_ATTRS_FOR_CLI_TYPES = {
11
+ CONFIG_ATTRS_FOR_KEEP_TYPES = {
12
12
  should: :convert_should=,
13
13
  should_receive: :convert_should_receive=,
14
14
  stub: :convert_stub=,
@@ -17,10 +17,12 @@ module Transpec
17
17
  deprecated: :convert_deprecated_method=
18
18
  }
19
19
 
20
+ VALID_BOOLEAN_MATCHER_TYPES = %w(truthy,falsey truthy,falsy true,false)
21
+
20
22
  attr_reader :configuration
21
23
 
22
24
  def self.available_conversion_types
23
- CONFIG_ATTRS_FOR_CLI_TYPES.keys
25
+ CONFIG_ATTRS_FOR_KEEP_TYPES.keys
24
26
  end
25
27
 
26
28
  def initialize(configuration = Configuration.new)
@@ -66,7 +68,7 @@ module Transpec
66
68
 
67
69
  define_option('-k', '--keep TYPE[,TYPE...]') do |types|
68
70
  types.split(',').each do |type|
69
- config_attr = CONFIG_ATTRS_FOR_CLI_TYPES[type.to_sym]
71
+ config_attr = CONFIG_ATTRS_FOR_KEEP_TYPES[type.to_sym]
70
72
  fail ArgumentError, "Unknown syntax type #{type.inspect}" unless config_attr
71
73
  @configuration.send(config_attr, false)
72
74
  end
@@ -76,6 +78,15 @@ module Transpec
76
78
  @configuration.negative_form_of_to = form
77
79
  end
78
80
 
81
+ define_option('-b', '--boolean-matcher TYPE') do |type|
82
+ unless VALID_BOOLEAN_MATCHER_TYPES.include?(type)
83
+ types = VALID_BOOLEAN_MATCHER_TYPES.map(&:inspect).join(', ')
84
+ fail ArgumentError, "Boolean matcher type must be any of #{types}"
85
+ end
86
+ @configuration.boolean_matcher_type = type.include?('truthy') ? :conditional : :exact
87
+ @configuration.form_of_be_falsey = type.include?('falsy') ? 'be_falsy' : 'be_falsey'
88
+ end
89
+
79
90
  define_option('-p', '--no-parentheses-matcher-arg') do
80
91
  @configuration.parenthesize_matcher_arg = false
81
92
  end
@@ -142,6 +153,14 @@ module Transpec
142
153
  "Either #{'not_to'.bright} or #{'to_not'.bright}.",
143
154
  "Default: #{'not_to'.bright}"
144
155
  ],
156
+ '-b' => [
157
+ "Specify matcher type that #{'be_true'.underline} and",
158
+ "#{'be_false'.underline} will be converted to.",
159
+ " #{'truthy,falsey'.bright} (conditional semantics)",
160
+ " #{'truthy,falsy'.bright} (alias of #{'falsey'.underline})",
161
+ " #{'true,false'.bright} (exact equality)",
162
+ "Default: #{'truthy,falsey'.bright}"
163
+ ],
145
164
  '-p' => [
146
165
  'Suppress parenthesizing argument of matcher',
147
166
  'when converting operator to non-operator in',
@@ -0,0 +1,49 @@
1
+ # coding: utf-8
2
+
3
+ require 'transpec/rspec_version'
4
+
5
+ module Transpec
6
+ class Project
7
+ attr_reader :path
8
+
9
+ def initialize(path = Dir.pwd)
10
+ @path = path
11
+ end
12
+
13
+ def basename
14
+ File.basename(@path)
15
+ end
16
+
17
+ def require_bundler?
18
+ gemfile_path = File.join(@path, 'Gemfile')
19
+ File.exist?(gemfile_path)
20
+ end
21
+
22
+ def rspec_version
23
+ @rspec_version ||= begin
24
+ command = 'rspec --version'
25
+ command = 'bundle exec ' + command if require_bundler?
26
+
27
+ version_string = nil
28
+
29
+ Dir.chdir(@path) do
30
+ with_bundler_clean_env { version_string = `#{command}`.chomp }
31
+ end
32
+
33
+ RSpecVersion.new(version_string)
34
+ end
35
+ end
36
+
37
+ def with_bundler_clean_env
38
+ if defined?(Bundler) && require_bundler?
39
+ Bundler.with_clean_env do
40
+ # Bundler.with_clean_env cleans environment variables
41
+ # which are set after bundler is loaded.
42
+ yield
43
+ end
44
+ else
45
+ yield
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+
3
+ require 'transpec'
4
+
5
+ module Transpec
6
+ class RSpecVersion < Gem::Version
7
+ # http://www.ruby-doc.org/stdlib-2.0.0/libdoc/rubygems/rdoc/Gem/Version.html
8
+ #
9
+ # If any part contains letters (currently only a-z are supported) then that version is
10
+ # considered prerelease.
11
+ # Prerelease parts are sorted alphabetically using the normal Ruby string sorting rules.
12
+ # If a prerelease part contains both letters and numbers, it will be broken into multiple parts
13
+ # 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')
16
+
17
+ def be_truthy_available?
18
+ self >= VERSION_2_99
19
+ end
20
+
21
+ def receive_messages_available?
22
+ self >= VERSION_3_0
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+
3
+ require 'transpec/syntax'
4
+ require 'transpec/syntax/mixin/send'
5
+
6
+ module Transpec
7
+ class Syntax
8
+ class BeBoolean < Syntax
9
+ include Mixin::Send
10
+
11
+ def self.target_method?(receiver_node, method_name)
12
+ receiver_node.nil? && [:be_true, :be_false].include?(method_name)
13
+ end
14
+
15
+ def be_true?
16
+ method_name == :be_true
17
+ end
18
+
19
+ def convert_to_conditional_matcher!(form_of_be_falsey = 'be_falsey')
20
+ replacement = be_true? ? 'be_truthy' : form_of_be_falsey
21
+ replace(expression_range, replacement)
22
+ register_record(replacement)
23
+ end
24
+
25
+ def convert_to_exact_matcher!
26
+ replacement = be_true? ? 'be true' : 'be false'
27
+ replace(expression_range, replacement)
28
+ register_record(replacement)
29
+ end
30
+
31
+ private
32
+
33
+ def register_record(converted_syntax)
34
+ @report.records << Record.new(method_name.to_s, converted_syntax)
35
+ end
36
+ end
37
+ end
38
+ end