transpec 1.0.0 → 1.1.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: e89b721e834bdcbbc84616c93aeb74dcdcd69d29
4
- data.tar.gz: 5678c00ce5a1bcc36e55cdcc41233fc0bd24d075
3
+ metadata.gz: 977f1d1608ec0a3279e492d25b71f6d89406d6c8
4
+ data.tar.gz: 6e66591a69cf5ac38b5d0591ce999f70461d462a
5
5
  SHA512:
6
- metadata.gz: b71de56cdff03743ced725d67478c80be77a2772421dd73c1bdc8d8d4a67fc17f6b1907f819b421feb40de91960afa64cf71ab5a9e5dbe3193924fd49ba8289c
7
- data.tar.gz: 39ca211fe213c2d6858ac2fbd669953d363de542443ceb85c4c0f7d8dc578cde12be976e94eb0a578d718e29cfeb65e29bba1516060f1f1c57279c2563e3f95f
6
+ metadata.gz: 2255fba8e8680c8dd0bcaf41375f4f189092c7eec52c50776b6cbb4eac0b714d726db8609385729dcdb3831cd1e7f973da84a6f488b2630a57e4fe2cd09dd5b3
7
+ data.tar.gz: 6e7c92b6b6305ac0b9afc00c5101f5bff45b582241bedb306dae75d7f449d0f2013abff19d372fcb8c3aa075e7ea263bd575eab816d358bfe9a009650b0f5c73
data/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## Master
4
4
 
