transpec 1.2.2 → 1.3.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.
@@ -4,17 +4,56 @@ module Transpec
4
4
  class Syntax
5
5
  module Mixin
6
6
  module AnyInstance
7
+ include ::AST::Sexp
8
+
9
+ def register_request_of_any_instance_inspection(rewriter)
10
+ key = :any_instance_target_class_name
11
+ code = <<-END.gsub(/^\s+\|/, '').chomp
12
+ |if self.class.name == 'RSpec::Mocks::AnyInstance::Recorder'
13
+ | if respond_to?(:klass)
14
+ | klass.name
15
+ | elsif instance_variable_defined?(:@klass)
16
+ | instance_variable_get(:@klass).name
17
+ | else
18
+ | nil
19
+ | end
20
+ |else
21
+ | nil
22
+ |end
23
+ END
24
+ rewriter.register_request(subject_node, key, code)
25
+ end
26
+
7
27
  def any_instance?
8
- !class_node_of_any_instance.nil?
28
+ return true unless any_instance_target_node.nil?
29
+ node_data = runtime_node_data(subject_node)
30
+ return false unless node_data
31
+ return false unless node_data[:any_instance_target_class_name]
32
+ !node_data[:any_instance_target_class_name].result.nil?
9
33
  end
10
34
 
11
- def class_node_of_any_instance
35
+ def any_instance_target_class_source
36
+ return nil unless any_instance?
37
+
38
+ if any_instance_target_node
39
+ any_instance_target_node.loc.expression.source
40
+ else
41
+ runtime_node_data(subject_node)[:any_instance_target_class_name].result
42
+ end
43
+ end
44
+
45
+ def any_instance_target_node
12
46
  return nil unless subject_node.type == :send
13
47
  return nil unless subject_node.children.count == 2
14
48
  receiver_node, method_name = *subject_node
49
+ return nil unless receiver_node
15
50
  return nil unless method_name == :any_instance
16
- return nil unless receiver_node.type == :const
17
- receiver_node
51
+
52
+ if receiver_node.type == :const || receiver_node == s(:send, nil, :described_class)
53
+ receiver_node
54
+ else
55
+ nil
56
+ end
18
57
  end
19
58
  end
20
59
  end
@@ -88,6 +88,10 @@ module Transpec
88
88
  arg_node.loc.expression
89
89
  end
90
90
 
91
+ def args_range
92
+ arg_nodes.first.loc.expression.begin.join(arg_nodes.last.loc.expression.end)
93
+ end
94
+
91
95
  def parentheses_range
92
96
  selector_range.end.join(expression_range.end)
93
97
  end
@@ -34,6 +34,8 @@ module Transpec
34
34
  :allow_to_receive_available?,
35
35
  [:allow, :receive]
36
36
  )
37
+
38
+ register_request_of_any_instance_inspection(rewriter)
37
39
  end
38
40
 
39
41
  def expect_to_receive_available?
@@ -83,7 +85,7 @@ module Transpec
83
85
 
84
86
  def convert_to_syntax!(syntax, negative_form)
85
87
  if any_instance?
86
- wrap_class_with_any_instance_of!(syntax)
88
+ wrap_subject_with_any_instance_of!(syntax)
87
89
  else
88
90
  wrap_subject_with_method!(syntax)
89
91
  end
@@ -104,11 +106,9 @@ module Transpec
104
106
  end
105
107
  end
106
108
 
107
- def wrap_class_with_any_instance_of!(syntax)
108
- insert_before(subject_range, "#{syntax}_any_instance_of(")
109
- map = subject_node.loc
110
- dot_any_instance_range = map.dot.join(map.selector)
111
- replace(dot_any_instance_range, ')')
109
+ def wrap_subject_with_any_instance_of!(syntax)
110
+ expression = "#{syntax}_any_instance_of(#{any_instance_target_class_source})"
111
+ replace(subject_range, expression)
112
112
  end
113
113
 
114
114
  def broken_block_nodes
@@ -164,7 +164,7 @@ module Transpec
164
164
 
165
165
  def original_syntax(conversion_type)
166
166
  syntax = if any_instance? && conversion_type != :stub
167
- 'SomeClass.any_instance.'
167
+ 'Klass.any_instance.'
168
168
  else
169
169
  'obj.'
170
170
  end
@@ -186,13 +186,13 @@ module Transpec
186
186
  syntax = case conversion_type
187
187
  when :expect
188
188
  if any_instance?
189
- 'expect_any_instance_of(SomeClass).'
189
+ 'expect_any_instance_of(Klass).'
190
190
  else
191
191
  'expect(obj).'
192
192
  end
193
193
  when :allow
194
194
  if any_instance?
195
- 'allow_any_instance_of(SomeClass).'
195
+ 'allow_any_instance_of(Klass).'
196
196
  else
197
197
  'allow(obj).'
198
198
  end
@@ -4,8 +4,8 @@ module Transpec
4
4
  # http://semver.org/
5
5
  module Version
6
6
  MAJOR = 1
7
- MINOR = 2
8
- PATCH = 2
7
+ MINOR = 3
8
+ PATCH = 0
9
9
 
10
10
  def self.to_s
11
11
  [MAJOR, MINOR, PATCH].join('.')
@@ -224,14 +224,14 @@ module Transpec
224
224
  let(:source) do
225
225
  <<-END
226
226
  describe 'example group' do
227
- class SomeClass
227
+ class Klass
228
228
  def some_method
229
229
  1.should == 1
230
230
  end
231
231
  end
232
232
 
233
233
  it 'is an example' do
234
- SomeClass.new.some_method
234
+ Klass.new.some_method
235
235
  end
236
236
  end
237
237
  END
@@ -97,14 +97,14 @@ module Transpec
97
97
  let(:source) do
98
98
  <<-END
99
99
  describe 'example group' do
100
- class SomeClass
100
+ class Klass
101
101
  def some_method
102
102
  1.should == 1
103
103
  end
104
104
  end
105
105
 
106
106
  it 'is an example' do
107
- SomeClass.new.some_method
107
+ Klass.new.some_method
108
108
  end
109
109
  end
110
110
  END
@@ -481,7 +481,7 @@ module Transpec
481
481
  <<-END
482
482
  describe 'foo' do
483
483
  it 'is an example' do
484
- class SomeClass
484
+ class Klass
485
485
  target
486
486
  end
487
487
  end
@@ -497,13 +497,13 @@ module Transpec
497
497
  <<-END
498
498
  describe 'foo' do
499
499
  it 'is an example' do
500
- class SomeClass
500
+ class Klass
501
501
  def some_method
502
502
  target
503
503
  end
504
504
  end
505
505
 
506
- SomeClass.new.some_method
506
+ Klass.new.some_method
507
507
  end
508
508
  end
509
509
  END
@@ -583,14 +583,14 @@ module Transpec
583
583
  context 'when in an instance method in a class' do
584
584
  let(:source) do
585
585
  <<-END
586
- class SomeClass
586
+ class Klass
587
587
  def some_method
588
588
  target
589
589
  end
590
590
  end
591
591
 
592
592
  describe 'test' do
593
- example { SomeClass.new.some_method }
593
+ example { Klass.new.some_method }
594
594
  end
595
595
  END
596
596
  end
@@ -70,6 +70,58 @@ module Transpec
70
70
  describe '#convert_to_standard_expectation!' do
71
71
  let(:record) { have_object.report.records.last }
72
72
 
73
+ context 'when rspec-rails is loaded in the spec' do
74
+ include_context 'dynamic analysis objects'
75
+
76
+ let(:source) do
77
+ <<-END
78
+ module RSpec
79
+ module Rails
80
+ end
81
+ end
82
+
83
+ describe 'example' do
84
+ it 'has 2 items' do
85
+ [:foo, :bar].should have(2).items
86
+ end
87
+ end
88
+ END
89
+ end
90
+
91
+ let(:have_object) { should_object.have_matcher }
92
+
93
+ it 'does nothing' do
94
+ have_object.convert_to_standard_expectation!
95
+ rewritten_source.should == source
96
+ end
97
+ end
98
+
99
+ context 'when rspec-collection_matchers is loaded in the spec' do
100
+ include_context 'dynamic analysis objects'
101
+
102
+ let(:source) do
103
+ <<-END
104
+ module RSpec
105
+ module CollectionMatchers
106
+ end
107
+ end
108
+
109
+ describe 'example' do
110
+ it 'has 2 items' do
111
+ [:foo, :bar].should have(2).items
112
+ end
113
+ end
114
+ END
115
+ end
116
+
117
+ let(:have_object) { should_object.have_matcher }
118
+
119
+ it 'does nothing' do
120
+ have_object.convert_to_standard_expectation!
121
+ rewritten_source.should == source
122
+ end
123
+ end
124
+
73
125
  context 'when it is `collection.should have(2).items` form' do
74
126
  let(:source) do
75
127
  <<-END
@@ -618,6 +670,309 @@ module Transpec
618
670
  end
619
671
  end
620
672
  end
