rspec-rails-assign 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Samuel Cochran
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,47 @@
1
+ # RSpec Rails Assign
2
+
3
+ ## Motivation
4
+
5
+ This is ugly:
6
+
7
+ ```ruby
8
+ subject { get :show }
9
+ specify { subject and assigns[:blah].should be_present }
10
+ specify { subject and assigns[:blah].should == "something" }
11
+ specify { subject and assigns[:blah].should =~ /thi/ }
12
+ specify { subject and assigns[:blah].should be_a String }
13
+ ```
14
+
15
+ Instead:
16
+
17
+ ```ruby
18
+ subject { get :show }
19
+ it { should assign :blah }
20
+ it { should assign :blah => "something" }
21
+ it { should assign :blah => /thi/ }
22
+ it { should assign :blah => is_a(String) }
23
+ ```
24
+
25
+ It's more like a subject modifier, a la `its`, but inline and allowing nicely described specs:
26
+
27
+ ```
28
+ MyController
29
+ #show
30
+ should assign @blah
31
+ should assign @blah == "something"
32
+ should assign @blah =~ /thi/
33
+ should assign @blah to be a kind of String
34
+ ```
35
+
36
+ And presents nice diffs when it fails:
37
+
38
+ ```
39
+ 1) MyController#show assign @blah to == "something"
40
+ Failure/Error: it { should assign :blah => "something" }
41
+ expected: "something"
42
+ got: "other" (using ==)
43
+ ```
44
+
45
+ ## License
46
+
47
+ The MIT License, see [LICENSE][license].
@@ -0,0 +1,4 @@
1
+ require 'rspec/rails'
2
+ require 'rspec/rails/matchers/assign'
3
+
4
+ RSpec::Rails::ControllerExampleGroup.send :include, RSpec::Rails::Matchers::Assign
@@ -0,0 +1,136 @@
1
+ require 'spec_helper'
2
+
3
+ module RSpec::Rails::Matchers::Assign
4
+ private
5
+
6
+ # +nodoc+
7
+ class AssignMatcher
8
+ attr_accessor :actual, :operator, :expected
9
+
10
+ def initialize scope, name, expected=nil
11
+ @scope = scope
12
+ @actual = nil
13
+
14
+ if name.is_a? Hash
15
+ raise ArgumentError, "must test at least one assignment" unless name.size
16
+ raise ArgumentError, "can only test one assign at a time" if name.size > 1
17
+
18
+ @name, expected = name.first
19
+ else
20
+ @name = name
21
+ end
22
+
23
+ @expected = [expected]
24
+ @operator = nil
25
+ end
26
+
27
+ def description
28
+ if @expected.first.nil?
29
+ "assign @#{@name}"
30
+ elsif @expected.first.respond_to? :matches?
31
+ "assign @#{@name} to #{@expected.first.description}"
32
+ else
33
+ "assign @#{@name} #{@operator} #{@expected.first.inspect}"
34
+ end
35
+ end
36
+
37
+ def failure_message_for_should
38
+ if @expected.first.nil?
39
+ "expected to assign @#{@name}"
40
+ elsif ['==','===', '=~'].include?(operator)
41
+ "expected: #{expected.first.inspect}\n got: #{actual.inspect} (using #{operator})"
42
+ elsif @expected.first.respond_to? :matches?
43
+ "expected: #{actual.inspect} to #{@expected.first.description}"
44
+ else
45
+ "expected: #{operator} #{expected.first.inspect}\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}"
46
+ end
47
+ end
48
+
49
+ def failure_message_for_should_not
50
+ if @expected.first.nil?
51
+ "expected not to assign @#{@name}"
52
+ elsif @expected.first.respond_to? :matches?
53
+ "expected: #{actual.inspect} to not #{@expected.first.description}"
54
+ else
55
+ "expected not: #{operator} #{expected.first.inspect}\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}"
56
+ end
57
+ end
58
+
59
+ def diffable?
60
+ not (@expected.first.is_a?(Regexp) or @expected.first.respond_to? :matches?)
61
+ end
62
+
63
+ def matches? actual
64
+ @actual = actual.assigns[@name]
65
+
66
+ if @expected.first.nil?
67
+ @actual.present?
68
+ elsif @operator
69
+ @actual.send @operator, @expected.first
70
+ elsif @expected.first.is_a? Regexp
71
+ @operator = "=~"
72
+ @actual =~ @expected.first
73
+ elsif @expected.first.respond_to? :matches?
74
+ @expected.first.matches? @actual
75
+ else
76
+ @operator = "=="
77
+ @actual == @expected.first
78
+ end
79
+ end
80
+
81
+ ['==', '===', '=~', '>', '>=', '<', '<='].each do |operator|
82
+ define_method operator do |expected|
83
+ raise ArgumentError, "can't use expected value and an opertator" if @expected.present?
84
+ @operator = operator
85
+ @expected = [expected]
86
+ self
87
+ end
88
+ end
89
+ end
90
+
91
+ # +nodoc+
92
+ class AssignMetaMatcher
93
+ def initialize scope, name, matcher
94
+ @scope = scope
95
+ @name = name
96
+ @matcher = matcher
97
+ end
98
+
99
+ def matches? actual
100
+ @actual = actual.assigns[@name]
101
+ @matcher.matches? @actual
102
+ end
103
+
104
+ def description
105
+ "assign @#{@name} to #{@matcher.description}"
106
+ end
107
+
108
+ def method_missing name, *args, &block
109
+ @matcher.send name, *args, &block
110
+ end
111
+ end
112
+
113
+ public
114
+
115
+ # Lets you write:
116
+ #
117
+ # subject { get :show }
118
+ # it { should assign(:blah) }
119
+ # it { should assign(:blah =>"something") }
120
+ #
121
+ # or, more interestingly:
122
+ #
123
+ # it { should assign(:blah) == "something" }
124
+ # it { should assign(:blah => is_a(String)) }
125
+ # it { should assign(:blah => satisfy { |value| Thing.exists? :blah => value }) }
126
+ #
127
+ def assign *args, &block
128
+ AssignMatcher.new self, *args, &block
129
+ end
130
+
131
+ def method_missing(method, *args, &block)
132
+ # Allow infinitive forms of `be_<predicate>` matchers.
133
+ return ::RSpec::Matchers::BePredicate.new(method.to_s.sub("is", "be"), *args, &block) if method.to_s =~ /\Ais_(.*)\Z/
134
+ super
135
+ end
136
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rspec-rails-assign
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Samuel Cochran
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec-rails
16
+ requirement: &70284572197740 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70284572197740
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &70284572197280 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 2.7.0
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70284572197280
36
+ description: A subject-oriented way to match assignments in controller examples.
37
+ email:
38
+ - sj26@sj26.com
39
+ executables: []
40
+ extensions: []
41
+ extra_rdoc_files: []
42
+ files:
43
+ - lib/rspec/rails/matchers/assign.rb
44
+ - lib/rspec-rails-assign.rb
45
+ - README.md
46
+ - LICENSE
47
+ homepage: http://github.com/sj26/rspec-rails-assign
48
+ licenses: []
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: 1.3.6
65
+ requirements: []
66
+ rubyforge_project:
67
+ rubygems_version: 1.8.11
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: RSpec Rails assign matcher
71
+ test_files: []
72
+ has_rdoc: