transpec 1.1.2 → 1.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: 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