warp 1.3.3 → 1.4.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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +7 -10
  3. data/Appraisals +2 -3
  4. data/CHANGELOG.md +6 -0
  5. data/Gemfile +3 -5
  6. data/README.md +2 -3
  7. data/gemfiles/rails_3.2_rspec_3.0.gemfile +2 -6
  8. data/gemfiles/rails_3.2_rspec_3.1.gemfile +2 -6
  9. data/gemfiles/rails_3.2_rspec_3.2.gemfile +2 -6
  10. data/gemfiles/{rails_3.2_rspec_2.99.gemfile → rails_3.2_rspec_3.3.gemfile} +3 -7
  11. data/gemfiles/rails_4.0_rspec_3.0.gemfile +2 -6
  12. data/gemfiles/rails_4.0_rspec_3.1.gemfile +2 -6
  13. data/gemfiles/rails_4.0_rspec_3.2.gemfile +2 -6
  14. data/gemfiles/{rails_4.0_rspec_2.99.gemfile → rails_4.0_rspec_3.3.gemfile} +3 -7
  15. data/gemfiles/rails_4.1_rspec_3.0.gemfile +2 -6
  16. data/gemfiles/rails_4.1_rspec_3.1.gemfile +2 -6
  17. data/gemfiles/rails_4.1_rspec_3.2.gemfile +2 -6
  18. data/gemfiles/{rails_4.1_rspec_2.99.gemfile → rails_4.1_rspec_3.3.gemfile} +3 -7
  19. data/gemfiles/rails_4.2_rspec_3.0.gemfile +2 -6
  20. data/gemfiles/rails_4.2_rspec_3.1.gemfile +2 -6
  21. data/gemfiles/rails_4.2_rspec_3.2.gemfile +2 -6
  22. data/gemfiles/{rails_4.2_rspec_2.99.gemfile → rails_4.2_rspec_3.3.gemfile} +3 -7
  23. data/lib/warp/action_matchers/create_matcher.rb +6 -14
  24. data/lib/warp/action_matchers/destroy_matcher.rb +6 -14
  25. data/lib/warp/action_matchers/matcher.rb +7 -1
  26. data/lib/warp/action_matchers/update_matcher.rb +6 -14
  27. data/lib/warp/controller_matchers/assign_matcher.rb +127 -48
  28. data/lib/warp/instrument.rb +8 -26
  29. data/lib/warp/matcher.rb +2 -27
  30. data/lib/warp/version.rb +2 -2
  31. data/spec/spec_helper.rb +0 -11
  32. data/spec/warp/action_matchers/create_matcher_spec.rb +1 -1
  33. data/spec/warp/action_matchers/destroy_matcher_spec.rb +1 -1
  34. data/spec/warp/action_matchers/update_matcher_spec.rb +1 -1
  35. data/spec/warp/controller_matchers/assign_matcher_spec.rb +132 -88
  36. metadata +7 -7
@@ -2,92 +2,171 @@ require "warp/matcher"
2
2
 
3
3
  module Warp
4
4
  module ControllerMatchers
5
- class AssignMatcher < Warp::Matcher
6
- attr_reader :assign_key, :assign_with, :assign_with_a, :assign_with_a_new
7
- attr_reader :controller, :failure_message, :failure_message_when_negated, :description
5
+ class AssignMatcherBuilder
6
+ attr_reader :assign_key, :controller
8
7
 
9
8
  def initialize(assign_key, controller)
10
9
  @assign_key = assign_key
11
10
  @controller = controller
12
11
  end
13
12
 
14
- def with(assign_eq)
15
- @assign_with = assign_eq
16
- self
13
+ def with(value)
14
+ AssignWithMatcher.new(@controller, @assign_key, value)
15
+ end
16
+
17
+ def with_a(klass)
18
+ AssignWithAMatcher.new(@controller, @assign_key, klass)
19
+ end
20
+
21
+ def with_a_new(klass)
22
+ AssignWithANewMatcher.new(@controller, @assign_key, klass)
17
23
  end
18
24
 
19
- def with_a(assign_class)
20
- @assign_with_a = assign_class
21
- self
25
+ def method_missing(method, *args)
26
+ matcher.send(method, *args)
27
+ end
28
+
29
+ private
30
+
31
+ def matcher
32
+ @matcher ||= AssignMatcher.new(@controller, @assign_key)
22
33
  end
