riot-rails 0.0.10.pre.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/{test/rails_root/app/views/rendered_templates/foo_bar.html.erb → README.md} +0 -0
- data/Rakefile +10 -32
- data/VERSION +1 -1
- data/init.rb +0 -0
- data/install.rb +0 -0
- data/lib/generators/riot_rails.rb +10 -0
- data/lib/generators/riot_rails/model/model_generator.rb +22 -0
- data/lib/generators/riot_rails/model/templates/fixtures.yml +23 -0
- data/lib/generators/riot_rails/model/templates/riot_test.rb +5 -0
- metadata +26 -155
- data/.gitignore +0 -4
- data/CHANGELOG +0 -144
- data/MIT-LICENSE +0 -20
- data/README.markdown +0 -31
- data/lib/riot/action_controller.rb +0 -4
- data/lib/riot/action_controller/context_macros/asserts_response.rb +0 -15
- data/lib/riot/action_controller/context_middleware.rb +0 -45
- data/lib/riot/action_controller/http_methods.rb +0 -19
- data/lib/riot/active_record.rb +0 -4
- data/lib/riot/active_record/assertion_macros.rb +0 -3
- data/lib/riot/active_record/context_middleware.rb +0 -15
- data/lib/riot/active_record/database_macros.rb +0 -58
- data/lib/riot/active_record/reflection_macros.rb +0 -106
- data/lib/riot/active_record/transactional_middleware.rb +0 -21
- data/lib/riot/active_record/validation_macros.rb +0 -187
- data/lib/riot/rails.rb +0 -1
- data/rails/init.rb +0 -1
- data/riot-rails.gemspec +0 -130
- data/test/action_controller/context_macros/asserts_response_test.rb +0 -35
- data/test/action_controller/context_middleware_test.rb +0 -66
- data/test/action_controller/delete_request_test.rb +0 -45
- data/test/action_controller/get_request_test.rb +0 -37
- data/test/action_controller/post_request_test.rb +0 -45
- data/test/action_controller/put_request_test.rb +0 -45
- data/test/action_controller/restful_delete_request_test.rb +0 -28
- data/test/action_controller/restful_get_request_test.rb +0 -25
- data/test/action_controller/restful_post_request_test.rb +0 -25
- data/test/action_controller/restful_put_request_test.rb +0 -28
- data/test/active_record/allowing_values_test.rb +0 -64
- data/test/active_record/attribute_is_invalid_test.rb +0 -20
- data/test/active_record/belongs_to_test.rb +0 -22
- data/test/active_record/context_middleware_test.rb +0 -18
- data/test/active_record/has_and_belongs_to_many_test.rb +0 -22
- data/test/active_record/has_database_index_on_test.rb +0 -73
- data/test/active_record/has_many_test.rb +0 -22
- data/test/active_record/has_one_test.rb +0 -22
- data/test/active_record/validates_length_of_test.rb +0 -31
- data/test/active_record/validates_presence_of_test.rb +0 -14
- data/test/active_record/validates_uniqueness_of_test.rb +0 -23
- data/test/rails_root/app/controllers/gremlins_controller.rb +0 -21
- data/test/rails_root/app/controllers/parties_controller.rb +0 -17
- data/test/rails_root/app/controllers/rooms_controller.rb +0 -22
- data/test/rails_root/config/database.yml +0 -4
- data/test/rails_root/config/environment.rb +0 -46
- data/test/rails_root/config/routes.rb +0 -7
- data/test/rails_root/db/schema.rb +0 -8
- data/test/teststrap.rb +0 -84
- data/test/transactional_middleware_test.rb +0 -26
data/MIT-LICENSE
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
Copyright (c) 2009 Justin Knowlden, Thumble Monks
|
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.
|
data/README.markdown
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
# Riot Rails
|
2
|
-
|
3
|
-
[Riot](http://github.com/thumblemonks/riot) macros for Rails application testing.
|
4
|
-
|
5
|
-
LOTS more to come ...
|
6
|
-
|
7
|
-
## Installation
|
8
|
-
|
9
|
-
We're a gem! Install per the normal course of installing gems.
|
10
|
-
|
11
|
-
gem install riot_rails
|
12
|
-
|
13
|
-
## Usage
|
14
|
-
|
15
|
-
Tons of documentation to come. Try looking at the [RDoc](http://rdoc.info/projects/thumblemonks/riot_rails) for now. As a note, you will likely put this in your `teststrap.rb` or `test_helper.rb`:
|
16
|
-
|
17
|
-
require 'riot/rails'
|
18
|
-
|
19
|
-
### ActiveRecord
|
20
|
-
|
21
|
-
Awesome stuff in the works. Doc coming soon.
|
22
|
-
|
23
|
-
### ActionController
|
24
|
-
|
25
|
-
Awesome stuff in the works. Doc coming soon.
|
26
|
-
|
27
|
-
### ActionMailer
|
28
|
-
|
29
|
-
Awesome stuff coming soon. See [Shoulda Action Mailer](http://github.com/thumblemonks/shoulda_action_mailer) - which is also by us - in the meantime.
|
30
|
-
|
31
|
-
I told you we liked Shoulda.
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module RiotRails
|
2
|
-
module ActionController
|
3
|
-
module AssertsResponse
|
4
|
-
|
5
|
-
def asserts_response(method_name=nil)
|
6
|
-
if method_name
|
7
|
-
asserts("response ##{method_name.to_s}") { response.send(method_name) }
|
8
|
-
else
|
9
|
-
asserts("response") { response }
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
end # AssertsResponse
|
14
|
-
end # ActionController
|
15
|
-
end # RiotRails
|
@@ -1,45 +0,0 @@
|
|
1
|
-
module RiotRails
|
2
|
-
class ActionControllerMiddleware < Riot::ContextMiddleware
|
3
|
-
register
|
4
|
-
|
5
|
-
def handle?(context)
|
6
|
-
description = context.description
|
7
|
-
description.kind_of?(Class) && description.ancestors.include?(::ActionController::Base)
|
8
|
-
end # handle?
|
9
|
-
|
10
|
-
def call(context)
|
11
|
-
setup_context_macros(context)
|
12
|
-
setup_situation(context)
|
13
|
-
end
|
14
|
-
private
|
15
|
-
def setup_context_macros(context)
|
16
|
-
context.class_eval do
|
17
|
-
include RiotRails::ActionController::AssertsResponse
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def setup_situation(context)
|
22
|
-
context.helper(:app) { @app }
|
23
|
-
context.helper(:env) { @env }
|
24
|
-
context.helper(:controller) { env["action_controller.instance"] }
|
25
|
-
|
26
|
-
context.helper(:request) do
|
27
|
-
return controller.request if controller
|
28
|
-
raise Exception, "No request made yet"
|
29
|
-
end
|
30
|
-
|
31
|
-
context.helper(:response) do
|
32
|
-
return controller.response if controller
|
33
|
-
raise Exception, "No response since no request made yet"
|
34
|
-
end
|
35
|
-
|
36
|
-
context.setup(true) do
|
37
|
-
self.class_eval { include RiotRails::ActionController::HttpMethods }
|
38
|
-
@app = ::Rails.application
|
39
|
-
http_reset
|
40
|
-
context.description
|
41
|
-
end # context.setup(true)
|
42
|
-
end # call
|
43
|
-
|
44
|
-
end # ActionControllerMiddleware
|
45
|
-
end # RiotRails
|
@@ -1,19 +0,0 @@
|
|
1
|
-
module RiotRails
|
2
|
-
module ActionController
|
3
|
-
module HttpMethods
|
4
|
-
def http_reset; @env = {}; end
|
5
|
-
def get(uri, params={}) perform_request("GET", uri, params); end
|
6
|
-
def post(uri, params={}) perform_request("POST", uri, params); end
|
7
|
-
def put(uri, params={}); perform_request("PUT", uri, params); end
|
8
|
-
def delete(uri, params={}); perform_request("DELETE", uri, params); end
|
9
|
-
private
|
10
|
-
def perform_request(request_method, uri, params)
|
11
|
-
http_reset
|
12
|
-
params = params.inject({}) { |acc,(key,val)| acc[key] = val.to_s; acc }
|
13
|
-
@env = ::Rack::MockRequest.env_for(uri, {:params => params, :method => request_method}).merge(@env)
|
14
|
-
@env['action_dispatch.show_exceptions'] = false
|
15
|
-
@app.call(@env)
|
16
|
-
end
|
17
|
-
end # HttpMethods
|
18
|
-
end # ActionController
|
19
|
-
end # RiotRails
|
data/lib/riot/active_record.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
module RiotRails
|
2
|
-
class ActiveRecordMiddleware < Riot::ContextMiddleware
|
3
|
-
register
|
4
|
-
|
5
|
-
def handle?(context)
|
6
|
-
description = context.description
|
7
|
-
description.kind_of?(Class) && description.ancestors.include?(::ActiveRecord::Base)
|
8
|
-
end
|
9
|
-
|
10
|
-
def call(context)
|
11
|
-
context.setup(true) { context.description.new }
|
12
|
-
end
|
13
|
-
|
14
|
-
end # ActiveRecordMiddleware
|
15
|
-
end # RiotRails
|
@@ -1,58 +0,0 @@
|
|
1
|
-
module RiotRails
|
2
|
-
module ActiveRecord
|
3
|
-
|
4
|
-
# An ActiveRecord assertion macro that looks for an index on a given set of attributes in the table
|
5
|
-
# used by the model under test (aka: topic).
|
6
|
-
#
|
7
|
-
# asserts_topic.has_database_index_on :name
|
8
|
-
# asserts_topic.has_database_index_on :email, :group_name
|
9
|
-
#
|
10
|
-
# In the form used above, the assertion will pass if any index is found with the attributes listed
|
11
|
-
# (unique or not). To be specific about uniqueness, provide the +:unique+ option.
|
12
|
-
#
|
13
|
-
# asserts_topic.has_database_index_on :email, :unique => true
|
14
|
-
# asserts_topic.has_database_index_on :name, :unique => false
|
15
|
-
#
|
16
|
-
# The last example will require that the index not be a unique one.
|
17
|
-
class HasDatabaseIndexOnMacro < Riot::AssertionMacro
|
18
|
-
register :has_database_index_on
|
19
|
-
|
20
|
-
def initialize(database_connection=nil) # Good for testing :)
|
21
|
-
@database_connection = database_connection
|
22
|
-
end
|
23
|
-
|
24
|
-
def evaluate(actual, *attributes_and_options)
|
25
|
-
attributes, options = extract_options_from(attributes_and_options)
|
26
|
-
unique = options[:unique]
|
27
|
-
|
28
|
-
index = find_index(actual, attributes, unique)
|
29
|
-
|
30
|
-
static_message = "#{unique ? "unique" : ""} index on #{attributes.inspect}".strip
|
31
|
-
index.nil? ? fail("expected #{static_message}") : pass("has #{static_message}")
|
32
|
-
end
|
33
|
-
private
|
34
|
-
def database_connection; @database_connection || ::ActiveRecord::Base.connection; end
|
35
|
-
|
36
|
-
def find_index(model, attributes, uniqueness, &block)
|
37
|
-
database_connection.indexes(model.class.table_name).find do |the_index|
|
38
|
-
unique_enough?(uniqueness, the_index) && attributes_match?(attributes, the_index)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def unique_enough?(uniqueness, index)
|
43
|
-
return true if uniqueness.nil?
|
44
|
-
index.unique == uniqueness
|
45
|
-
end
|
46
|
-
|
47
|
-
def attributes_match?(attributes, index)
|
48
|
-
Set.new(attributes.map(&:to_s)) == Set.new(index.columns)
|
49
|
-
end
|
50
|
-
|
51
|
-
def extract_options_from(attributes)
|
52
|
-
options = attributes.last.kind_of?(Hash) ? attributes.pop : {}
|
53
|
-
[attributes, options]
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
end # ActiveRecord
|
58
|
-
end # RiotRails
|
@@ -1,106 +0,0 @@
|
|
1
|
-
module RiotRails
|
2
|
-
module ActiveRecord
|
3
|
-
protected
|
4
|
-
|
5
|
-
class ReflectionAssertionMacro < Riot::AssertionMacro
|
6
|
-
private
|
7
|
-
def reflection_match?(expected, reflection)
|
8
|
-
!reflection.nil? && (expected == reflection.macro.to_s)
|
9
|
-
end
|
10
|
-
|
11
|
-
def options_match_for_reflection?(reflection, options)
|
12
|
-
options.all? { |k, v| reflection.options[k] == v }
|
13
|
-
end
|
14
|
-
|
15
|
-
def assert_reflection(expected, record, attribute, options=nil)
|
16
|
-
options ||= {}
|
17
|
-
reflection = record.class.reflect_on_association(attribute)
|
18
|
-
if reflection_match?(expected, reflection)
|
19
|
-
if options_match_for_reflection?(reflection, options)
|
20
|
-
pass new_message(attribute).is_a.push(expected).association
|
21
|
-
else
|
22
|
-
fail expected_message.push("#{expected} #{attribute.inspect}").with(options)
|
23
|
-
end
|
24
|
-
else
|
25
|
-
fail new_message(attribute).is_not_a.push(expected).association
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
public
|
31
|
-
|
32
|
-
# An ActiveRecord assertion macro that expects to pass when a given attribute is defined as a +has_many+
|
33
|
-
# association. Will fail if an association is not defined for the attribute or if the association is
|
34
|
-
# not +has_many+.
|
35
|
-
#
|
36
|
-
# context "a Room" do
|
37
|
-
# setup { Room.new }
|
38
|
-
#
|
39
|
-
# asserts_topic.has_many(:doors)
|
40
|
-
# asserts_topic.has_many(:floors) # should probably fail given our current universe :)
|
41
|
-
# end
|
42
|
-
class HasManyMacro < ReflectionAssertionMacro
|
43
|
-
register :has_many
|
44
|
-
|
45
|
-
def evaluate(actual, *expectings)
|
46
|
-
attribute, options = *expectings
|
47
|
-
assert_reflection("has_many", actual, attribute, options)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
# An ActiveRecord assertion macro that expects to pass when a given attribute is defined as a
|
52
|
-
# +has_one+ association. Will fail if an association is not defined for the attribute or if the
|
53
|
-
# association is not +has_one+.
|
54
|
-
#
|
55
|
-
# context "a Room" do
|
56
|
-
# setup { Room.new }
|
57
|
-
#
|
58
|
-
# asserts_topic.has_one(:floor)
|
59
|
-
# end
|
60
|
-
class HasOneMacro < ReflectionAssertionMacro
|
61
|
-
register :has_one
|
62
|
-
|
63
|
-
def evaluate(actual, *expectings)
|
64
|
-
attribute, options = *expectings
|
65
|
-
assert_reflection("has_one", actual, attribute, options)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
# An ActiveRecord assertion macro that expects to pass when a given attribute is defined as a
|
70
|
-
# +belongs_to+ association. Will fail if an association is not defined for the attribute or if the
|
71
|
-
# association is not +belongs_to+.
|
72
|
-
#
|
73
|
-
# context "a Room" do
|
74
|
-
# setup { Room.new }
|
75
|
-
#
|
76
|
-
# asserts_topic.belongs_to(:house)
|
77
|
-
# end
|
78
|
-
class BelongsToMacro < ReflectionAssertionMacro
|
79
|
-
register :belongs_to
|
80
|
-
|
81
|
-
def evaluate(actual, *expectings)
|
82
|
-
attribute, options = *expectings
|
83
|
-
assert_reflection("belongs_to", actual, attribute, options)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
# An ActiveRecord assertion macro that expects to pass when a given attribute is defined as a
|
88
|
-
# +has_and_belongs_to_many+ association. Will fail if an association is not defined for the attribute or
|
89
|
-
# if the association is not +has_and_belongs_to_many+.
|
90
|
-
#
|
91
|
-
# context "a Room" do
|
92
|
-
# setup { Room.new }
|
93
|
-
#
|
94
|
-
# asserts_topic.has_and_belongs_to_many(:walls)
|
95
|
-
# end
|
96
|
-
class HasAndBelongsToManyMacro < ReflectionAssertionMacro
|
97
|
-
register :has_and_belongs_to_many
|
98
|
-
|
99
|
-
def evaluate(actual, *expectings)
|
100
|
-
attribute, options = *expectings
|
101
|
-
assert_reflection("has_and_belongs_to_many", actual, attribute, options)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
end # ActiveRecord
|
106
|
-
end # RiotRails
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module RiotRails
|
2
|
-
class TransactionalMiddleware < Riot::ContextMiddleware
|
3
|
-
register
|
4
|
-
|
5
|
-
def handle?(context)
|
6
|
-
context.option(:transactional) == true
|
7
|
-
end
|
8
|
-
|
9
|
-
def call(context)
|
10
|
-
context.class.class_eval do
|
11
|
-
alias_method :transactionless_local_run, :local_run
|
12
|
-
def local_run(*args)
|
13
|
-
::ActiveRecord::Base.transaction do
|
14
|
-
transactionless_local_run(*args)
|
15
|
-
raise ::ActiveRecord::Rollback
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end # RiotRails
|
@@ -1,187 +0,0 @@
|
|
1
|
-
module RiotRails
|
2
|
-
module ActiveRecord
|
3
|
-
protected
|
4
|
-
|
5
|
-
class ValidationAssertionMacro < Riot::AssertionMacro
|
6
|
-
private
|
7
|
-
def errors_from_writing_value(model, attribute, value)
|
8
|
-
# TODO: Fix me to not use __send__
|
9
|
-
model.__send__(:write_attribute, attribute, value)
|
10
|
-
model.valid?
|
11
|
-
model.errors[attribute]
|
12
|
-
end
|
13
|
-
|
14
|
-
def errors_from_writing_value?(*args)
|
15
|
-
errors_from_writing_value(*args).any?
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
public
|
20
|
-
|
21
|
-
# An ActiveRecord assertion that expects to pass with a given value or set of values for a given
|
22
|
-
# attribute.
|
23
|
-
#
|
24
|
-
# rails_context User do
|
25
|
-
# asserts_topic.allows_values_for :email, "a@b.cd"
|
26
|
-
# asserts_topic.allows_values_for :email, "a@b.cd", "e@f.gh"
|
27
|
-
# end
|
28
|
-
class AllowsValuesForMacro < ValidationAssertionMacro
|
29
|
-
register :allows_values_for
|
30
|
-
|
31
|
-
def evaluate(actual, attribute, *values)
|
32
|
-
bad_values = []
|
33
|
-
values.each do |value|
|
34
|
-
bad_values << value if errors_from_writing_value?(actual, attribute, value)
|
35
|
-
end
|
36
|
-
bad_values.empty? ? pass : fail(expected_message(attribute).to_allow_values(bad_values))
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
# An ActiveRecord assertion that expects to fail with a given value or set of values for a given
|
41
|
-
# attribute.
|
42
|
-
#
|
43
|
-
# rails_context User do
|
44
|
-
# asserts_topic.does_not_allow_values_for :email, "a"
|
45
|
-
# asserts_topic.does_not_allow_values_for :email, "a@b", "e f@g.h"
|
46
|
-
# end
|
47
|
-
class DoesNotAllowValuesForMacro < ValidationAssertionMacro
|
48
|
-
register :does_not_allow_values_for
|
49
|
-
def evaluate(actual, attribute, *values)
|
50
|
-
good_values = []
|
51
|
-
values.each do |value|
|
52
|
-
good_values << value unless errors_from_writing_value?(actual, attribute, value)
|
53
|
-
end
|
54
|
-
good_values.empty? ? pass : fail(expected_message(attribute).not_to_allow_values(good_values))
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
# An ActiveRecord assertion that expects to fail with invalid value for an attribute. Optionally, the
|
59
|
-
# error message can be provided as the exact string or as regular expression.
|
60
|
-
#
|
61
|
-
# rails_context User do
|
62
|
-
# asserts_topic.is_invalid_when :email, "fake", "is invalid"
|
63
|
-
# asserts_topic.is_invalid_when :email, "another fake", /invalid/
|
64
|
-
# end
|
65
|
-
class IsInvalidWhenMacro < ValidationAssertionMacro
|
66
|
-
register :is_invalid_when
|
67
|
-
|
68
|
-
def evaluate(actual, attribute, value, expected_error=nil)
|
69
|
-
actual_errors = errors_from_writing_value(actual, attribute, value)
|
70
|
-
if actual_errors.empty?
|
71
|
-
fail expected_message(attribute).to_be_invalid_when_value_is(value)
|
72
|
-
elsif expected_error && !has_error_message?(expected_error, actual_errors)
|
73
|
-
fail expected_message(attribute).to_be_invalid_with_error_message(expected_error)
|
74
|
-
else
|
75
|
-
pass new_message.attribute(attribute).is_invalid
|
76
|
-
end
|
77
|
-
end
|
78
|
-
private
|
79
|
-
def has_error_message?(expected, errors)
|
80
|
-
return true unless expected
|
81
|
-
expected.kind_of?(Regexp) ? errors.any? {|e| e =~ expected } : errors.any? {|e| e == expected }
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
# An ActiveRecord assertion that expects to fail when a given attribute is validated after a nil value
|
86
|
-
# is provided to it.
|
87
|
-
#
|
88
|
-
# rails_context User do
|
89
|
-
# asserts_topic.validates_presence_of(:name)
|
90
|
-
# end
|
91
|
-
class ValidatesPresenceOfMacro < ValidationAssertionMacro
|
92
|
-
register :validates_presence_of
|
93
|
-
|
94
|
-
def evaluate(actual, attribute)
|
95
|
-
if errors_from_writing_value?(actual, attribute, nil)
|
96
|
-
pass new_message.validates_presence_of(attribute)
|
97
|
-
else
|
98
|
-
fail expected_message.to_validate_presence_of(attribute)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
# An ActiveRecord assertion that expects to fail with an attribute is not valid for record because the
|
104
|
-
# value of the attribute is not unique. Requires the topic of the context to be a created record; one
|
105
|
-
# that returns false for a call to +new_record?+.
|
106
|
-
#
|
107
|
-
# rails_context User do
|
108
|
-
# setup { User.create(:email => "a@b.cde", ... ) }
|
109
|
-
# asserts_topic.validates_uniqueness_of :email
|
110
|
-
# end
|
111
|
-
class ValidatesUniquenessOfMacro < ValidationAssertionMacro
|
112
|
-
register :validates_uniqueness_of
|
113
|
-
|
114
|
-
def evaluate(actual, attribute)
|
115
|
-
actual_record = actual
|
116
|
-
if actual_record.new_record?
|
117
|
-
fail new_message.must_use_a_persisted_record_when_testing_uniqueness_of(attribute)
|
118
|
-
else
|
119
|
-
copied_model = actual_record.class.new
|
120
|
-
actual_record.attributes.each do |dup_attribute, dup_value|
|
121
|
-
copied_model.__send__(:write_attribute, dup_attribute, dup_value)
|
122
|
-
end
|
123
|
-
copied_value = actual_record.__send__(:read_attribute, attribute)
|
124
|
-
if errors_from_writing_value?(copied_model, attribute, copied_value)
|
125
|
-
pass new_message(attribute).is_unique
|
126
|
-
else
|
127
|
-
fail expected_message.to_fail_because(attribute).is_not_unique
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
# An ActiveRecord assertion to test that the length of the value of an attribute must be within a
|
134
|
-
# specified range. Assertion fails if: there are errors when min/max characters are used, there are no
|
135
|
-
# errors when min-1/max+1 characters are used.
|
136
|
-
#
|
137
|
-
# rails_context User do
|
138
|
-
# asserts_topic.validates_length_of :name, (2..36)
|
139
|
-
# end
|
140
|
-
#
|
141
|
-
# TODO: allow for options on what to validate
|
142
|
-
class ValidatesLengthOfMacro < ValidationAssertionMacro
|
143
|
-
register :validates_length_of
|
144
|
-
|
145
|
-
def evaluate(actual, attribute, range)
|
146
|
-
min, max = range.first, range.last
|
147
|
-
[min, max].each do |length|
|
148
|
-
if errors_from_writing_value?(actual, attribute, "r" * length)
|
149
|
-
return fail(new_message(attribute).should_be_able_to_be(length).characters)
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
if (min-1) > 0 && !errors_from_writing_value?(actual, attribute, "r" * (min-1))
|
154
|
-
fail new_message(attribute).expected_to_be_more_than(min - 1).characters
|
155
|
-
elsif !errors_from_writing_value?(actual, attribute, "r" * (max+1))
|
156
|
-
fail new_message(attribute).expected_to_be_less_than(max + 1).characters
|
157
|
-
else
|
158
|
-
pass new_message.validates_length_of(attribute).is_within(range)
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
# An ActiveRecord assertion to test that an attribute is invalid along with the expected error message
|
164
|
-
# (or error message partial). The assumption is that a value has already been set.
|
165
|
-
#
|
166
|
-
# rails_context User do
|
167
|
-
# hookup { topic.bio = "I'm a goofy clown" }
|
168
|
-
# asserts_topic.attribute_is_invalid :bio, "cannot contain adjectives"
|
169
|
-
# end
|
170
|
-
class AttributeIsInvalidMacro < ValidationAssertionMacro
|
171
|
-
register :attribute_is_invalid
|
172
|
-
|
173
|
-
def evaluate(actual, attribute, error_message)
|
174
|
-
actual.valid?
|
175
|
-
errors = actual.errors[attribute]
|
176
|
-
if errors.empty?
|
177
|
-
fail new_message(attribute).expected_to_be_invalid
|
178
|
-
elsif errors.include?(error_message)
|
179
|
-
pass new_message(attribute).is_invalid
|
180
|
-
else
|
181
|
-
fail new_message(attribute).is_invalid.but(error_message).is_not_a_valid_error_message
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
end # ActiveRecord
|
187
|
-
end # RiotRails
|