minitest_to_rspec 0.6.2 → 0.7.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: 3c9d5f1d2e46d2dda762773e68dbe9e52ab2fdf6
4
- data.tar.gz: e8c9aa28efe6397fdd477ca2fab1906eedd2ec76
3
+ metadata.gz: c5b86085638913b9300eac531234df1080da30f8
4
+ data.tar.gz: 25716e1fa38dd1770ecf4d6af06d1ae17e83f9b8
5
5
  SHA512:
6
- metadata.gz: fbb7261a6826ad41645eabe1e196d27e063885cee9d3f0597ca6634957a07986367216762cd99f23e06e5c0c0597a51c7c19fa3561cdab117bc01c88f2ef4625
7
- data.tar.gz: f3bb7eedbe467dd10895ae229e8578d3cb0f7108c352e555f072e633cac0bb3ab2e1ddbe19de03476c6a047655032186fe2e310696f311f3e2463f324925843d
6
+ metadata.gz: 5f77f05e827b8a7ccf6670bd10f3ff595199b19be8398035377c3efad2ded7f251b188a5ba0a0d443abc7d78debcfab986a17b001afc2b653a9ee7ee9d1a51ba
7
+ data.tar.gz: 602e936f4681ccb800f950185d8fb970299531a5616346a72b7f2a49c80e21aedf8168aa1aff1f87e36e2eafee9c45a59e54919a8e2985178236e853d63d858e
data/CHANGELOG.md CHANGED
@@ -4,6 +4,27 @@ Change Log
4
4
  This project follows [semver 2.0.0][1] and the recommendations
5
5
  of [keepachangelog.com][2].
6
6
 
7
+ 0.7.0
8
+ -----
9
+
10
+ ### Changed
11
+ - `assert` on a question-mark method converts to `eq(true)` instead
12
+ of `be_truthy`. Likewise, `refute` converts to `eq(false)`. This is not
13
+ guaranteed to be the same as minitest's fuzzy `assert`, but the convention of
14
+ question-mark methods returning real booleans is strong.
15
+
16
+ ### Added
17
+ - Converts assert_not_nil
18
+ - CLI
19
+ - Added `--mocha` flag. If present, converts mocha to
20
+ rspec-mocks. (Experimental)
21
+ - Creates `target_file` directory if it does not exist
22
+ - Experimental
23
+ - mocha: with
24
+
25
+ ### Fixed
26
+ - `__FILE__` keyword in input
27
+
7
28
  0.6.2
8
29
  -----
9
30
 
data/README.md CHANGED
@@ -7,6 +7,7 @@ Converts [minitest][8] files to [rspec][9].
7
7
  - Selected assertions from [Test::Unit][26], [minitest][8],
8
8
  and [ActiveSupport][27] are converted to [rspec-expectations][25].
9
9
  - Selected methods from [mocha][28] are converted to [rspec-mocks][24].
10
+ (Experimental)
10
11
 
11
12
  Example
12
13
  -------
@@ -28,26 +29,22 @@ end
28
29
  Output:
29
30
 
30
31
  ```ruby
31
- require("spec_helper")
32
- RSpec.describe(Array) do
33
- it("changes length") do
32
+ require "spec_helper"
33
+ RSpec.describe Array do
34
+ it "changes length" do
34
35
  ary = []
35
- expect { ary.push(:x) }.to(change { ary.length })
36
+ expect { ary.push(:x) }.to change { ary.length }
36
37
  end
37
38
  end
38
39
  ```
39
40
 
40
- The code style is whatever [ruby2ruby][6] feels like printing,
41
- and is not configurable. Comments are discarded.
42
-
43
41
  Usage
44
42
  -----
45
43
 
46
44
  ### CLI
47
45
 
48
46
  ```bash
49
- gem install mt2rspec
50
- bundle exec mt2rspec [--rails] source_file [target_file]
47
+ bundle exec mt2rspec [--rails] [--mocha] source_file [target_file]
51
48
  bundle exec mt2rspec --help
52
49
  ```
53
50
 
@@ -55,16 +52,28 @@ bundle exec mt2rspec --help
55
52
 
56
53
  ```ruby
57
54
  require 'minitest_to_rspec'
58
- MinitestToRspec::Converter.new.convert("assert('banana')")
55
+ converter = MinitestToRspec::Converter.new(rails: false, mocha: false)
56
+ converter.convert("assert('banana')")
59
57
  #=> "expect(\"banana\").to(be_truthy)"
60
58
  ```
61
59
 
60
+ Output
61
+ ------
62
+
63
+ The primary goal is correctness, but [code style][34] is also important. To
64
+ allow us to configure our output, we use [sexp2ruby][33] instead of
65
+ [ruby2ruby][6]. As [sexp2ruby][33] adds more configuration options, we'll make
66
+ use of them.
67
+
68
+ Comments are discarded by [ruby_parser][14], so we have no way of
69
+ preserving them.
70
+
62
71
  Supported Assertions
63
72
  --------------------
64
73
 
65
- Selected assertions from minitest, Test::Unit, and ActiveSupport.
66
- See [doc/supported_assertions.md][5] for rationale. Contributions
67
- are welcome.
74
+ Selected assertions from [minitest][8], [Test::Unit][26], and
75
+ [ActiveSupport][27]. See [doc/supported_assertions.md][5] for rationale.
76
+ Contributions are welcome.
68
77
 
69
78
  Assertion | Arity | Source
70
79
  --------------------------- | ----- | ------
@@ -74,6 +83,7 @@ assert_difference | 1,2 |
74
83
  [assert_not_equal][22] | 2,3 | Test::Unit
75
84
  assert_match | |
76
85
  assert_nil | |
86
+ assert_not_nil | |
77
87
  [assert_no_difference][12] | | ActiveSupport
78
88
  [assert_nothing_raised][10] | | Test::Unit
79
89
  [assert_raise][11] | 0..2 | Test::Unit
@@ -81,8 +91,6 @@ assert_nil | |
81
91
  refute | |
82
92
  refute_equal | |
83
93
 
84
- To do: assert_not_nil
85
-
86
94
  Supported Mocha
87
95
  ---------------
88
96
 
@@ -136,3 +144,5 @@ This project would not be possible without [ruby_parser][14],
136
144
  [30]: http://www.rubydoc.info/github/floehopper/mocha/Mocha/Expectation
137
145
  [31]: http://www.rubydoc.info/github/floehopper/mocha/Mocha/Expectation#once-instance_method
138
146
  [32]: http://www.rubydoc.info/github/floehopper/mocha/Mocha/Expectation#twice-instance_method
147
+ [33]: https://github.com/jaredbeck/sexp2ruby
148
+ [34]: https://github.com/bbatsov/ruby-style-guide
@@ -1,3 +1,4 @@
1
+ require "fileutils"
1
2
  require "minitest_to_rspec"
2
3
  require "trollop"
3
4
 
@@ -7,34 +8,36 @@ module MinitestToRspec
7
8
  E_FILE_NOT_FOUND = 2.freeze
8
9
  E_FILE_ALREADY_EXISTS = 3.freeze
9
10
  E_CONVERT_FAIL = 4.freeze
11
+ E_CANNOT_CREATE_TARGET_DIR = 5.freeze
10
12
 
11
13
  BANNER = <<EOS.freeze
12
- Usage: mt2rspec --rails source_file [target_file]
14
+ Usage: mt2rspec [--rails] [--mocha] source_file [target_file]
13
15
 
14
- Reads source_file, writes target_file. If target_file is omitted,
15
- its location will be inferred. For example, test/fruit/banana_test.rb
16
- implies spec/fruit/banana_spec.rb.
16
+ Reads source_file, writes target_file. If target_file is omitted,
17
+ its location will be inferred. For example, test/fruit/banana_test.rb
18
+ implies spec/fruit/banana_spec.rb. If the target directory doesn't
19
+ exist, it will be created.
17
20
 
18
21
  Options:
19
22
  EOS
20
-
23
+ OPT_MOCHA = "Convert mocha to rspec-mocks. (Experimental)"
21
24
  OPT_RAILS = <<EOS.gsub(/\n/, " ").freeze
22
25
  Requires rails_helper instead of spec_helper.
23
26
  Passes :type metadatum to RSpec.describe.
24
27
  EOS
25
28
 
26
- attr_reader :rails, :source, :target
29
+ attr_reader :source, :target
27
30
 
28
31
  def initialize(args)
29
- assert_trollop_version
30
-
31
32
  opts = Trollop.options(args) do
32
33
  version MinitestToRspec::VERSION
33
34
  banner BANNER
34
35
  opt :rails, OPT_RAILS, short: :none
36
+ opt :mocha, OPT_MOCHA, short: :none
35
37
  end
36
38
 
37
39
  @rails = opts[:rails]
40
+ @mocha = opts[:mocha]
38
41
  case args.length
39
42
  when 2
40
43
  @source, @target = args
@@ -50,7 +53,8 @@ EOS
50
53
  def run
51
54
  assert_file_exists(source)
52
55
  assert_file_does_not_exist(target)
53
- write_target(converter.convert(read_source))
56
+ ensure_target_directory(target)
57
+ write_target(converter.convert(read_source, source))
54
58
  rescue Error => e
55
59
  $stderr.puts "Failed to convert: #{e}"
56
60
  exit E_CONVERT_FAIL
@@ -72,19 +76,20 @@ EOS
72
76
  end
73
77
  end
74
78
 
75
- # Temporary assertion. It would be nice if gemspec supported git.
76
- def assert_trollop_version
77
- unless Trollop.method(:die).arity == -2
78
- warn "Please use trollop version f7009b45 or greater."
79
- warn "This manual version constraint will be removed when"
80
- warn "https://github.com/ManageIQ/trollop/pull/63"
81
- warn "is included in an official trollop release."
82
- exit(-1)
83
- end
79
+ def converter
80
+ Converter.new(mocha: @mocha, rails: @rails)
84
81
  end
85
82
 
86
- def converter
87
- Converter.new(rails: rails)
83
+ def ensure_target_directory(target)
84
+ dir = File.dirname(target)
85
+ return if Dir.exist?(dir)
86
+ begin
87
+ FileUtils.mkdir_p(dir)
88
+ rescue SystemCallError => e
89
+ $stderr.puts "Cannot create target dir: #{dir}"
90
+ $stderr.puts e.message
91
+ exit E_CANNOT_CREATE_TARGET_DIR
92
+ end
88
93
  end
89
94
 
90
95
  def infer_target_from(source)
@@ -19,21 +19,24 @@ module MinitestToRspec
19
19
  to_not
20
20
  ]
21
21
 
22
- def initialize(options)
23
- @options = options
24
- @processor = Processor.new(@options[:rails])
22
+ def initialize(rails: false, mocha: false)
23
+ @processor = Processor.new(rails, mocha)
25
24
  end
26
25
 
27
- def convert(input)
28
- render process parse input
26
+ # - `input` - Contents of a ruby file.
27
+ # - `file_path` - Optional. Value will replace any `__FILE__`
28
+ # keywords in the input.
29
+ def convert(input, file_path = nil)
30
+ render process parse(input, file_path)
29
31
  end
30
32
 
31
33
  private
32
34
 
33
35
  # Parses input string and returns Abstract Syntax Tree (AST)
34
36
  # as an S-expression.
35
- def parse(input)
36
- RubyParser.new.parse(input)
37
+ def parse(input, file_path)
38
+ file_path ||= "No file path provided to #{self.class}#convert"
39
+ RubyParser.new.parse(input, file_path)
37
40
  end
38
41
 
39
42
  # Processes an AST (S-expressions) representing a minitest
@@ -1,7 +1,7 @@
1
1
  require_relative "../sexp_assertions"
2
2
 
3
3
  module MinitestToRspec
4
- module Exp
4
+ module Model
5
5
 
6
6
  # Classes inheriting `Base` are simple data objects
7
7
  # representing the S-expressions they are named after.
@@ -1,7 +1,7 @@
1
1
  require_relative "base"
2
2
 
3
3
  module MinitestToRspec
4
- module Exp
4
+ module Model
5
5
 
6
6
  # Data object. Represents a `:call` s-expression.
7
7
  class Call < Base
@@ -35,7 +35,7 @@ module MinitestToRspec
35
35
  end
36
36
 
37
37
  def method_name?(exp, name)
38
- exp.sexp_type == :call && new(exp).method_name == name
38
+ exp.sexp_type == :call && new(exp).method_name.to_s == name.to_s
39
39
  end
40
40
  end
41
41
 
@@ -70,6 +70,13 @@ module MinitestToRspec
70
70
  method_name == :assert_raises && raise_error_args?
71
71
  end
72
72
 
73
+ def calls_in_receiver_chain
74
+ receiver_chain.
75
+ compact.
76
+ select { |r| sexp_type?(:call, r) }.
77
+ map { |r| Call.new(r) }
78
+ end
79
+
73
80
  def method_name
74
81
  @exp[2]
75
82
  end
@@ -95,14 +102,14 @@ module MinitestToRspec
95
102
  end
96
103
 
97
104
  # While `#receiver` returns a `Sexp`, `#receiver_call`
98
- # returns a `Exp::Call`.
105
+ # returns a `Model::Call`.
99
106
  def receiver_call
100
107
  if sexp_type?(:call, receiver)
101
- rvc = Exp::Call.new(receiver)
108
+ rvc = Model::Call.new(receiver)
102
109
 
103
110
  # TODO: Seems like a factory pattern
104
111
  if rvc.method_name == :returns
105
- Exp::Calls::Returns.new(receiver)
112
+ Model::Calls::Returns.new(receiver)
106
113
  else
107
114
  rvc
108
115
  end
@@ -111,12 +118,52 @@ module MinitestToRspec
111
118
  end
