minitest_to_rspec 0.6.2 → 0.7.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: 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