34
+ end
23
35
 
24
- def with_a_new(assign_class)
25
- @assign_with_a_new = assign_class
26
- self
36
+ def assign(assign_key)
37
+ AssignMatcherBuilder.new(controller, assign_key)
38
+ end
39
+
40
+ class AssignMatcher < Warp::Matcher
41
+ attr_reader :assign_key, :controller
42
+
43
+ def initialize(assign_key, controller)
44
+ @assign_key = assign_key
45
+ @controller = controller
27
46
  end
28
-
47
+
29
48
  def matches?(actual)
30
49
  @controller = actual if actual.is_a?(ActionController::Metal)
50
+ check_assign
51
+ end
31
52
 
32
- if multiple_assertions?
33
- raise "Only one of .with, .with_a, and .with_a_new can be used with the assigns matcher."
34
- end
53
+ def description
54
+ "assign @#{assign_key}"
55
+ end
35
56
 
36
- return check_assign_with if assign_with
37
- return check_assign_with_a if assign_with_a
38
- return check_assign_with_a_new if assign_with_a_new
39
- return check_assign
57
+ def failure_message
58
+ "expected @#{assign_key} to be assigned"
40
59
  end
41
-
60
+
61
+ def failure_message_when_negated
62
+ "expected @#{assign_key} to not be assigned"
63
+ end
64
+
42
65
  private
43
66
 
44
67
  def check_assign
45
- @description = "assign @#{assign_key}"
46
- @failure_message = "expected @#{assign_key} to be assigned"
47
- @failure_message_when_negated = "expected @#{assign_key} to not be assigned"
48
-
49
68
  values_match?(false, assign_value.nil?)
50
69
  end
51
70
 
52
- def check_assign_with
53
- @description = "assign @#{assign_key} with #{description_of(assign_with)}"
54
- @failure_message = "expected @#{assign_key} to be assigned with #{description_of(assign_with)} but was assigned with #{assign_value.inspect}"
55
- @failure_message_when_negated = "expected @#{assign_key} to not be assigned with #{description_of(assign_with)}"
71
+ def assign_value
72
+ controller.view_assigns[assign_key.to_s]
73
+ end
74
+ def has_ancestor?(expected_class, actual)
75
+ actual.class.ancestors.any? {|ancestor| values_match?(expected_class, ancestor) }
76
+ end
77
+ end
78
+
79
+ class AssignWithMatcher < AssignMatcher
80
+ attr_reader :assign_with
81
+
82
+ def initialize(controller, assign_key, assign_with)
83
+ super(controller, assign_key)
84
+ @assign_with = assign_with
85
+ end
56
86
 
87
+ def description
88
+ "assign @#{assign_key} with #{description_of(assign_with)}"
89
+ end
90
+
91
+ def failure_message
92
+ if assign_value.nil?
93
+ "expected @#{assign_key} to be assigned with #{description_of(assign_with)} but was not assigned"
94
+ else
95
+ "expected @#{assign_key} to be assigned with #{description_of(assign_with)} but was assigned with #{assign_value.inspect}"
96
+ end
97
+ end
98
+
99
+ def failure_message_when_negated
100
+ "expected @#{assign_key} to not be assigned with #{description_of(assign_with)}"
101
+ end
102
+
103
+ private
104
+
105
+ def check_assign
57
106
  values_match?(assign_with, assign_value)
58
107
  end
108
+ end
109
+
110
+ class AssignWithAMatcher < AssignMatcher
111
+ attr_reader :assign_with_a
112
+
113
+ def initialize(controller, assign_key, assign_with_a)
114
+ super(controller, assign_key)
115
+ @assign_with_a = assign_with_a
116
+ end
59
117
 
60
- def check_assign_with_a
61
- @description = "assign @#{assign_key} with an instance of #{assign_with_a.name}"
62
- @failure_message = "expected @#{assign_key} to be assigned with an instance of #{assign_with_a.name} but was assigned with an instance of #{assign_value.class.name}"
63
- @failure_message_when_negated = "expected @#{assign_key} to not be assigned with an instance of #{assign_with_a.name}"
118
+ def description
119
+ "assign @#{assign_key} with an instance of #{assign_with_a.name}"
120
+ end
121
+
122
+ def failure_message
123
+ if assign_value.nil?
124
+ "expected @#{assign_key} to be assigned with an instance of #{assign_with_a.name} but was not assigned"
125
+ else
126
+ "expected @#{assign_key} to be assigned with an instance of #{assign_with_a.name} but was assigned with an instance of #{assign_value.class.name}"
127
+ end
128
+ end
64
129
 