112
119
  end
113
120
 
121
+ # Consider the following chain of method calls:
122
+ #
123
+ # @a.b.c
124
+ #
125
+ # whose S-expression is
126
+ #
127
+ # s(:call, s(:call, s(:call, nil, :a), :b), :c)
128
+ #
129
+ # the "receiver chain" is
130
+ #
131
+ # [
132
+ # s(:call, s(:call, nil, :a), :b),
133
+ # s(:call, nil, :a),
134
+ # nil
135
+ # ]
136
+ #
137
+ # The order of the returned array matches the order in which
138
+ # messages are received, i.e. the order of execution.
139
+ #
140
+ # Note that the final receiver `nil` is included. This `nil`
141
+ # represents the implicit receiver, e.g. `self` or `main`.
142
+ #
143
+ def receiver_chain
144
+ receivers = []
145
+ ptr = @exp
146
+ while sexp_type?(:call, ptr)
147
+ receivers << ptr[1]
148
+ ptr = ptr[1]
149
+ end
150
+ receivers
151
+ end
152
+
153
+ def receiver_chain_include?(method_name)
154
+ receiver_chain.compact.any? { |r| Call.method_name?(r, method_name) }
155
+ end
156
+
114
157
  def require_test_helper?
115
158
  method_name == :require &&
116
159
  one_string_argument? &&
117
160
  arguments[0][1] == "test_helper"
118
161
  end
119
162
 
163
+ def question_mark_method?
164
+ method_name.to_s.end_with?("?")
165
+ end
166
+
120
167
  private
121
168
 
122
169
  def string?(exp)
@@ -2,7 +2,7 @@ require_relative "../call"
2
2
  require_relative "../../errors"
3
3
 
4
4
  module MinitestToRspec
5
- module Exp
5
+ module Model
6
6
  module Calls
7
7
  class Once < Call
8
8
  end
@@ -2,32 +2,29 @@ require_relative "../call"
2
2
  require_relative "../../errors"
3
3
 
4
4
  module MinitestToRspec
5
- module Exp
5
+ module Model
6
6
  module Calls
7
7
 
8
8
  # Represents a call to `returns`, the stubbing method
9
9
  # from `mocha`.
10
10
  class Returns < Call
11
- KNOWN_RECEIVERS = %i[stubs expects]
12
- RSPEC_MOCK_METHODS = { expects: :expect, stubs: :allow }
11
+ KNOWN_RECEIVERS = %i[stubs expects with]
13
12
 
14
13
  def initialize(exp)
15
14
  @exp = exp
16
15
  raise UnknownVariant unless known_variant?
17
16
  end
18
17
 
18
+ def stub?
19
+ receiver_chain_include?(:stubs)
20
+ end
21
+
19
22
  def any_instance?
20
- rcr = receiver_call.receiver
21
- if !rcr.nil? && sexp_type?(:call, rcr)
22
- Call.new(rcr).method_name == :any_instance
23
- else
24
- false
25
- end
23
+ receiver_chain_include?(:any_instance)
26
24
  end
27
25
 
28
- # The message recipient
29
- def msg_recipient
30
- receiver_call.receiver
26
+ def expectation?
27
+ receiver_chain_include?(:expects)
31
28
  end
32
29
 
33
30
  def known_variant?
@@ -40,13 +37,25 @@ module MinitestToRspec
40
37
  end
41
38
 
42
39
  def message
43
- receiver_call.arguments[0]
40
+ calls_in_receiver_chain.
41
+ find { |c| [:stubs, :expects].include? c.method_name }.
42
+ arguments[0]
44
43
  end
45
44
 
46
45
  # To avoid a `ProcessingError` please check `known_variant?`
47
46
  # before calling `rspec_mocks_method`.
48
47
  def rspec_mocks_method
49
- RSPEC_MOCK_METHODS[receiver_call.method_name]
48
+ s = stub?
49
+ e = expectation?
50
+ if s && e
51
+ raise ProcessingError, "Method chain contains stubs and expects"
52
+ elsif s
53
+ :allow
54
+ elsif e
55
+ :expect
56
+ else
57
+ raise ProcessingError, "Found returns without stubs or expects"
58
+ end
50
59
  end
51
60
 
52
61
  # Returns `Sexp` representing the object that will receive
@@ -55,16 +64,22 @@ module MinitestToRspec
55
64
  # banana.stubs(:delicious?).returns(true)
56
65
  # Kiwi.any_instance.stubs(:delicious?).returns(false)
57
66
  #
58
- # The `rspec_msg_recipient` is `banana` and `Kiwi`, respectively.
67
+ # On the first line, the `rspec_msg_recipient` is `banana`. On the
68
+ # second, `Kiwi`.
59
69
  #