673
+
674
+ context 'when it is `expect(subject).to have(1).word` form' do
675
+ let(:have_object) { expect_object.have_matcher }
676
+
677
+ context 'with runtime information' do
678
+ include_context 'dynamic analysis objects'
679
+
680
+ context 'when the subject responds to #words and #words responds to #size' do
681
+ context 'and ActiveSupport::Inflector.pluralize is available in the spec' do
682
+ let(:source) do
683
+ <<-END
684
+ require 'active_support/inflector'
685
+
686
+ class String
687
+ def words
688
+ split(' ')
689
+ end
690
+ end
691
+
692
+ describe 'string' do
693
+ it 'has a word' do
694
+ expect(subject).to have(1).word
695
+ end
696
+ end
697
+ END
698
+ end
699
+
700
+ let(:expected_source) do
701
+ <<-END
702
+ require 'active_support/inflector'
703
+
704
+ class String
705
+ def words
706
+ split(' ')
707
+ end
708
+ end
709
+
710
+ describe 'string' do
711
+ it 'has a word' do
712
+ expect(subject.words.size).to eq(1)
713
+ end
714
+ end
715
+ END
716
+ end
717
+
718
+ it 'converts into `expect(subject.words.size).to eq(1)` form' do
719
+ have_object.convert_to_standard_expectation!
720
+ rewritten_source.should == expected_source
721
+ end
722
+
723
+ it 'adds record "`expect(obj).to have(n).words` -> `expect(obj.words.size).to eq(n)`"' do
724
+ have_object.convert_to_standard_expectation!
725
+ record.original_syntax.should == 'expect(obj).to have(n).words'
726
+ record.converted_syntax.should == 'expect(obj.words.size).to eq(n)'
727
+ end
728
+ end
729
+
730
+ context 'and ActiveSupport::Inflector.pluralize is not available in the spec' do
731
+ let(:source) do
732
+ <<-END
733
+ class String
734
+ def words
735
+ split(' ')
736
+ end
737
+ end
738
+
739
+ describe 's' do
740
+ it 'has a character' do
741
+ expect(subject).to have(1).word
742
+ end
743
+ end
744
+ END
745
+ end
746
+
747
+ let(:expected_source) do
748
+ <<-END
749
+ class String
750
+ def words
751
+ split(' ')
752
+ end
753
+ end
754
+
755
+ describe 's' do
756
+ it 'has a character' do
757
+ expect(subject.size).to eq(1)
758
+ end
759
+ end
760
+ END
761
+ end
762
+
763
+ it 'converts into `expect(subject.size).to eq(1)` form' do
764
+ have_object.convert_to_standard_expectation!
765
+ rewritten_source.should == expected_source
766
+ end
767
+
768
+ it 'adds record "`expect(collection).to have(n).items` -> `expect(collection.size).to eq(n)`"' do
769
+ have_object.convert_to_standard_expectation!
770
+ record.original_syntax.should == 'expect(collection).to have(n).items'
771
+ record.converted_syntax.should == 'expect(collection.size).to eq(n)'
772
+ end
773
+ end
774
+ end
775
+ end
776
+
777
+ context 'without runtime information' do
778
+ let(:source) do
779
+ <<-END
780
+ require 'active_support/inflector'
781
+
782
+ class String
783
+ def words
784
+ split(' ')
785
+ end
786
+ end
787
+
788
+ describe 'string' do
789
+ it 'has a word' do
790
+ expect(subject).to have(1).word
791
+ end
792
+ end
793
+ END
794
+ end
795
+
796
+ let(:expected_source) do
797
+ <<-END
798
+ require 'active_support/inflector'
799
+
800
+ class String
801
+ def words
802
+ split(' ')
803
+ end
804
+ end
805
+
806
+ describe 'string' do
807
+ it 'has a word' do
808
+ expect(subject.size).to eq(1)
809
+ end
810
+ end
811
+ END
812
+ end
813
+
814
+ it 'converts into `expect(subject.size).to eq(1)` form' do
815
+ have_object.convert_to_standard_expectation!
816
+ rewritten_source.should == expected_source
817
+ end
818
+
819
+ it 'adds record "`expect(collection).to have(n).items` -> `expect(collection.size).to eq(n)`"' do
820
+ have_object.convert_to_standard_expectation!
821
+ record.original_syntax.should == 'expect(collection).to have(n).items'
822
+ record.converted_syntax.should == 'expect(collection.size).to eq(n)'
823
+ end
824
+ end
825
+ end
826
+
827
+ context 'when it is `expect(subject).to have(2).errors_on(:name)` form' do
828
+ let(:have_object) { expect_object.have_matcher }
829
+
830
+ context 'with runtime information' do
831
+ include_context 'dynamic analysis objects'
832
+
833
+ context 'and subject responds to #errors_on' do
834
+ let(:source) do
835
+ <<-END
836
+ class SomeModel
837
+ def errors_on(attribute)
838
+ [:foo, :bar]
839
+ end
840
+ end
841
+
842
+ describe SomeModel do
843
+ it 'has 2 errors on name' do
844
+ expect(subject).to have(2).errors_on(:name)
845
+ end
846
+ end
847
+ END
848
+ end
849
+
850
+ let(:expected_source) do
851
+ <<-END
852
+ class SomeModel
853
+ def errors_on(attribute)
854
+ [:foo, :bar]
855
+ end
856
+ end
857
+
858
+ describe SomeModel do
859
+ it 'has 2 errors on name' do
860
+ expect(subject.errors_on(:name).size).to eq(2)
861
+ end
862
+ end
863
+ END
864
+ end
865
+
866
+ it 'converts into `expect(subject.errors_on(:name).size).to eq(2)` form' do
867
+ have_object.convert_to_standard_expectation!
868
+ rewritten_source.should == expected_source
869
+ end
870
+
871
+ it 'adds record ' +
872
+ '"`expect(obj).to have(n).errors_on(...)` -> `expect(obj.errors_on(...).size).to eq(n)`"' do
873
+ have_object.convert_to_standard_expectation!
874
+ record.original_syntax.should == 'expect(obj).to have(n).errors_on(...)'
875
+ record.converted_syntax.should == 'expect(obj.errors_on(...).size).to eq(n)'
876
+ end
877
+ end
878
+
879
+ context 'and #errors_on is a private method' do
880
+ let(:source) do
881
+ <<-END
882
+ class SomeModel
883
+ private
884
+
885
+ def errors_on(attribute)
886
+ [:foo, :bar]
887
+ end
888
+ end
889
+
890
+ describe SomeModel do
891
+ it 'has 2 errors on name' do
892
+ expect(subject).to have(2).errors_on(:name)
893
+ end
894
+ end
895
+ END
896
+ end
897
+
898
+ let(:expected_source) do
899
+ <<-END
900
+ class SomeModel
901
+ private
902
+
903
+ def errors_on(attribute)
904
+ [:foo, :bar]
905
+ end
906
+ end
907
+
908
+ describe SomeModel do
909
+ it 'has 2 errors on name' do
910
+ expect(subject.send(:errors_on, :name).size).to eq(2)
911
+ end
912
+ end
913
+ END
914
+ end
915
+
916
+ it 'converts into `expect(subject.send(:errors_on, :name).size).to eq(2)` form' do
917
+ have_object.convert_to_standard_expectation!
918
+ rewritten_source.should == expected_source
919
+ end
920
+
921
+ it 'adds record ' +
922
+ '"`expect(obj).to have(n).errors_on(...)` -> `expect(obj.send(:errors_on, ...).size).to eq(n)`"' do
923
+ have_object.convert_to_standard_expectation!
924
+ record.original_syntax.should == 'expect(obj).to have(n).errors_on(...)'
925
+ record.converted_syntax.should == 'expect(obj.send(:errors_on, ...).size).to eq(n)'
926
+ end
927
+ end
928
+ end
929
+
930
+ context 'without runtime information' do
931
+ let(:source) do
932
+ <<-END
933
+ class SomeModel
934
+ def errors_on(attribute)
935
+ [:foo, :bar]
936
+ end
937
+ end
938
+
939
+ describe SomeModel do
940
+ it 'has 2 errors on name' do
941
+ expect(subject).to have(2).errors_on(:name)
942
+ end
943
+ end
944
+ END
945
+ end
946
+
947
+ let(:expected_source) do
948
+ <<-END
949
+ class SomeModel
950
+ def errors_on(attribute)
951
+ [:foo, :bar]
952
+ end
953
+ end
954
+
955
+ describe SomeModel do
956
+ it 'has 2 errors on name' do
957
+ expect(subject.errors_on(:name).size).to eq(2)
958
+ end
959
+ end
960
+ END
961
+ end
962
+
963
+ it 'converts into `expect(subject.errors_on(:name).size).to eq(2)` form' do
964
+ have_object.convert_to_standard_expectation!
965
+ rewritten_source.should == expected_source
966
+ end
967
+
968
+ it 'adds record ' +
969
+ '"`expect(obj).to have(n).errors_on(...)` -> `expect(obj.errors_on(...).size).to eq(n)`"' do
970
+ have_object.convert_to_standard_expectation!
971
+ record.original_syntax.should == 'expect(obj).to have(n).errors_on(...)'
972
+ record.converted_syntax.should == 'expect(obj.errors_on(...).size).to eq(n)'
973
+ end
974
+ end
975
+ end
621
976
  end
622
977
  end
623
978
  end