130
+ def failure_message_when_negated
131
+ "expected @#{assign_key} to not be assigned with an instance of #{assign_with_a.name}"
132
+ end
133
+
134
+ private
135
+
136
+ def check_assign
65
137
  has_ancestor?(assign_with_a, assign_value)
66
138
  end
139
+ end
67
140
 
68
- def check_assign_with_a_new
69
- @description = "assign @#{assign_key} with a new instance of #{assign_with_a_new.name}"
70
- @failure_message = "expected @#{assign_key} to be assigned with a new instance of #{assign_with_a_new.name} but was assigned with a #{assign_value.persisted? ? "persisted" : "new"} instance of #{assign_value.class.name}"
71
- @failure_message_when_negated = "expected @#{assign_key} to not be assigned with a new instance of #{assign_with_a_new.name}"
141
+ class AssignWithANewMatcher < AssignMatcher
142
+ attr_reader :assign_with_a_new
72
143
 
73
- has_ancestor?(assign_with_a_new, assign_value) && values_match?(false, assign_value.persisted?)
144
+ def initialize(controller, assign_key, assign_with_a_new)
145
+ super(controller, assign_key)
146
+ @assign_with_a_new = assign_with_a_new
74
147
  end
75
148
 
76
- def assign_value
77
- controller.view_assigns[assign_key.to_s]
149
+ def description
150
+ "assign @#{assign_key} with a new instance of #{assign_with_a_new.name}"
78
151
  end
79
152
 
80
- def multiple_assertions?
81
- [@assign_with, @assign_with_a, @assign_with_a_new].compact.size > 1
153
+ def failure_message
154
+ if assign_value.nil?
155
+ "expected @#{assign_key} to be assigned with a new instance of #{assign_with_a_new.name} but was not assigned"
156
+ else
157
+ "expected @#{assign_key} to be assigned with a new instance of #{assign_with_a_new.name} but was assigned with a #{assign_value.try(:persisted?) ? "persisted" : "new"} instance of #{assign_value.class.name}"
158
+ end
82
159
  end
83
160
 
84
- def has_ancestor?(expected_class, actual)
85
- actual.class.ancestors.any? {|ancestor| values_match?(expected_class, ancestor) }
161
+ def failure_message_when_negated
162
+ "expected @#{assign_key} to not be assigned with a new instance of #{assign_with_a_new.name}"
86
163
  end
87
- end
88
164
 
89
- def assign(assign_key)
90
- AssignMatcher.new(assign_key, controller)
165
+ private
166
+
167
+ def check_assign
168
+ has_ancestor?(assign_with_a_new, assign_value) && values_match?(false, assign_value.try(:persisted?))
169
+ end
91
170
  end
92
171
  end
93
- end
172
+ end
@@ -12,7 +12,7 @@ module Warp
12
12
  def register(instrument)
13
13
  @@registry ||= {}
14
14
  @@registry[instrument.klass] ||= {}
15
- @@registry[instrument.klass][instrument.method] = instrument
15
+ @@registry[instrument.klass][instrument.method] = instrument
16
16
  end
17
17
  end
18
18
 
@@ -43,7 +43,7 @@ module Warp
43
43
  end
44
44
 
45
45
  def log(args)
46
- calls << args
46
+ calls << args if enabled?
47
47
  end
48
48
 
49
49
  private
@@ -57,33 +57,15 @@ module Warp
57
57
  end
58
58
 
59
59
  def setup_hook
60
- if Module.method_defined?(:prepend)
61
- hook = Module.new
60
+ original_method = klass.instance_method(method)
62
61
 
63
- hook.send(:define_method, method) do |*args|
64
- result = super(*args)
62
+ klass.send(:define_method, method) do |*args|
63
+ result = original_method.bind(self).call(*args)
65
64
 