5
+ ## v1.1.0
6
+
7
+ * Support conversion of `its` (#9)
8
+
9
+ ## v1.0.0
10
+
5
11
  * Now Transpec does dynamic code analysis!
6
12
  * Support conversion of `have(n).items` matcher ([#5](https://github.com/yujinakayama/transpec/issues/5))
7
13
  * Add `-s/--skip-dynamic-analysis` option that allows to skip dynamic analysis and convert with only static analysis
data/README.md CHANGED
@@ -133,7 +133,7 @@ Converting spec/support/shared_context.rb
133
133
  Converting spec/transpec/ast/node_spec.rb
134
134
  ```
135
135
 
136
- This will run your specs, convert them, and overwrite all spec files in the `spec` directory.
136
+ This will run the specs, convert them, and overwrite all spec files in the `spec` directory.
137
137
 
138
138
  After the conversion, run `rspec` again and check whether all pass:
139
139
 
@@ -162,9 +162,8 @@ $ git status --short
162
162
  $ transpec
163
163
  The current Git repository is not clean. Aborting.
164
164
  $ transpec --force
165
- Processing spec/spec_helper.rb
166
- Processing spec/spec_spec.rb
167
- Processing spec/support/file_helper.rb
165
+ Copying project for dynamic analysis...
166
+ Running dynamic analysis with command "bundle exec rspec"...
168
167
  ```
169
168
 
170
169
  ### `-s/--skip-dynamic-analysis`
@@ -210,8 +209,11 @@ Type | Target Syntax | Converted Syntax
210
209
  `should_receive` | `obj.should_receive` | `expect(obj).to receive`
211
210
  `stub` | `obj.stub` | `allow(obj).to receive`
212
211
  `have_items` | `expect(obj).to have(x).items` | `expect(obj.size).to eq(x)`
212
+ `its` | `its(:attr) { }` | `describe { subject { } it { } }`
213
213
  `deprecated` | `obj.stub!`, `mock('foo')`, etc. | `obj.stub`, `double('foo')`
214
214
 
215
+ See [Supported Conversions](#supported-conversions) for more details.
216
+
215
217
  ### `-n/--negative-form`
216
218
 
217
219
  Specify negative form of `to` that is used in `expect` syntax.
@@ -292,8 +294,8 @@ end
292
294
 
293
295
  ### Reason
294
296
 
295
- * `should` is defined on `Kernel` module that is included by `Object` class, so you can use `should` almost everywhere.
296
- * `expect` is defined on `RSpec::Matchers` module that is included by `RSpec::Core::ExampleGroup` class, so you can use `expect` only where `self` is an instance of `RSpec::Core::ExampleGroup` (i.e. in `it` blocks, `:each` hook blocks or included methods).
297
+ * `should` is defined on `BasicObject` class, so you can use `should` everywhere.
298
+ * `expect` is defined on `RSpec::Matchers` module that is included by `RSpec::Core::ExampleGroup` class, so you can use `expect` only where `self` is an instance of `RSpec::Core::ExampleGroup` (i.e. in `it` blocks, `:each` hook blocks or included module methods).
297
299
 
298
300
  With the above example, in the context of `1.should == 1`, the `self` is an instance of `MyAwesomeTestRunner`.
299
301
  Transpec tracks contexts and skips conversion if the target syntax cannot be converted in a case like this.
@@ -380,7 +382,7 @@ expect(team.players.size).to eq(3)
380
382
  expect(team.send(:players).size).to eq(3)
381
383
  ```
382
384
 
383
- You have the option to continue using `have(n).items` matcher with [rspec-collection_matchers](https://github.com/rspec/rspec-collection_matchers) that is an external gem extracted from `rspec-expectations`.
385
+ There's the option to continue using `have(n).items` matcher with [rspec-collection_matchers](https://github.com/rspec/rspec-collection_matchers) that is an external gem extracted from `rspec-expectations`.
384
386
  If you choose so, disable this conversion with `--keep have_items`.
385
387
 
386
388
  * Disabled by: `--keep have_items`
@@ -524,6 +526,47 @@ double('something')
524
526
  * Disabled by: `--keep deprecated`
525
527
  * See also: [Deprecate "stub" for doubles · rspec/rspec-mocks](https://github.com/rspec/rspec-mocks/issues/214)
526
528
 
529
+ ### Expectations on attribute of subject with `its`
530
+
531
+ ```ruby
532
+ # Targets
533
+ describe 'example' do
534
+ subject { { foo: 1, bar: 2 } }
535
+ its(:size) { should == 2 }
536
+ its([:foo]) { should == 1 }
537
+ its('keys.first') { should == :foo }
538
+ end
539
+
540
+ # Converted
541
+ describe 'example' do
542
+ subject { { foo: 1, bar: 2 } }
543
+
544
+ describe '#size' do
545
+ subject { super().size }
546
+ it { should == 2 }
547
+ end
548
+
549
+ describe '[:foo]' do
550
+ subject { super()[:foo] }
551
+ it { should == 1 }
552
+ end
553
+
554
+ describe '#keys' do
555
+ subject { super().keys }
556
+ describe '#first' do
557
+ subject { super().first }
558
+ it { should == :foo }
559
+ end
560
+ end
561
+ end
562
+ ```
563
+
564
+ There's the option to continue using `its` with [rspec-its](https://github.com/rspec/rspec-its) that is an external gem extracted from `rspec-core`.
565
+ If you choose so, disable this conversion with `--keep its`.
566
+
567
+ * Disabled by: `--keep its`
568
+ * See also: [Core: its will be moved into an external gem - The Plan for RSpec 3](http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3#core__will_be_moved_into_an_external_gem)
569
+
527
570
  ## Compatibility
528
571
 
529
572
  Tested on MRI 1.9, MRI 2.0 and JRuby in 1.9 mode.
data/README.md.erb CHANGED
@@ -106,7 +106,7 @@ Converting spec/support/shared_context.rb
106
106
  Converting spec/transpec/ast/node_spec.rb
107
107
  ```
108
108
 
109
- This will run your specs, convert them, and overwrite all spec files in the `spec` directory.
109
+ This will run the specs, convert them, and overwrite all spec files in the `spec` directory.
110
110
 
111
111
  After the conversion, run `rspec` again and check whether all pass:
112
112
 
@@ -135,9 +135,8 @@ $ git status --short
135
135
  $ transpec
136
136
  The current Git repository is not clean. Aborting.
137
137
  $ transpec --force
138
- Processing spec/spec_helper.rb
139
- Processing spec/spec_spec.rb
140
- Processing spec/support/file_helper.rb
138
+ Copying project for dynamic analysis...
139
+ Running dynamic analysis with command "bundle exec rspec"...
141
140
  ```
142
141
 
143
142
  ### `-s/--skip-dynamic-analysis`
@@ -185,6 +184,7 @@ conversion_type_table = <<END
185
184
  `should_receive` | `obj.should_receive` | `expect(obj).to receive`
186
185
  `stub` | `obj.stub` | `allow(obj).to receive`
187
186
  `have_items` | `expect(obj).to have(x).items` | `expect(obj.size).to eq(x)`
187
+ `its` | `its(:attr) { }` | `describe { subject { } it { } }`
188
188
  `deprecated` | `obj.stub!`, `mock('foo')`, etc. | `obj.stub`, `double('foo')`
189
189
  END
190
190
 
@@ -203,6 +203,8 @@ end
203
203
  conversion_type_table
204
204
  -%>
205
205
 
206
+ See [Supported Conversions](#supported-conversions) for more details.
207
+
206
208
  ### `-n/--negative-form`
207
209
 
208
210
  Specify negative form of `to` that is used in `expect` syntax.
@@ -288,8 +290,8 @@ end
288
290
 
289
291
  ### Reason
290
292
 
291
- * `should` is defined on `Kernel` module that is included by `Object` class, so you can use `should` almost everywhere.
292
- * `expect` is defined on `RSpec::Matchers` module that is included by `RSpec::Core::ExampleGroup` class, so you can use `expect` only where `self` is an instance of `RSpec::Core::ExampleGroup` (i.e. in `it` blocks, `:each` hook blocks or included methods).
293
+ * `should` is defined on `BasicObject` class, so you can use `should` everywhere.
294
+ * `expect` is defined on `RSpec::Matchers` module that is included by `RSpec::Core::ExampleGroup` class, so you can use `expect` only where `self` is an instance of `RSpec::Core::ExampleGroup` (i.e. in `it` blocks, `:each` hook blocks or included module methods).
293
295
 
294
296
  With the above example, in the context of `1.should == 1`, the `self` is an instance of `MyAwesomeTestRunner`.
295
297
  Transpec tracks contexts and skips conversion if the target syntax cannot be converted in a case like this.
@@ -376,7 +378,7 @@ expect(team.players.size).to eq(3)
376
378
  expect(team.send(:players).size).to eq(3)
377
379
  ```
378
380
 
379
- You have the option to continue using `have(n).items` matcher with [rspec-collection_matchers](https://github.com/rspec/rspec-collection_matchers) that is an external gem extracted from `rspec-expectations`.
381
+ There's the option to continue using `have(n).items` matcher with [rspec-collection_matchers](https://github.com/rspec/rspec-collection_matchers) that is an external gem extracted from `rspec-expectations`.
380
382
  If you choose so, disable this conversion with `--keep have_items`.
381
383
 
382
384
  * Disabled by: `--keep have_items`
@@ -520,6 +522,31 @@ double('something')
520
522
  * Disabled by: `--keep deprecated`
521
523
  * See also: [Deprecate "stub" for doubles · rspec/rspec-mocks](https://github.com/rspec/rspec-mocks/issues/214)
522
524
 
525
+ ### Expectations on attribute of subject with `its`
526
+
527
+ ```ruby
528
+ # Targets
529
+ <%=
530
+ its_target = <<END
531
+ describe 'example' do
532
+ subject { { foo: 1, bar: 2 } }
533
+ its(:size) { should == 2 }
534
+ its([:foo]) { should == 1 }
535
+ its('keys.first') { should == :foo }
536
+ end
537
+ END
538
+ -%>
539
+
540
+ # Converted
541
+ <%= Transpec::Converter.new.convert(its_target) -%>
542
+ ```
543
+
544
+ There's the option to continue using `its` with [rspec-its](https://github.com/rspec/rspec-its) that is an external gem extracted from `rspec-core`.
545
+ If you choose so, disable this conversion with `--keep its`.
546
+
547
+ * Disabled by: `--keep its`
548
+ * See also: [Core: its will be moved into an external gem - The Plan for RSpec 3](http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3#core__will_be_moved_into_an_external_gem)
549
+
523
550
  ## Compatibility
524
551
 
525
552
  Tested on MRI 1.9, MRI 2.0 and JRuby in 1.9 mode.
@@ -9,6 +9,7 @@ module Transpec
9
9
  [:convert_should_receive, true],
10
10
  [:convert_stub, true],
11
11
  [:convert_have_items, true],
12
+ [:convert_its, true],
12
13
  [:convert_deprecated_method, true],
13
14
  [:parenthesize_matcher_arg, true],
14
15
  [:forced, false],
@@ -8,6 +8,7 @@ require 'transpec/syntax'
8
8
  require 'transpec/syntax/be_close'
9
9
  require 'transpec/syntax/double'
10
10
  require 'transpec/syntax/expect'
11
+ require 'transpec/syntax/its'
11
12
  require 'transpec/syntax/method_stub'
12
13
  require 'transpec/syntax/raise_error'
13
14
  require 'transpec/syntax/rspec_configure'
@@ -115,6 +116,10 @@ module Transpec
115
116
  end
116
117
  end
117
118
 
119
+ def process_its(its)
120
+ its.convert_to_describe_subject_it! if @configuration.convert_its?
121
+ end
122
+
118
123
  def process_rspec_configure(rspec_configure)
119
124
  if need_to_modify_expectation_syntax_configuration?(rspec_configure)
120
125
  rspec_configure.modify_expectation_syntaxes!(:expect)
@@ -13,6 +13,7 @@ module Transpec
13
13
  should_receive: :convert_should_receive=,
14
14
  stub: :convert_stub=,
15
15
  have_items: :convert_have_items=,
16
+ its: :convert_its=,
16
17
  deprecated: :convert_deprecated_method=
17
18
  }
18
19
 
@@ -131,6 +132,7 @@ module Transpec
131
132
  " #{'should_receive'.bright} (to #{'expect(obj).to receive'.underline})",
132
133
  " #{'stub'.bright} (to #{'allow(obj).to receive'.underline})",
133
134
  " #{'have_items'.bright} (to #{'expect(obj.size).to eq(x)'.underline})",
135
+ " #{'its'.bright} (to #{'describe { subject { } it { } }'.underline})",
134
136
  " #{'deprecated'.bright} (e.g. from #{'mock'.underline} to #{'double'.underline})",
135
137
  'These are all converted by default.'
136
138
  ],
@@ -0,0 +1,165 @@
1
+ # coding: utf-8
2
+
3
+ require 'transpec/syntax'
4
+ require 'transpec/syntax/mixin/send'
5
+ require 'transpec/util'
6
+
7
+ module Transpec
8
+ class Syntax
9
+ class Its < Syntax
10
+ include Mixin::Send, Util
11
+
12
+ def self.target_method?(receiver_node, method_name)
13
+ receiver_node.nil? && method_name == :its
14
+ end
15
+
16
+ def convert_to_describe_subject_it!
17
+ front, rear = build_wrapper_codes
18
+
19
+ insert_before(beginning_of_line_range, front)
20
+ replace(expression_range, 'it')
21
+ insert_after(block_node.loc.expression, rear)
22
+
23
+ register_record
24
+ end
25
+
26
+ def attribute_expression
27
+ @attribute_expression ||= AttributeExpression.new(attribute_node)
28
+ end
29
+
30
+ def attributes
31
+ attribute_expression.attributes
32
+ end
33
+
34
+ alias_method :attribute_node, :arg_node
35
+
36
+ def block_node
37
+ @node.parent_node
38
+ end
39
+
40
+ private
41
+
42
+ def build_wrapper_codes
43
+ front = ''
44
+ rear = ''
45
+
46
+ front << "\n" if !previous_line_is_blank? &&
47
+ previous_and_current_line_are_same_indentation_level?
48
+
49
+ attributes.each_with_index do |attribute, index|
50
+ indentation = base_indentation + ' ' * index
51
+
52
+ front << indentation + "describe #{attribute.description} do\n"
53
+ front << indentation + " subject { super()#{attribute.selector} }\n"
54
+
55
+ rear = "\n#{indentation}end" + rear
56
+ end
57
+
58
+ front << ' ' * attributes.size
59
+
60
+ [front, rear]
61
+ end
62
+
63
+ def previous_line_is_blank?
64
+ return false unless previous_line_source
65
+ previous_line_source.empty? || !previous_line_source.match(/\A\s*\Z/).nil?
66
+ end
67
+
68
+ def previous_and_current_line_are_same_indentation_level?
69
+ indentation_of_line(previous_line_source) == base_indentation
70
+ end
71
+
72
+ def previous_line_source
73
+ expression_range.source_buffer.source_line(expression_range.line - 1)
74
+ rescue IndexError
75
+ nil
76
+ end
77
+
78
+ def base_indentation
79
+ @base_indentation ||= indentation_of_line(@node)
80
+ end
81
+
82
+ def beginning_of_line_range
83
+ block_range = block_node.loc.expression
84
+ begin_pos = block_range.begin_pos - block_range.column
85
+ Parser::Source::Range.new(block_range.source_buffer, begin_pos, begin_pos)
86
+ end
87
+
88
+ def register_record
89
+ @report.records << Record.new(original_syntax, converted_syntax)
90
+ end
91
+
92
+ def original_syntax
93
+ if attribute_expression.brackets?
94
+ 'its([:key]) { }'
95
+ else
96
+ 'its(:attr) { }'
97
+ end
98
+ end
99
+
100
+ def converted_syntax
101
+ if attribute_expression.brackets?
102
+ "describe '[:key]' do subject { super()[:key] } it { } end"
103
+ else
104
+ "describe 'attr' do subject { super().attr } it { } end"
105
+ end
106
+ end
107
+
108
+ class AttributeExpression
109
+ def initialize(node)
110
+ @node = node
111
+ end
112
+
113
+ def brackets?
114
+ @node.type == :array
115
+ end
116
+
117
+ def literal?
118
+ Util.literal?(@node)
119
+ end
120
+
121
+ def attributes
122
+ @attributes ||= if brackets?
123
+ brackets_attributes
124
+ else
125
+ non_brackets_attributes
126
+ end
127
+ end
128
+
129
+ private
130
+
131
+ def brackets_attributes
132
+ selector = @node.loc.expression.source
133
+ description = literal? ? quote(selector) : selector
134
+ [Attribute.new(selector, description)]
135
+ end
136
+
137
+ def non_brackets_attributes
138
+ if literal?
139
+ expression = @node.children.first.to_s
140
+ chained_names = expression.split('.')
141
+ chained_names.map do |name|
142
+ Attribute.new(".#{name}", quote("##{name}"))
143
+ end
144
+ else
145
+ source = @node.loc.expression.source
146
+ selector = ".send(#{source})"
147
+ [Attribute.new(selector, source)]
148
+ end
149
+ end
150
+
151
+ def quote(string)
152
+ if string.include?("'")
153
+ '"' + string + '"'
154
+ elsif string.include?('"')
155
+ string.inspect
156
+ else
157
+ "'" + string + "'"
158
+ end
159
+ end
160
+ end
161
+
162
+ Attribute = Struct.new(:selector, :description)
163
+ end
164
+ end
165
+ end
data/lib/transpec/util.rb CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  module Transpec
4
4
  module Util
5
+ LITERAL_TYPES = %w(
6
+ true false nil
7
+ int float
8
+ str sym regexp
9
+ ).map(&:to_sym).freeze
10
+
5
11
  module_function
6
12
 
7
13
  def proc_literal?(node)
@@ -55,15 +61,30 @@ module Transpec
55
61
  end
56
62
 
57
63
  def indentation_of_line(arg)
58
- range = case arg
59
- when AST::Node then arg.loc.expression
60
- when Parser::Source::Range then arg
61
- else fail ArgumentError, "Invalid argument #{arg}"
62
- end
64
+ line = case arg
65
+ when AST::Node then arg.loc.expression.source_line
66
+ when Parser::Source::Range then arg.source_line
67
+ when String then arg
68
+ else fail ArgumentError, "Invalid argument #{arg}"
69
+ end
63
70
 
64
- line = range.source_line
65
71
  /^(?<indentation>\s*)\S/ =~ line
66
72
  indentation
67
73
  end
74
+
75
+ def literal?(node)
76
+ case node.type
77
+ when *LITERAL_TYPES
78
+ true
79
+ when :array, :irange, :erange
80
+ node.children.all? { |n| literal?(n) }
81
+ when :hash
82
+ node.children.all? do |pair_node|
83
+ pair_node.children.all? { |n| literal?(n) }
84
+ end
85
+ else
86
+ false
87
+ end
88
+ end
68
89
  end
69
90
  end
@@ -4,7 +4,7 @@ module Transpec
4
4
  # http://semver.org/
5
5
  module Version
6
6
  MAJOR = 1
7
- MINOR = 0
7
+ MINOR = 1
8
8
  PATCH = 0
9
9
 
10
10
  def self.to_s
@@ -13,6 +13,7 @@ module Transpec
13
13
  [:convert_should_receive?, true],
14
14
  [:convert_stub?, true],
15
15
  [:convert_have_items?, true],
16
+ [:convert_its?, true],
16
17
  [:convert_deprecated_method?, true],
17
18
  [:parenthesize_matcher_arg?, true],
18
19
  [:forced?, false],
@@ -528,6 +528,28 @@ module Transpec
528
528
  end
529
529
  end
530
530
 
531
+ describe '#process_its' do
532
+ let(:its_object) { double('its_object').as_null_object }
533
+
534
+ context 'when Configuration#convert_its? is true' do
535
+ before { configuration.convert_its = true }
536
+
537
+ it 'invokes Its#convert_to_describe_subject_it!' do
538
+ its_object.should_receive(:convert_to_describe_subject_it!)
539
+ converter.process_its(its_object)
540
+ end
541
+ end
542
+
543
+ context 'when Configuration#convert_its? is true' do
544
+ before { configuration.convert_its = false }
545
+
546
+ it 'does not invoke Its#convert_to_describe_subject_it!' do
547
+ its_object.should_not_receive(:convert_to_describe_subject_it!)
548
+ converter.process_its(its_object)
549
+ end
550
+ end
551
+ end
552
+
531
553
  describe '#process_rspec_configure' do
532
554
  let(:rspec_configure) { double('rspec_configure').as_null_object }
533
555
 
@@ -66,6 +66,7 @@ module Transpec
66
66
  ['should_receive', :convert_should_receive?],
67
67
  ['stub', :convert_stub?],
68
68
  ['have_items', :convert_have_items],
69
+ ['its', :convert_its],
69
70
  ['deprecated', :convert_deprecated_method?]
70
71
  ].each do |cli_type, config_attr|
71
72
  context "when #{cli_type.inspect} is specified" do
@@ -0,0 +1,390 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require 'transpec/syntax/its'
5
+
6
+ module Transpec
7
+ class Syntax
8
+ describe Its do
9
+ include_context 'parsed objects'
10
+
11
+ subject(:its_object) do
12
+ AST::Scanner.scan(ast) do |node, ancestor_nodes|
13
+ next unless Its.target_node?(node)
14
+ return Its.new(
15
+ node,
16
+ ancestor_nodes,
17
+ source_rewriter
18
+ )
19
+ end
20
+ fail 'No #its node is found!'
21
+ end
22
+
23
+ let(:record) { its_object.report.records.last }
24
+
25
+ describe '#convert_to_describe_subject_it!' do
26
+ before do
27
+ its_object.convert_to_describe_subject_it!
28
+ end
29
+
30
+ context 'when it is `its(:size) { ... }` form' do
31
+ let(:source) do
32
+ <<-END
33
+ describe 'example' do
34
+ subject { ['foo'] }
35
+
36
+ its(:size) { should == 1 }
37
+ end
38
+ END
39
+ end
40
+
41
+ let(:expected_source) do
42
+ <<-END
43
+ describe 'example' do
44
+ subject { ['foo'] }
45
+
46
+ describe '#size' do
47
+ subject { super().size }
48
+ it { should == 1 }
49
+ end
50
+ end
51
+ END
52
+ end
53
+
54
+ it "converts into `describe '#size' do subject { super().size } it { ... } end` form" do
55
+ rewritten_source.should == expected_source
56
+ end
57
+
58
+ it "adds record \"`its(:attr) { }` -> `describe 'attr' do subject { super().attr } it { } end`\"" do
59
+ record.original_syntax.should == 'its(:attr) { }'
60
+ record.converted_syntax.should == "describe 'attr' do subject { super().attr } it { } end"
61
+ end
62
+
63
+ context 'and there is no blank line before #its' do
64
+ context 'and the indentation level of the previous line is same as the target line' do
65
+ let(:source) do
66
+ <<-END
67
+ describe 'example' do
68
+ subject { ['foo'] }
69
+ its(:size) { should == 1 }
70
+ end
71
+ END
72
+ end
73
+
74
+ let(:expected_source) do
75
+ <<-END
76
+ describe 'example' do
77
+ subject { ['foo'] }
78
+
79
+ describe '#size' do
80
+ subject { super().size }
81
+ it { should == 1 }
82
+ end
83
+ end
84
+ END
85
+ end
86
+
87
+ it 'inserts a blank line before #its' do
88
+ rewritten_source.should == expected_source
89
+ end
90
+ end
91
+
92
+ context 'and the indentation level of the previous line is lower than the target line' do
93
+ let(:source) do
94
+ <<-END
95
+ describe 'example' do
96
+ subject { ['foo'] }
97
+
98
+ context 'in some case' do
99
+ its(:size) { should == 1 }
100
+ end
101
+ end
102
+ END
103
+ end
104
+
105
+ let(:expected_source) do
106
+ <<-END
107
+ describe 'example' do
108
+ subject { ['foo'] }
109
+
110
+ context 'in some case' do
111
+ describe '#size' do
112
+ subject { super().size }
113
+ it { should == 1 }
114
+ end
115
+ end
116
+ end
117
+ END
118
+ end
119
+
120
+ it 'does not insert blank line before #its' do
121
+ rewritten_source.should == expected_source
122
+ end
123
+ end
124
+ end
125
+ end
126
+
127
+ context "when it is `its('size') { ... }` form" do
128
+ let(:source) do
129
+ <<-END
130
+ describe 'example' do
131
+ subject { ['foo'] }
132
+
133
+ its('size') { should == 1 }
134
+ end
135
+ END
136
+ end
137
+
138
+ let(:expected_source) do
139
+ <<-END
140
+ describe 'example' do
141
+ subject { ['foo'] }
142
+
143
+ describe '#size' do
144
+ subject { super().size }
145
+ it { should == 1 }
146
+ end
147
+ end
148
+ END
149
+ end
150
+
151
+ it "converts into `describe '#size' do subject { super().size } it { ... } end` form" do
152
+ rewritten_source.should == expected_source
153
+ end
154
+
155
+ it "adds record \"`its(:attr) { }` -> `describe 'attr' do subject { super().attr } it { } end`\"" do
156
+ record.original_syntax.should == 'its(:attr) { }'
157
+ record.converted_syntax.should == "describe 'attr' do subject { super().attr } it { } end"
158
+ end
159
+ end
160
+
161
+ context "when it is `its('size.odd?') { ... }` form" do
162
+ let(:source) do
163
+ <<-END
164
+ describe 'example' do
165
+ subject { ['foo'] }
166
+
167
+ its('size.odd?') { should be_true }
168
+ end
169
+ END
170
+ end
171
+
172
+ let(:expected_source) do
173
+ <<-END
174
+ describe 'example' do
175
+ subject { ['foo'] }
176
+
177
+ describe '#size' do
178
+ subject { super().size }
179
+ describe '#odd?' do
180
+ subject { super().odd? }
181
+ it { should be_true }
182
+ end
183
+ end
184
+ end
185
+ END
186
+ end
187
+
188
+ it 'converts into nested #describe' do
189
+ rewritten_source.should == expected_source
190
+ end
191
+
192
+ it "adds record \"`its(:attr) { }` -> `describe 'attr' do subject { super().attr } it { } end`\"" do
193
+ record.original_syntax.should == 'its(:attr) { }'
194
+ record.converted_syntax.should == "describe 'attr' do subject { super().attr } it { } end"
195
+ end
196
+ end
197
+
198
+ context 'when it is `its([:foo]) { ... }` form' do
199
+ let(:source) do
200
+ <<-END
201
+ describe 'example' do
202
+ subject { { foo: 'bar' } }
203
+
204
+ its([:foo]) { should == 'bar' }
205
+ end
206
+ END
207
+ end
208
+
209
+ let(:expected_source) do
210
+ <<-END
211
+ describe 'example' do
212
+ subject { { foo: 'bar' } }
213
+
214
+ describe '[:foo]' do
215
+ subject { super()[:foo] }
216
+ it { should == 'bar' }
217
+ end
218
+ end
219
+ END
220
+ end
221
+
222
+ it "converts into `describe '[:foo]' do subject { super()[:foo] } it { ... } end` form" do
223
+ rewritten_source.should == expected_source
224
+ end
225
+
226
+ it "adds record \"`its([:key]) { }` -> `describe '[:key]' do subject { super()[:key] } it { } end`\"" do
227
+ record.original_syntax.should == 'its([:key]) { }'
228
+ record.converted_syntax.should == "describe '[:key]' do subject { super()[:key] } it { } end"
229
+ end
230
+ end
231
+
232
+ context "when it is `its(['foo']) { ... }` form" do
233
+ let(:source) do
234
+ <<-END
235
+ describe 'example' do
236
+ subject { { 'foo' => 'bar' } }
237
+
238
+ its(['foo']) { should == 'bar' }
239
+ end
240
+ END
241
+ end
242
+
243
+ let(:expected_source) do
244
+ <<-END
245
+ describe 'example' do
246
+ subject { { 'foo' => 'bar' } }
247
+
248
+ describe "['foo']" do
249
+ subject { super()['foo'] }
250
+ it { should == 'bar' }
251
+ end
252
+ end
253
+ END
254
+ end
255
+
256
+ it "converts into `describe \"['foo']\" do subject { super()['foo'] } it { ... } end` form" do
257
+ rewritten_source.should == expected_source
258
+ end
259
+
260
+ it "adds record \"`its([:key]) { }` -> `describe '[:key]' do subject { super()[:key] } it { } end`\"" do
261
+ record.original_syntax.should == 'its([:key]) { }'
262
+ record.converted_syntax.should == "describe '[:key]' do subject { super()[:key] } it { } end"
263
+ end
264
+ end
265
+
266
+ context 'when it is `its([3, 2]) { ... }` form' do
267
+ let(:source) do
268
+ <<-END
269
+ describe 'example' do
270
+ subject { %w(a b c d r f g) }
271
+
272
+ its([3, 2]) { should == %w(d r) }
273
+ end
274
+ END
275
+ end
276
+
277
+ let(:expected_source) do
278
+ <<-END
279
+ describe 'example' do
280
+ subject { %w(a b c d r f g) }
281
+
282
+ describe '[3, 2]' do
283
+ subject { super()[3, 2] }
284
+ it { should == %w(d r) }
285
+ end
286
+ end
287
+ END
288
+ end
289
+
290
+ it "converts into `describe '[3, 2]' do subject { super()[3, 2] } it { ... } end` form" do
291
+ rewritten_source.should == expected_source
292
+ end
293
+
294
+ it "adds record \"`its([:key]) { }` -> `describe '[:key]' do subject { super()[:key] } it { } end`\"" do
295
+ record.original_syntax.should == 'its([:key]) { }'
296
+ record.converted_syntax.should == "describe '[:key]' do subject { super()[:key] } it { } end"
297
+ end
298
+ end
299
+
300
+ context 'when it is `its(attribute) { ... }` form' do
301
+ let(:source) do
302
+ <<-END
303
+ describe 'example' do
304
+ subject { 'foo' }
305
+
306
+ [
307
+ [:size, 3],
308
+ [:upcase, 'FOO']
309
+ ].each do |attribute, expected_value|
310
+ its(attribute) { should == expected_value }
311
+ end
312
+ end
313
+ END
314
+ end
315
+
316
+ let(:expected_source) do
317
+ <<-END
318
+ describe 'example' do
319
+ subject { 'foo' }
320
+
321
+ [
322
+ [:size, 3],
323
+ [:upcase, 'FOO']
324
+ ].each do |attribute, expected_value|
325
+ describe attribute do
326
+ subject { super().send(attribute) }
327
+ it { should == expected_value }
328
+ end
329
+ end
330
+ end
331
+ END
332
+ end
333
+
334
+ it 'converts into `describe attribute do subject { super().send(attribute) } it { ... } end` form' do
335
+ rewritten_source.should == expected_source
336
+ end
337
+
338
+ it "adds record \"`its(:attr) { }` -> `describe 'attr' do subject { super().attr } it { } end`\"" do
339
+ record.original_syntax.should == 'its(:attr) { }'
340
+ record.converted_syntax.should == "describe 'attr' do subject { super().attr } it { } end"
341
+ end
342
+ end
343
+
344
+ context 'when it is `its([1, length]) { ... }` form' do
345
+ let(:source) do
346
+ <<-END
347
+ describe 'example' do
348
+ subject { 'foobar' }
349
+
350
+ [
351
+ [2, 'oo'],
352
+ [3, 'oob']
353
+ ].each do |length, expected_value|
354
+ its([1, length]) { should == expected_value }
355
+ end
356
+ end
357
+ END
358
+ end
359
+
360
+ let(:expected_source) do
361
+ <<-END
362
+ describe 'example' do
363
+ subject { 'foobar' }
364
+
365
+ [
366
+ [2, 'oo'],
367
+ [3, 'oob']
368
+ ].each do |length, expected_value|
369
+ describe [1, length] do
370
+ subject { super()[1, length] }
371
+ it { should == expected_value }
372
+ end
373
+ end
374
+ end
375
+ END
376
+ end
377
+
378
+ it 'converts into `describe [1, length] do subject { super()[1, length] } it { ... } end` form' do
379
+ rewritten_source.should == expected_source
380
+ end
381
+
382
+ it "adds record \"`its([:key]) { }` -> `describe '[:key]' do subject { super()[:key] } it { } end`\"" do
383
+ record.original_syntax.should == 'its([:key]) { }'
384
+ record.converted_syntax.should == "describe '[:key]' do subject { super()[:key] } it { } end"
385
+ end
386
+ end
387
+ end
388
+ end
389
+ end
390
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: transpec
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuji Nakayama
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-27 00:00:00.000000000 Z
11
+ date: 2013-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -207,6 +207,7 @@ files:
207
207
  - lib/transpec/syntax/double.rb
208
208
  - lib/transpec/syntax/expect.rb
209
209
  - lib/transpec/syntax/have.rb
210
+ - lib/transpec/syntax/its.rb
210
211
  - lib/transpec/syntax/method_stub.rb
211
212
  - lib/transpec/syntax/mixin/allow_no_message.rb
212
213
  - lib/transpec/syntax/mixin/any_instance.rb
@@ -244,6 +245,7 @@ files:
244
245
  - spec/transpec/syntax/double_spec.rb
245
246
  - spec/transpec/syntax/expect_spec.rb
246
247
  - spec/transpec/syntax/have_spec.rb
248
+ - spec/transpec/syntax/its_spec.rb
247
249
  - spec/transpec/syntax/method_stub_spec.rb
248
250
  - spec/transpec/syntax/operator_matcher_spec.rb
249
251
  - spec/transpec/syntax/raise_error_spec.rb
@@ -306,6 +308,7 @@ test_files:
306
308
  - spec/transpec/syntax/double_spec.rb
307
309
  - spec/transpec/syntax/expect_spec.rb
308
310
  - spec/transpec/syntax/have_spec.rb
311
+ - spec/transpec/syntax/its_spec.rb
309
312
  - spec/transpec/syntax/method_stub_spec.rb
310
313
  - spec/transpec/syntax/operator_matcher_spec.rb
311
314
  - spec/transpec/syntax/raise_error_spec.rb