60
70
  def rspec_msg_recipient
61
- any_instance? ? Call.new(msg_recipient).receiver : msg_recipient
71
+ receiver_chain.compact.last
62
72
  end
63
73
 
64
74
  # The return values
65
75
  def values
66
76
  arguments
67
77
  end
78
+
79
+ def with
80
+ w = calls_in_receiver_chain.find { |c| c.method_name == :with }
81
+ w.nil? ? [] : w.arguments
82
+ end
68
83
  end
69
84
  end
70
85
  end
@@ -2,7 +2,7 @@ require_relative "../call"
2
2
  require_relative "../../errors"
3
3
 
4
4
  module MinitestToRspec
5
- module Exp
5
+ module Model
6
6
  module Calls
7
7
  class Twice < Call
8
8
  end
@@ -1,5 +1,5 @@
1
1
  module MinitestToRspec
2
- module Exp
2
+ module Model
3
3
 
4
4
  # Data object. Represents a `:hash` S-expression.
5
5
  class HashExp < Base
@@ -1,7 +1,7 @@
1
1
  require_relative "base"
2
2
 
3
3
  module MinitestToRspec
4
- module Exp
4
+ module Model
5
5
 
6
6
  # Data object. Represents an `:iter` s-expression.
7
7
  class Iter < Base
@@ -15,23 +15,23 @@ module MinitestToRspec
15
15
  end
16
16
 
17
17
  def assert_difference?
18
- !empty? && Exp::Call.assert_difference?(@exp[1])
18
+ !empty? && Model::Call.assert_difference?(@exp[1])
19
19
  end
20
20
 
21
21
  def assert_no_difference?
22
- !empty? && Exp::Call.assert_no_difference?(@exp[1])
22
+ !empty? && Model::Call.assert_no_difference?(@exp[1])
23
23
  end
24
24
 
25
25
  def assert_nothing_raised?
26
- !empty? && Exp::Call.assert_nothing_raised?(@exp[1])
26
+ !empty? && Model::Call.assert_nothing_raised?(@exp[1])
27
27
  end
28
28
 
29
29
  def assert_raise?
30
- !empty? && Exp::Call.assert_raise?(@exp[1])
30
+ !empty? && Model::Call.assert_raise?(@exp[1])
31
31
  end
32
32
 
33
33
  def assert_raises?
34
- !empty? && Exp::Call.assert_raises?(@exp[1])
34
+ !empty? && Model::Call.assert_raises?(@exp[1])
35
35
  end
36
36
 
37
37
  def block
@@ -48,7 +48,7 @@ module MinitestToRspec
48
48
  end
49
49
 
50
50
  def call_obj
51
- Exp::Call.new(call)
51
+ Model::Call.new(call)
52
52
  end
53
53
 
54
54
  # Enumerates children, skipping the base `call` and
@@ -63,11 +63,11 @@ module MinitestToRspec
63
63
  end
64
64
 
65
65
  def setup?
66
- !empty? && Exp::Call.method_name?(@exp[1], :setup)
66
+ !empty? && Model::Call.method_name?(@exp[1], :setup)
67
67
  end
68
68
 
69
69
  def teardown?
70
- !empty? && Exp::Call.method_name?(@exp[1], :teardown)
70
+ !empty? && Model::Call.method_name?(@exp[1], :teardown)
71
71
  end
72
72
 
73
73
  def sexp
@@ -1,7 +1,7 @@
1
1
  require_relative "base"
2
2
 
3
3
  module MinitestToRspec
4
- module Exp
4
+ module Model
5
5
 
6
6
  # Data object. Represents a `:class` S-expression.
7
7
  class Klass < Base
@@ -6,22 +6,23 @@ require_relative "subprocessors/iter"
6
6
 
7
7
  module MinitestToRspec
8
8
  class Processor < SexpProcessor
9
- def initialize(rails)
9
+ def initialize(rails, mocha)
10
10
  super()
11
11
  self.strict = false
12
+ @mocha = mocha
12
13
  @rails = rails
13
14
  end
14
15
 
15
16
  def process_call(exp)
16
- Subprocessors::Call.new(exp, @rails).process
17
+ Subprocessors::Call.new(exp, @rails, @mocha).process
17
18
  end
18
19
 
19
20
  def process_class(exp)
20
- Subprocessors::Klass.new(exp, @rails).process
21
+ Subprocessors::Klass.new(exp, @rails, @mocha).process
21
22
  end
22
23
 
23
24
  def process_iter(exp)
24
- Subprocessors::Iter.new(exp).process
25
+ Subprocessors::Iter.new(exp, @rails, @mocha).process
25
26
  end