66
- if Warp::Instrument.for(self.class, __method__).enabled?
67
- Warp::Instrument.for(self.class, __method__).log([args, result])
68
- end
65
+ Warp::Instrument.for(self.class, __method__).log([args, result])
69
66
 
70
- return result
71
- end
72
-
73
- klass.prepend(hook)
74
- else
75
- original_method = klass.instance_method(method)
76
-
77
- klass.send(:define_method, method) do |*args|
78
- result = original_method.bind(self).call(*args)
79
-
80
- if Warp::Instrument.for(self.class, __method__).enabled?
81
- Warp::Instrument.for(self.class, __method__).log([args, result])
82
- end
83
-
84
- return result
85
- end
67
+ result
86
68
  end
87
69
  end
88
70
  end
89
- end
71
+ end
data/lib/warp/matcher.rb CHANGED
@@ -2,31 +2,6 @@ require "rspec"
2
2
 
3
3
  module Warp
4
4
  class Matcher
5
- # Composable matchers are new in RSpec 3.
6
- # Define basic helpers in their absence.
7
- if defined?(RSpec::Matchers::Composable)
8
- include RSpec::Matchers::Composable
9
- else
10
- def description_of(object)
11
- object.inspect
12
- end
13
-
14
- def values_match?(expected, actual)
15
- expected === actual || actual == expected
16
- end
17
- end
18
-
19
- # RSpec 2 and 3 have different methods
20
- # that they call on matcher to get the
21
- # failure messages.
22
- if RSpec::Version::STRING[0] == "2" || RSpec::Version::STRING == "3.0.0.beta1"
23
- def failure_message_for_should
24
- failure_message
25
- end
26
-
27
- def failure_message_for_should_not
28
- failure_message_when_negated
29
- end
30
- end
5
+ include RSpec::Matchers::Composable
31
6
  end
32
- end
7
+ end
data/lib/warp/version.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module Warp
2
2
  module VERSION
3
3
  MAJOR = 1
4
- MINOR = 3
5
- PATCH = 3
4
+ MINOR = 4
5
+ PATCH = 0
6
6
 
7
7
  BETA = nil
8
8
 
data/spec/spec_helper.rb CHANGED
@@ -8,17 +8,6 @@ unless ENV["TRAVIS_CI"]
8
8
  end
9
9
  end
10
10
 
11
- if ENV["TRAVIS_CI"]
12
- require "simplecov"
13
- require "coveralls"
14
-
15
- SimpleCov.formatter = Coveralls::SimpleCov::Formatter
16
-
17
- SimpleCov.start do
18
- add_filter "/spec/"
19
- end
20
- end
21
-
22
11
  if ENV["TRAVIS_CI"]
23
12
  Bundler.require
24
13
  else
@@ -9,7 +9,7 @@ describe Warp::ActionMatchers::CreateMatcher do
9
9
  end
10
10
  end
11
11
 
12
- before { Warp::Instrument.for(model, Warp::ActionMatchers::CreateMatcher.instrument_method).calls << Object.new }
12
+ before { Warp::Instrument.for(model, Warp::ActionMatchers::CreateMatcher.new(Object.new).send(:instrument_method)).calls << Object.new }
13
13
 
14
14
  subject { create(model) }
15
15
 
@@ -5,7 +5,7 @@ describe Warp::ActionMatchers::DestroyMatcher do
5
5
 
6
6
  let!(:instance) { model.create }
7
7
 
8
- before { Warp::Instrument.for(model, Warp::ActionMatchers::DestroyMatcher.instrument_method).calls << Object.new }
8
+ before { Warp::Instrument.for(model, Warp::ActionMatchers::DestroyMatcher.new(Object.new).send(:instrument_method)).calls << Object.new }
9
9
 
10
10
  subject { destroy(model) }
11
11
 
@@ -9,7 +9,7 @@ describe Warp::ActionMatchers::UpdateMatcher do
9
9
  end
10
10
  end
11
11
 
12
- before { Warp::Instrument.for(model, Warp::ActionMatchers::UpdateMatcher.instrument_method).calls << Object.new }
12
+ before { Warp::Instrument.for(model, Warp::ActionMatchers::UpdateMatcher.new(Object.new).send(:instrument_method)).calls << Object.new }
13
13
 
14
14
  let(:instance) { model.create(foo: "bar") }
15
15