26
27
  end
27
28
  end
@@ -5,6 +5,11 @@ module MinitestToRspec
5
5
  class Base
6
6
  include SexpAssertions
7
7
 
8
+ def initialize(rails, mocha)
9
+ @rails = rails
10
+ @mocha = mocha
11
+ end
12
+
8
13
  # Returns a s-expression representing an rspec-mocks stub.
9
14
  def allow_to(msg_recipient, matcher, any_instance = false)
10
15
  allow_method = any_instance ? :allow_any_instance_of : :allow
@@ -64,7 +69,7 @@ module MinitestToRspec
64
69
  #
65
70
  # TODO: `full_process` may not be the best name.
66
71
  def full_process(obj)
67
- obj.is_a?(Sexp) ? Processor.new(false).process(obj) : obj
72
+ obj.is_a?(Sexp) ? Processor.new(@rails, @mocha).process(obj) : obj
68
73
  end
69
74
 
70
75
  def matcher(name, *args)
@@ -1,34 +1,57 @@
1
- require_relative "../exp/call"
2
- require_relative "../exp/calls/returns"
3
- require_relative "../exp/hash_exp"
1
+ require_relative "../model/call"
2
+ require_relative "../model/calls/returns"
3
+ require_relative "../model/hash_exp"
4
4
  require_relative "base"
5
5
 
6
6
  module MinitestToRspec
7
7
  module Subprocessors
8
8
  class Call < Base
9
- def initialize(sexp, rails)
10
- @exp = Exp::Call.new(sexp)
9
+
10
+ # Mocha methods will only be processed if `--mocha` flag was given,
11
+ # i.e. `mocha` argument in constructor is true.
12
+ MOCHA_METHODS = %i[
13
+ expects
14
+ once
15
+ returns
16
+ stub
17
+ stubs
18
+ stub_everything
19
+ twice
20
+ ]
21
+
22
+ def initialize(sexp, rails, mocha)
23
+ super(rails, mocha)
24
+ @exp = Model::Call.new(sexp)
11
25
  sexp.clear
12
- @rails = rails
13
26
  end
14
27
 
15
- # Given a `Exp::Call`, returns a `Sexp`
28
+ # Given a `Model::Call`, returns a `Sexp`
16
29
  def process
17
- if respond_to?(name_of_processing_method, true)
30
+ if process?
18
31
  send(name_of_processing_method)
19
32
  else
20
33
  @exp.original
21
34
  end
22
35
  end
23
36
 
37
+ def process?
38
+ respond_to?(name_of_processing_method, true) &&
39
+ (@mocha || !MOCHA_METHODS.include?(@exp.method_name))
40
+ end
41
+
24
42
  private
25
43
 
26
44
  # - msg_rcp. Message recipient. The object to be stubbed.
27
45
  # - msg. Message. The name of the stubbed method.
28
46
  # - ret_vals. Return values.
29
47
  # - any_ins. Any instance? True if this is an `any_instance` stub.
30
- def allow_receive_and_return(msg_rcp, msg, ret_vals, any_ins = false)
31
- allow_to(msg_rcp, receive_and_return(msg, ret_vals), any_ins)
48
+ # - with. Allowed arguments.
49
+ def allow_receive_and_return(msg_rcp, msg, ret_vals, any_ins, with)
50
+ allow_to(
51
+ msg_rcp,
52
+ receive_and_return(msg, ret_vals, with),
53
+ any_ins
54
+ )
32
55
  end
33
56
 
34
57
  # Given `exp`, an S-expression representing an rspec-mocks statement
@@ -52,6 +75,10 @@ module MinitestToRspec
52
75
  matcher(:be_truthy)
53
76
  end
54
77
 
78
+ def call_to_question_mark?(exp)
79
+ sexp_type?(:call, exp) && Model::Call.new(exp).question_mark_method?
80
+ end
81
+
55
82
  def eq(exp)
56
83
  matcher(:eq, exp)
57
84
  end
@@ -60,17 +87,23 @@ module MinitestToRspec
60
87
  # - msg. Message. The name of the stubbed method.
61
88
  # - ret_vals. Return values.
62
89
  # - any_ins. Any instance? True if this is an `any_instance` stub.
63
- def expect_receive_and_return(msg_rcp, msg, ret_vals, any_ins = false)
64
- expect_to(receive_and_return(msg, ret_vals), msg_rcp, true, any_ins)
90
+ # - with. Allowed arguments.
91
+ def expect_receive_and_return(msg_rcp, msg, ret_vals, any_ins, with)
92
+ expect_to(
93
+ receive_and_return(msg, ret_vals, with),
94
+ msg_rcp,
95
+ true,
96
+ any_ins
97
+ )
65
98
  end
66
99
 
67
100
  # Given a `Sexp` representing a `Hash` of message expectations,
68
101
  # return an array of `Sexp`, each representing an expectation
69
102
  # in rspec-mocks syntax.
70
103
  def hash_to_expectations(sexp, receiver)
71
- Exp::HashExp.new(sexp).to_h.map { |msg, ret_val|
104
+ Model::HashExp.new(sexp).to_h.map { |msg, ret_val|
72
105
  expect_receive_and_return(
73
- receiver.deep_clone, msg, wrap_sexp(ret_val)
106
+ receiver.deep_clone, msg, wrap_sexp(ret_val), false, []
74
107
  )
75
108
  }
76
109
  end
@@ -80,7 +113,7 @@ module MinitestToRspec
80
113
  end
81
114
 
82
115
  def method_assert
83
- expect_to(be_truthy, @exp.arguments[0], true)
116
+ refsert eq(s(:true)), be_truthy
84
117
  end
85
118
 
86
119
  def method_assert_equal
@@ -99,6 +132,10 @@ module MinitestToRspec
99
132
  expect_to(be_nil, @exp.arguments[0], true)
100
133
  end
101
134
 
135
+ def method_assert_not_nil
136
+ expect_to_not(be_nil, @exp.arguments[0], true)
137
+ end
138
+
102
139
  def method_assert_not_equal
103
140
  expected = @exp.arguments[0]
104
141
  calculated = @exp.arguments[1]
@@ -118,7 +155,7 @@ module MinitestToRspec
118
155
  end
119
156
 
120
157
  def method_refute
121
- expect_to(be_falsey, @exp.arguments[0], true)
158
+ refsert eq(s(:false)), be_falsey
122
159
  end
123
160
 
124
161
  def method_refute_equal
@@ -128,7 +165,7 @@ module MinitestToRspec
128
165
  end
129
166
 
130
167
  def method_returns
131
- mocha_returns(Exp::Calls::Returns.new(@exp.original))
168
+ mocha_returns(Model::Calls::Returns.new(@exp.original))
132
169
  rescue UnknownVariant
133
170
  @exp.original
134
171
  end
@@ -176,7 +213,7 @@ module MinitestToRspec
176
213
  end
177
214
 
178
215
  def mocha_expects(exp)
179
- raise ArgumentError unless exp.is_a?(Exp::Call)
216
+ raise ArgumentError unless exp.is_a?(Model::Call)
180
217
  arg = exp.arguments.first
181
218
  if sexp_type?(:hash, arg)
182
219
  mocha_expects_hash(exp, arg)
@@ -198,7 +235,7 @@ module MinitestToRspec
198
235
  end
199
236
 
200
237
  def mocha_expectation_count(exp, ordinal)
201
- raise ArgumentError unless exp.is_a?(Exp::Call)
238
+ raise ArgumentError unless exp.is_a?(Model::Call)
202
239
  raise ArgumentError unless %i[once twice].include?(ordinal)
203
240
  rvc = exp.receiver_call
204
241
  receiver_processing_method = "mocha_#{rvc.method_name}".to_sym
@@ -214,21 +251,22 @@ module MinitestToRspec
214
251
  mocha_expectation_count(exp, :once)
215
252
  end
216
253
 
217
- # Given `r`, a `Exp::Calls::Returns`, return a `Sexp` representing
254
+ # Given `r`, a `Model::Calls::Returns`, return a `Sexp` representing
218
255
  # the equivalent stub or message expectation in RSpec.
219
256
  def mocha_returns(r)
220
- raise ArgumentError unless r.is_a?(Exp::Calls::Returns)
257
+ raise ArgumentError unless r.is_a?(Model::Calls::Returns)
221
258
  subprocessor_method = "#{r.rspec_mocks_method}_receive_and_return"
222
259
  send(subprocessor_method,
223
260
  r.rspec_msg_recipient,
224
261
  r.message,
225
262
  r.values,
226
- r.any_instance?
263
+ r.any_instance?,
264
+ r.with
227
265
  )
228
266
  end
229
267
 
230
268
  def mocha_stub(exp)
231
- raise ArgumentError unless exp.is_a?(Exp::Call)
269
+ raise ArgumentError unless exp.is_a?(Model::Call)
232
270
  if exp.receiver.nil?
233
271
  s(:call, nil, :double, *exp.arguments)
234
272
  else
@@ -275,16 +313,29 @@ module MinitestToRspec
275
313
  )
276
314
  end
277
315
 
278
- def receive(message)
279
- s(:call, nil, :receive, message)
316
+ def receive(message, with = [])
317
+ r = s(:call, nil, :receive, message)
318
+ if with.empty?
319
+ r
320
+ else
321
+ s(:call, r, :with, *with)
322
+ end
280
323
  end
281
324
 
282
325
  def receive_and_call_original(message)
283
326
  s(:call, s(:call, nil, :receive, message), :and_call_original)
284
327
  end
285
328
 
286
- def receive_and_return(message, return_values)
287
- s(:call, receive(message), :and_return, *return_values)
329
+ def receive_and_return(message, return_values, with = [])
330
+ s(:call, receive(message, with), :and_return, *return_values)
331
+ end
332
+
333
+ # `refsert` - Code shared by refute and assert. I could also have gone
334
+ # with `assfute`. Wooo .. time for bed.
335
+ def refsert(exact, fuzzy)
336
+ actual = @exp.arguments[0]
337
+ matcher = call_to_question_mark?(actual) ? exact : fuzzy
338
+ expect_to(matcher, actual, true)
288
339
  end
289
340
 
290
341
  def require_spec_helper
@@ -1,11 +1,12 @@
1
1
  require_relative "base"
2
- require_relative "../exp/iter"
2
+ require_relative "../model/iter"
3
3
 
4
4
  module MinitestToRspec
5
5
  module Subprocessors
6
6
  class Iter < Base
7
- def initialize(sexp)
8
- @exp = Exp::Iter.new(sexp)
7
+ def initialize(sexp, rails, mocha)
8
+ super(rails, mocha)
9
+ @exp = Model::Iter.new(sexp)
9
10
  sexp.clear
10
11
  end
11
12
 
@@ -84,7 +85,7 @@ module MinitestToRspec
84
85
  RubyParser.new.parse(str)
85
86
  end
86
87
 
87
- # Given a `Exp::Iter`, returns a `Sexp`
88
+ # Given a `Model::Iter`, returns a `Sexp`
88
89
  def process_exp(exp)
89
90
  if processable?(exp)
90
91
  send_to_processing_method(exp)
@@ -1,5 +1,5 @@
1
1
  require_relative "../errors"
2
- require_relative "../exp/klass"
2
+ require_relative "../model/klass"
3
3
  require_relative "base"
4
4
 
5
5
  module MinitestToRspec
@@ -9,10 +9,10 @@ module MinitestToRspec
9
9
  # Takes `sexp`, a `:class` s-expression, and `rails`, a
10
10
  # boolean indicating that `rspec-rails` conventions (like
11
11
  # `:type` metadata) should be used.
12
- def initialize(sexp, rails)
13
- @exp = Exp::Klass.new(sexp)
12
+ def initialize(sexp, rails, mocha)
13
+ super(rails, mocha)
14
+ @exp = Model::Klass.new(sexp)
14
15
  sexp.clear
15
- @rails = rails
16
16
  end
17
17
 
18
18
  def process
@@ -1,3 +1,3 @@
1
1
  module MinitestToRspec
2
- VERSION = "0.6.2".freeze
2
+ VERSION = "0.7.0".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minitest_to_rspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jared Beck
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-18 00:00:00.000000000 Z
11
+ date: 2015-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby_parser
@@ -180,14 +180,14 @@ files:
180
180
  - lib/minitest_to_rspec/cli.rb
181
181
  - lib/minitest_to_rspec/converter.rb
182
182
  - lib/minitest_to_rspec/errors.rb
183
- - lib/minitest_to_rspec/exp/base.rb
184
- - lib/minitest_to_rspec/exp/call.rb
185
- - lib/minitest_to_rspec/exp/calls/once.rb
186
- - lib/minitest_to_rspec/exp/calls/returns.rb
187
- - lib/minitest_to_rspec/exp/calls/twice.rb
188
- - lib/minitest_to_rspec/exp/hash_exp.rb
189
- - lib/minitest_to_rspec/exp/iter.rb
190
- - lib/minitest_to_rspec/exp/klass.rb
183
+ - lib/minitest_to_rspec/model/base.rb
184
+ - lib/minitest_to_rspec/model/call.rb
185
+ - lib/minitest_to_rspec/model/calls/once.rb
186
+ - lib/minitest_to_rspec/model/calls/returns.rb
187
+ - lib/minitest_to_rspec/model/calls/twice.rb
188
+ - lib/minitest_to_rspec/model/hash_exp.rb
189
+ - lib/minitest_to_rspec/model/iter.rb
190
+ - lib/minitest_to_rspec/model/klass.rb
191
191
  - lib/minitest_to_rspec/processor.rb
192
192
  - lib/minitest_to_rspec/sexp_assertions.rb
193
193
  - lib/minitest_to_rspec/subprocessors/base.rb