minitest-activemodel 0.0.1 → 1.0.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 (35) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +9 -0
  3. data/CHANGELOG.md +14 -1
  4. data/Gemfile +4 -1
  5. data/Gemfile.edge +5 -0
  6. data/Gemfile.rails4 +6 -0
  7. data/README.md +6 -5
  8. data/Rakefile +2 -0
  9. data/lib/matchers/helpers.rb +15 -0
  10. data/lib/{minitest-activemodel/matchers → matchers}/validate_acceptance_matcher.rb +3 -1
  11. data/lib/matchers/validate_associated_matcher.rb +26 -0
  12. data/lib/{minitest-activemodel/matchers → matchers}/validate_confirmation_matcher.rb +0 -0
  13. data/lib/matchers/validate_exclusion_matcher.rb +55 -0
  14. data/lib/{minitest-activemodel/matchers → matchers}/validate_format_matcher.rb +3 -1
  15. data/lib/matchers/validate_inclusion_matcher.rb +55 -0
  16. data/lib/{minitest-activemodel/matchers → matchers}/validate_length_matcher.rb +2 -0
  17. data/lib/{minitest-activemodel/matchers → matchers}/validate_presence_matcher.rb +1 -1
  18. data/lib/matchers/validate_uniqueness_matcher.rb +80 -0
  19. data/lib/matchers/validation_matcher.rb +96 -0
  20. data/lib/minitest-activemodel.rb +11 -8
  21. data/minitest-activemodel.gemspec +11 -6
  22. data/test/ar_test_helper.rb +15 -0
  23. data/test/cases/validate_acceptance_matcher_test.rb +1 -0
  24. data/test/cases/validate_associated_matcher_test.rb +13 -0
  25. data/test/cases/validate_confirmation_matcher_test.rb +1 -0
  26. data/test/cases/validate_length_matcher_test.rb +1 -0
  27. data/test/cases/validate_presence_matcher_test.rb +1 -0
  28. data/test/cases/validate_uniqueness_matcher_test.rb +25 -0
  29. data/test/cases/{validation_test.rb → validation_matcher_test.rb} +26 -1
  30. data/test/models/person.rb +6 -0
  31. data/test/models/user.rb +1 -1
  32. data/test/test_helper.rb +1 -1
  33. metadata +74 -41
  34. data/lib/minitest-activemodel/matchers/validation_matcher.rb +0 -52
  35. data/lib/minitest-activemodel/version.rb +0 -7
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 76dd726673da7e51fdcde111e974872642fb051b
4
+ data.tar.gz: 6fe74deeab91df64ce8c394ce40a987d4ed5fcfc
5
+ SHA512:
6
+ metadata.gz: f3e15148818b68310e8cde9993a8310459f96e7447381d324a0fe963c15d6304ae23975277bf2fa96f378dbbf40f62a27ef7a4db38ad59319ab3890390e7c2b5
7
+ data.tar.gz: fb9b39a0f1a95857334f3a30c2d1c81b406c1c634e6632abe59da8aec1c081666a0f187d673113564c6524892d4dc219c78ee144bf9522d440e8d1f61643f8a5
@@ -1,3 +1,12 @@
1
1
  language: ruby
2
+ before_install:
3
+ - gem install bundler
2
4
  rvm:
3
5
  - 1.9.3
6
+ - 2.0.0
7
+ - ruby-head
8
+ - rbx-19mode
9
+ gemfile:
10
+ - Gemfile
11
+ - Gemfile.rails4
12
+ - Gemfile.edge
@@ -1,4 +1,17 @@
1
- # 0.0.1 - 10/13/12
1
+ # 1.0.0 - February 27, 2013
2
+
3
+ + Add `validate_exclusion_of` matcher.
4
+ + Add `validate_inclusion_of` matcher.
5
+ + Add `validate_associated` matcher.
6
+ + Add `with_message` option to all the matchers.
7
+ + Add `on` option to all the matchers.
8
+ + Add support for activerecord and activemodel 3.2.x, 4.0.0 and edge.
9
+ + Add support for Ruby 1.9.3, 2.0.0, ruby-head, rbx-19mode.
10
+ + Add `validate_uniqueness_of` matcher.
11
+ + Add `scoped_to` option to `validate_uniqueness_of` matcher.
12
+ + Add `case_insensitive` option to `validate_uniqueness_of` matcher.
13
+
14
+ # 0.0.1 - October 13, 2012
2
15
 
3
16
  + Add `validate_presence_of` matcher.
4
17
  + Add `validate_acceptance_of` matcher.
data/Gemfile CHANGED
@@ -1,3 +1,6 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
+
5
+ gem 'activemodel', '~> 3.2.0'
6
+ gem 'activerecord', '~> 3.2.0'
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'rails', github: 'rails/rails'
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'activemodel', '4.0.0.beta1'
6
+ gem 'activerecord', '4.0.0.beta1'
data/README.md CHANGED
@@ -2,15 +2,15 @@
2
2
 
3
3
  [![Build Status](https://secure.travis-ci.org/frodsan/minitest-activemodel.png?branch=master&.png)](http://travis-ci.org/frodsan/minitest-activemodel)
4
4
  [![Dependency Status](https://gemnasium.com/frodsan/minitest-activemodel.png)](https://gemnasium.com/frodsan/minitest-activemodel)
5
- [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/frodsan/minitest-activemodel)
5
+ [![Code Climate](https://codeclimate.com/github/frodsan/minitest-activemodel.png)](https://codeclimate.com/github/frodsan/minitest-activemodel)
6
6
 
7
- MiniTest matchers for ActiveModel::Validations.
7
+ MiniTest matchers for `ActiveModel::Validations`.
8
8
 
9
9
  ## Support
10
10
 
11
11
  This gem supports:
12
12
 
13
- + Ruby 1.9.3.
13
+ + Ruby 1.9.3, 2.0.0, ruby-head, rbx-19mode.
14
14
  + ActiveModel 3.2.x.
15
15
 
16
16
  ## Installation
@@ -29,7 +29,8 @@ Or install it yourself as:
29
29
 
30
30
  ## Usage
31
31
 
32
- TODO: In this section, it must appear the Official Documentation link.
32
+ Check the [official documentation](http://rubydoc.info/github/frodsan/minitest-activemodel/master/frames)
33
+ for more details.
33
34
 
34
35
  ## Contributing
35
36
 
@@ -37,5 +38,5 @@ Read [CONTRIBUTING](https://github.com/frodsan/minitest-activemodel/blob/master/
37
38
 
38
39
  ## License
39
40
 
40
- MIT License. Copyright 2012 Francesco Rodriguez. See [LICENSE](https://github.com/frodsan/minitest-activemodel/blob/master/LICENSE.md)
41
+ MIT License. Copyright 2012 Francesco Rodriguez. See [LICENSE.md](https://github.com/frodsan/minitest-activemodel/blob/master/LICENSE.md)
41
42
  for more information.
data/Rakefile CHANGED
@@ -5,6 +5,8 @@ require 'rake/testtask'
5
5
  Rake::TestTask.new do |task|
6
6
  task.libs << 'test'
7
7
  task.pattern = 'test/**/*_test.rb'
8
+ task.warning = true
9
+ task.verbose = true
8
10
  end
9
11
 
10
12
  task default: :test
@@ -0,0 +1,15 @@
1
+ module MiniTest
2
+ module Matchers
3
+ module ActiveModel
4
+ module Helpers # :nodoc:
5
+ def to_sentence ary
6
+ ary.collect(&:inspect).to_sentence
7
+ end
8
+
9
+ def class_of subject
10
+ subject.is_a?(Class) ? subject : subject.class
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,7 +1,7 @@
1
1
  module MiniTest
2
2
  module Matchers
3
3
  module ActiveModel
4
- # Ensures that the model is not valid if the given attribute is not accepted.
4
+ # Ensures that the model is invalid if the given attribute is not accepted.
5
5
  #
6
6
  # Options:
7
7
  # * <tt>accept_with</tt> - value that is considered accepted.
@@ -16,6 +16,8 @@ module MiniTest
16
16
 
17
17
  class ValidateAcceptanceMatcher < ValidationMatcher
18
18
  def initialize attr
19
+ @accepted = nil
20
+
19
21
  super attr, :acceptance
20
22
  end
21
23
 
@@ -0,0 +1,26 @@
1
+ module MiniTest
2
+ module Matchers
3
+ module ActiveModel
4
+ # Ensures that the model is invalid if the given
5
+ # association name is not valid itself.
6
+ #
7
+ # it { must validate_associated(:parent) }
8
+ # it { must validate_associated(:children) }
9
+ def validate_associated association_name
10
+ ValidateAssociated.new association_name
11
+ end
12
+
13
+ private
14
+
15
+ class ValidateAssociated < ValidationMatcher
16
+ def initialize association_name
17
+ super association_name, :associated
18
+ end
19
+
20
+ def description
21
+ "validate associated #{@attr.inspect}"
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,55 @@
1
+ module MiniTest
2
+ module Matchers
3
+ module ActiveModel
4
+ # TODO: Add documentation
5
+ def validate_exclusion_of attr
6
+ ValidateExclusionMatcher.new attr
7
+ end
8
+
9
+ private
10
+
11
+ class ValidateExclusionMatcher < ValidationMatcher
12
+ def initialize attr
13
+ super attr, :exclusion
14
+ end
15
+
16
+ def to_not_allow *values
17
+ @not_allowed_values = (values.length > 1) ? values.flatten : values[0]
18
+ self
19
+ end
20
+
21
+ def matches? subject
22
+ return false unless result = super(subject)
23
+
24
+ if Array === @not_allowed_values
25
+ allowed_values = @not_allowed_values - @validator.options[:in].to_a
26
+ if allowed_values.empty?
27
+ @positive_message << ' not allowing all values mentioned'
28
+ else
29
+ @negative_message << ' allowing the values:'
30
+ @negative_message << " #{to_sentence(allowed_values)}"
31
+ result = false
32
+ end
33
+ elsif @not_allowed_values
34
+ if @not_allowed_values == @validator.options[:in]
35
+ @positive_message << " not allowing values in #{@not_allowed_values.inspect}"
36
+ else
37
+ @negative_message << " not allowing values in #{@validator.options[:in].inspect}"
38
+ result = false
39
+ end
40
+ end
41
+
42
+ result
43
+ end
44
+
45
+ def description
46
+ if Array === @not_allowed_values
47
+ super << " not allowing the values: #{to_sentence(@not_allowed_values)}"
48
+ elsif @not_allowed_values
49
+ super << " not allowing the values in #{@not_allowed_values.inspect}"
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,7 +1,7 @@
1
1
  module MiniTest
2
2
  module Matchers
3
3
  module ActiveModel
4
- # Ensures that the model is not valid if the given attribute is not
4
+ # Ensures that the model is invalid if the given attribute is not
5
5
  # formatted correctly.
6
6
  #
7
7
  # Options:
@@ -18,6 +18,8 @@ module MiniTest
18
18
 
19
19
  class ValidateFormatMatcher < ValidationMatcher
20
20
  def initialize attr
21
+ @valid, @invalid = nil
22
+
21
23
  super attr, :format
22
24
  end
23
25
 
@@ -0,0 +1,55 @@
1
+ module MiniTest
2
+ module Matchers
3
+ module ActiveModel
4
+ # TODO: Add documentation.
5
+ def validate_inclusion_of attr
6
+ ValidateInclusionMatcher.new attr
7
+ end
8
+
9
+ private
10
+
11
+ class ValidateInclusionMatcher < ValidationMatcher
12
+ def initialize attr
13
+ super attr, :inclusion
14
+ end
15
+
16
+ def to_allow *values
17
+ @allowed_values = (values.length > 1) ? values.flatten : values[0]
18
+ self
19
+ end
20
+
21
+ def matches? subject
22
+ return false unless result = super(subject)
23
+
24
+ if Array === @allowed_values
25
+ not_allowed_values = @allowed_values - @validator.options[:in].to_a
26
+ if not_allowed_values.empty?
27
+ @positive_message << ' allowing all values mentioned'
28
+ else
29
+ @negative_message << ' not allowing the following the values:'
30
+ @negative_message << " #{not_allowed_values.inspect}"
31
+ result = false
32
+ end
33
+ elsif @allowed_values
34
+ if @allowed_values == @validator.options[:in]
35
+ @positive_message << " allowing values in #{@allowed_values.inspect}"
36
+ else
37
+ @negative_message << " allowing values in #{@validator.options[:in].inspect}"
38
+ result = false
39
+ end
40
+ end
41
+
42
+ result
43
+ end
44
+
45
+ def description
46
+ if Array === @allowed_values
47
+ super << " allowing the values: #{to_sentence(@allowed_values)}"
48
+ elsif @allowed_values
49
+ super << " allowing the values in #{@allowed_values.inspect}"
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -47,6 +47,8 @@ module MiniTest
47
47
 
48
48
  class ValidateLengthMatcher < ValidationMatcher
49
49
  def initialize attr
50
+ @minimum, @maximum, @within, @is = nil
51
+
50
52
  super attr, :length
51
53
  end
52
54
 
@@ -1,7 +1,7 @@
1
1
  module MiniTest
2
2
  module Matchers
3
3
  module ActiveModel
4
- # Ensures that the model is not valid if the given attribute is not present.
4
+ # Ensures that the model is invalid if the given attribute is not present.
5
5
  #
6
6
  # it { must validate_presence_of(:name) }
7
7
  def validate_presence_of attr
@@ -0,0 +1,80 @@
1
+ module MiniTest
2
+ module Matchers
3
+ module ActiveModel
4
+ # Ensures that the model is invalid if the given attribute is not unique.
5
+ #
6
+ # Options:
7
+ # * <tt>scoped_to</tt> - field(s) to scope the uniqueness to.
8
+ # * <tt>case_insensitive</tt> - ensures that the validation doesn't
9
+ # check case. Off by default. Ignored by non-text attributes.
10
+ #
11
+ # it { must validate_uniqueness_of(:email) }
12
+ # it { must validate_uniqueness_of(:email).scoped_to(:name) }
13
+ # it { must validate_uniqueness_of(:email).scoped_to(:first_name, :last_name) }
14
+ # it { must validate_uniqueness_of(:keyword).case_insensitive }
15
+ def validate_uniqueness_of attr
16
+ ValidateUniquenessMatcher.new attr
17
+ end
18
+
19
+ private
20
+
21
+ class ValidateUniquenessMatcher < ValidationMatcher
22
+ def initialize attr
23
+ @scope = nil
24
+ @case_insensitive = false
25
+
26
+ super attr, :uniqueness
27
+ end
28
+
29
+ def scoped_to *scope
30
+ @scope = [scope].flatten.map(&:to_s)
31
+ self
32
+ end
33
+
34
+ def case_insensitive
35
+ @case_insensitive = true
36
+ self
37
+ end
38
+
39
+ def matches? subject
40
+ return false unless @result = super(subject)
41
+
42
+ check_scope if @scope
43
+ check_case_sensivity if @case_insensitive
44
+
45
+ @result
46
+ end
47
+
48
+ def description
49
+ desc = []
50
+ desc << " scoped to #{to_sentence(@scope)}" if @scope
51
+ desc << ' allowing case insensitive values' if @case_insensitive
52
+ super << desc.to_sentence
53
+ end
54
+
55
+ private
56
+
57
+ def check_scope
58
+ actual_scope = [@validator.options[:scope]].flatten.map(&:to_s)
59
+ message = " scoped to #{to_sentence(actual_scope)}"
60
+
61
+ if actual_scope == @scope
62
+ @positive_message << message
63
+ else
64
+ @negative_message << message
65
+ @result = false
66
+ end
67
+ end
68
+
69
+ def check_case_sensivity
70
+ if @validator.options[:case_sensitive] == false
71
+ @positive_message << ' with case insensitive values'
72
+ else
73
+ @negative_message << ' without case insensitive values'
74
+ @result = false
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,96 @@
1
+ module MiniTest
2
+ module Matchers
3
+ module ActiveModel
4
+ class ValidationMatcher # :nodoc:
5
+ include Helpers
6
+
7
+ def initialize attr, type
8
+ @attr = attr
9
+ @type = type
10
+ @expected_on = @expected_message = nil
11
+ end
12
+
13
+ # TODO: Add documentation.
14
+ def on *contexts
15
+ @expected_on = clean_contexts contexts
16
+ self
17
+ end
18
+
19
+ # TODO: Add documentation.
20
+ def with_message expected_message
21
+ @expected_message = expected_message
22
+ self
23
+ end
24
+
25
+ def matches? subject
26
+ @klass = subject.is_a?(Class) ? subject : subject.class
27
+ @validator = @klass.validators_on(@attr).find { |v| v.kind == @type }
28
+ @result = true
29
+
30
+ check_validator
31
+ check_on if @expected_on
32
+ check_message if @expected_message
33
+
34
+ @result
35
+ end
36
+
37
+ def failure_message
38
+ "Expected #{@klass} to #{description}; instead got #{@negative_message}"
39
+ end
40
+
41
+ def negative_failure_message
42
+ "Expected #{@klass} to not #{description}; instead got #{@positive_message}"
43
+ end
44
+
45
+ def description
46
+ "validate #{@type} of #{@attr}"
47
+ end
48
+
49
+ private
50
+
51
+ def check_validator
52
+ if @validator
53
+ @positive_message = "#{@type} validator for #{@attr}"
54
+ @negative_message = "#{@type} validator for #{@attr}"
55
+ else
56
+ @negative_message = "no #{@type} validator for #{@attr}"
57
+ @result = false
58
+ end
59
+ end
60
+
61
+ def check_on
62
+ on = clean_contexts @validator.options[:on]
63
+
64
+ if on.sort == @expected_on.sort
65
+ @positive_message << " on #{on.empty? ? 'all actions' : to_sentence(on)}"
66
+ else
67
+ @negative_message << " on #{on.empty? ? 'all actions' : to_sentence(on)}"
68
+ @result = false
69
+ end
70
+ end
71
+
72
+ def check_message
73
+ error_message = @validator.options[:message]
74
+
75
+ if @expected_message == error_message
76
+ @positive_message << " with message: #{error_message.inspect}"
77
+ else
78
+ @negative_message << " with message: #{error_message.inspect}"
79
+ @result = false
80
+ end
81
+ end
82
+
83
+ def clean_contexts contexts
84
+ [contexts].flatten.compact.reject { |ctx| ctx == :save }
85
+ end
86
+
87
+ # TODO: Document this helper method.
88
+ def validate_invalid_options! *options
89
+ if options.all?(&:nil?)
90
+ raise ArgumentError, 'You have to supply an option for this matcher'
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -1,9 +1,12 @@
1
- require 'minitest-activemodel/version'
2
-
3
1
  require 'minitest/matchers'
4
- require 'minitest-activemodel/matchers/validation_matcher.rb'
5
- require 'minitest-activemodel/matchers/validate_acceptance_matcher'
6
- require 'minitest-activemodel/matchers/validate_confirmation_matcher'
7
- require 'minitest-activemodel/matchers/validate_format_matcher'
8
- require 'minitest-activemodel/matchers/validate_length_matcher'
9
- require 'minitest-activemodel/matchers/validate_presence_matcher'
2
+ require 'matchers/helpers'
3
+ require 'matchers/validation_matcher'
4
+ require 'matchers/validate_acceptance_matcher'
5
+ require 'matchers/validate_associated_matcher'
6
+ require 'matchers/validate_confirmation_matcher'
7
+ require 'matchers/validate_exclusion_matcher'
8
+ require 'matchers/validate_format_matcher'
9
+ require 'matchers/validate_inclusion_matcher'
10
+ require 'matchers/validate_length_matcher'
11
+ require 'matchers/validate_presence_matcher'
12
+ require 'matchers/validate_uniqueness_matcher'
@@ -1,15 +1,15 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require File.expand_path '../lib/minitest-activemodel/version', __FILE__
3
2
 
4
3
  Gem::Specification.new do |gem|
5
4
  gem.name = 'minitest-activemodel'
6
- gem.version = MiniTest::Matchers::ActiveModel::VERSION
5
+ gem.version = '1.0.0'
7
6
 
8
7
  gem.authors = ['Francesco Rodriguez']
9
8
  gem.email = ['lrodriguezsanc@gmail.com']
10
- gem.description = %q{MiniTest Matchers for ActiveModel::Validations}
9
+ gem.description = %q{MiniTest matchers for ActiveModel::Validations}
11
10
  gem.summary = gem.description
12
11
  gem.homepage = 'https://github.com/frodsan/minitest-activemodel'
12
+ gem.licenses = ['MIT']
13
13
 
14
14
  gem.files = `git ls-files`.split "\n"
15
15
  gem.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename f }
@@ -18,8 +18,13 @@ Gem::Specification.new do |gem|
18
18
  gem.rdoc_options = ['--charset=UTF-8']
19
19
  gem.require_paths = ['lib']
20
20
 
21
- gem.add_dependency 'minitest', '>= 4.0.0'
22
- gem.add_dependency 'minitest-matchers', '~> 1.2.0'
23
- gem.add_dependency 'activemodel', '~> 3.2.0'
21
+ gem.required_ruby_version = '>= 1.9.3'
22
+
23
+ gem.add_dependency 'minitest', '~> 4.1'
24
+ gem.add_dependency 'minitest-matchers', '~> 1.2'
25
+ gem.add_dependency 'activemodel', '>= 3.2'
26
+
27
+ gem.add_development_dependency 'activerecord', '>= 3.2'
28
+ gem.add_development_dependency 'sqlite3', '~> 1.3.6'
24
29
  gem.add_development_dependency 'rake'
25
30
  end
@@ -0,0 +1,15 @@
1
+ require 'active_record'
2
+ require 'sqlite3'
3
+
4
+ ActiveRecord::Base.establish_connection(
5
+ adapter: 'sqlite3',
6
+ database: ':memory:'
7
+ )
8
+
9
+ ActiveRecord::Migration.verbose = false
10
+
11
+ ActiveRecord::Schema.define do
12
+ create_table :people do |t|
13
+ t.string :email
14
+ end
15
+ end
@@ -1,4 +1,5 @@
1
1
  require 'test_helper'
2
+ require 'models/user'
2
3
 
3
4
  class ValidateAcceptanceTest < MiniTest::Unit::TestCase
4
5
  test 'must validate acceptance of an attribute' do
@@ -0,0 +1,13 @@
1
+ require 'test_helper'
2
+ require 'ar_test_helper'
3
+ require 'models/person'
4
+
5
+ class ValidateAssociatedMatcherTest < MiniTest::Unit::TestCase
6
+ test 'must validate exists association' do
7
+ assert_must validate_associated(:posts), Person
8
+ end
9
+
10
+ test 'must not validate exists association' do
11
+ assert_wont validate_associated(:parent), Person
12
+ end
13
+ end
@@ -1,4 +1,5 @@
1
1
  require 'test_helper'
2
+ require 'models/user'
2
3
 
3
4
  class ValidateConfirmationMatcherTest < MiniTest::Unit::TestCase
4
5
  test 'must validate confirmation of an attribute' do
@@ -1,4 +1,5 @@
1
1
  require 'test_helper'
2
+ require 'models/user'
2
3
 
3
4
  class ValidateLengthMatcher < MiniTest::Unit::TestCase
4
5
  test 'raises ArgumentError when no option is given' do
@@ -1,4 +1,5 @@
1
1
  require 'test_helper'
2
+ require 'models/user'
2
3
 
3
4
  class ValidatePresenceMatcherTest < MiniTest::Unit::TestCase
4
5
  test 'must validate presence of a required attribute' do
@@ -0,0 +1,25 @@
1
+ require 'test_helper'
2
+ require 'ar_test_helper'
3
+ require 'models/person'
4
+
5
+ class ValidateUniquenessMatcherTest < MiniTest::Unit::TestCase
6
+ test 'must validate uniqueness of an attribute' do
7
+ assert_must validate_uniqueness_of(:email), Person
8
+ end
9
+
10
+ test 'must not validate uniqueness of an attribute' do
11
+ assert_wont validate_uniqueness_of(:not_unique), Person
12
+ end
13
+
14
+ test 'must validate scope of an unique attribute' do
15
+ assert_must validate_uniqueness_of(:email).scoped_to(:site), Person
16
+ end
17
+
18
+ test 'must not validate scope of an unique attribute' do
19
+ assert_wont validate_uniqueness_of(:email).scoped_to(:none), Person
20
+ end
21
+
22
+ test 'must validate uniqueness validation does not check case' do
23
+ assert_must validate_uniqueness_of(:email).case_insensitive, Person
24
+ end
25
+ end
@@ -33,11 +33,36 @@ class ValidationMatcherTest < MiniTest::Unit::TestCase
33
33
  assert_match 'type validator for attr', @validator.negative_failure_message
34
34
  end
35
35
 
36
+ test 'returns true if validation type exists with on option' do
37
+ subject = create_subject :attr, :type, on: [ :create ]
38
+
39
+ assert @validator.on(:create).matches? subject
40
+ end
41
+
42
+ test 'returns false if validation type not exists with on option' do
43
+ subject = create_subject :attr, :type, on: [ :create ]
44
+
45
+ assert !@validator.on(:update).matches?(subject)
46
+ end
47
+
48
+ test 'returns true if validation type exists with with_message option' do
49
+ subject = create_subject :attr, :type, message: 'error'
50
+
51
+ assert @validator.with_message('error').matches? subject
52
+ end
53
+
54
+ test 'returns false if validation type not exists with with_message option' do
55
+ subject = create_subject :attr, :type, message: 'different error'
56
+
57
+ assert !@validator.with_message('error').matches?(subject)
58
+ end
59
+
36
60
  private
37
61
 
38
- def create_subject attr, type
62
+ def create_subject attr, type, options={}
39
63
  arg = MiniTest::Mock.new
40
64
  arg.expect :kind, type
65
+ arg.expect :options, options
41
66
 
42
67
  subject = MiniTest::Mock.new
43
68
  subject.expect :is_a?, true, [Class]
@@ -0,0 +1,6 @@
1
+ class Person < ActiveRecord::Base
2
+ has_many :posts
3
+
4
+ validates_uniqueness_of :email, scope: :site, case_sensitive: false
5
+ validates_associated :posts
6
+ end
@@ -8,7 +8,7 @@ class User
8
8
 
9
9
  validates_confirmation_of :password
10
10
 
11
- validates_format_of :email, with: /^([^\s]+)((?:[-a-z0-9]\.)[a-z]{2,})$/i
11
+ validates_format_of :email, with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/
12
12
 
13
13
  validates_length_of :name, minimum: 10, maximum: 100
14
14
  validates_length_of :password, is: 8
@@ -1,7 +1,7 @@
1
+ require 'bundler/setup'
1
2
  require 'minitest/autorun'
2
3
  require 'active_support/testing/declarative'
3
4
  require 'minitest-activemodel'
4
- require 'models/user'
5
5
 
6
6
  class MiniTest::Unit::TestCase
7
7
  include MiniTest::Matchers::ActiveModel
metadata CHANGED
@@ -1,81 +1,100 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minitest-activemodel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
5
- prerelease:
4
+ version: 1.0.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Francesco Rodriguez
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-10-13 00:00:00.000000000 Z
11
+ date: 2013-02-27 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: minitest
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ~>
20
18
  - !ruby/object:Gem::Version
21
- version: 4.0.0
19
+ version: '4.1'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ~>
28
25
  - !ruby/object:Gem::Version
29
- version: 4.0.0
26
+ version: '4.1'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: minitest-matchers
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ~>
36
32
  - !ruby/object:Gem::Version
37
- version: 1.2.0
33
+ version: '1.2'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ~>
44
39
  - !ruby/object:Gem::Version
45
- version: 1.2.0
40
+ version: '1.2'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: activemodel
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ~>
45
+ - - '>='
52
46
  - !ruby/object:Gem::Version
53
- version: 3.2.0
47
+ version: '3.2'
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '3.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activerecord
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '3.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '3.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: sqlite3
71
+ requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - ~>
60
74
  - !ruby/object:Gem::Version
61
- version: 3.2.0
75
+ version: 1.3.6
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: 1.3.6
62
83
  - !ruby/object:Gem::Dependency
63
84
  name: rake
64
85
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
86
  requirements:
67
- - - ! '>='
87
+ - - '>='
68
88
  - !ruby/object:Gem::Version
69
89
  version: '0'
70
90
  type: :development
71
91
  prerelease: false
72
92
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
93
  requirements:
75
- - - ! '>='
94
+ - - '>='
76
95
  - !ruby/object:Gem::Version
77
96
  version: '0'
78
- description: MiniTest Matchers for ActiveModel::Validations
97
+ description: MiniTest matchers for ActiveModel::Validations
79
98
  email:
80
99
  - lrodriguezsanc@gmail.com
81
100
  executables: []
@@ -90,57 +109,71 @@ files:
90
109
  - CHANGELOG.md
91
110
  - CONTRIBUTING.md
92
111
  - Gemfile
112
+ - Gemfile.edge
113
+ - Gemfile.rails4
93
114
  - LICENSE.md
94
115
  - README.md
95
116
  - Rakefile
117
+ - lib/matchers/helpers.rb
118
+ - lib/matchers/validate_acceptance_matcher.rb
119
+ - lib/matchers/validate_associated_matcher.rb
120
+ - lib/matchers/validate_confirmation_matcher.rb
121
+ - lib/matchers/validate_exclusion_matcher.rb
122
+ - lib/matchers/validate_format_matcher.rb
123
+ - lib/matchers/validate_inclusion_matcher.rb
124
+ - lib/matchers/validate_length_matcher.rb
125
+ - lib/matchers/validate_presence_matcher.rb
126
+ - lib/matchers/validate_uniqueness_matcher.rb
127
+ - lib/matchers/validation_matcher.rb
96
128
  - lib/minitest-activemodel.rb
97
- - lib/minitest-activemodel/matchers/validate_acceptance_matcher.rb
98
- - lib/minitest-activemodel/matchers/validate_confirmation_matcher.rb
99
- - lib/minitest-activemodel/matchers/validate_format_matcher.rb
100
- - lib/minitest-activemodel/matchers/validate_length_matcher.rb
101
- - lib/minitest-activemodel/matchers/validate_presence_matcher.rb
102
- - lib/minitest-activemodel/matchers/validation_matcher.rb
103
- - lib/minitest-activemodel/version.rb
104
129
  - minitest-activemodel.gemspec
130
+ - test/ar_test_helper.rb
105
131
  - test/cases/validate_acceptance_matcher_test.rb
132
+ - test/cases/validate_associated_matcher_test.rb
106
133
  - test/cases/validate_confirmation_matcher_test.rb
107
134
  - test/cases/validate_format_matcher_test.rb
108
135
  - test/cases/validate_length_matcher_test.rb
109
136
  - test/cases/validate_presence_matcher_test.rb
110
- - test/cases/validation_test.rb
137
+ - test/cases/validate_uniqueness_matcher_test.rb
138
+ - test/cases/validation_matcher_test.rb
139
+ - test/models/person.rb
111
140
  - test/models/user.rb
112
141
  - test/test_helper.rb
113
142
  homepage: https://github.com/frodsan/minitest-activemodel
114
- licenses: []
143
+ licenses:
144
+ - MIT
145
+ metadata: {}
115
146
  post_install_message:
116
147
  rdoc_options:
117
148
  - --charset=UTF-8
118
149
  require_paths:
119
150
  - lib
120
151
  required_ruby_version: !ruby/object:Gem::Requirement
121
- none: false
122
152
  requirements:
123
- - - ! '>='
153
+ - - '>='
124
154
  - !ruby/object:Gem::Version
125
- version: '0'
155
+ version: 1.9.3
126
156
  required_rubygems_version: !ruby/object:Gem::Requirement
127
- none: false
128
157
  requirements:
129
- - - ! '>='
158
+ - - '>='
130
159
  - !ruby/object:Gem::Version
131
160
  version: '0'
132
161
  requirements: []
133
162
  rubyforge_project:
134
- rubygems_version: 1.8.23
163
+ rubygems_version: 2.0.0
135
164
  signing_key:
136
- specification_version: 3
137
- summary: MiniTest Matchers for ActiveModel::Validations
165
+ specification_version: 4
166
+ summary: MiniTest matchers for ActiveModel::Validations
138
167
  test_files:
168
+ - test/ar_test_helper.rb
139
169
  - test/cases/validate_acceptance_matcher_test.rb
170
+ - test/cases/validate_associated_matcher_test.rb
140
171
  - test/cases/validate_confirmation_matcher_test.rb
141
172
  - test/cases/validate_format_matcher_test.rb
142
173
  - test/cases/validate_length_matcher_test.rb
143
174
  - test/cases/validate_presence_matcher_test.rb
144
- - test/cases/validation_test.rb
175
+ - test/cases/validate_uniqueness_matcher_test.rb
176
+ - test/cases/validation_matcher_test.rb
177
+ - test/models/person.rb
145
178
  - test/models/user.rb
146
179
  - test/test_helper.rb
@@ -1,52 +0,0 @@
1
- module MiniTest
2
- module Matchers
3
- module ActiveModel
4
- class ValidationMatcher # :nodoc:
5
- def initialize attr, type
6
- @attr = attr
7
- @type = type
8
- end
9
-
10
- def matches? subject
11
- @klass = subject.is_a?(Class) ? subject : subject.class
12
- @validator = @klass.validators_on(@attr).find { |v| v.kind == @type }
13
- @result = true
14
-
15
- check_validator
16
-
17
- @result
18
- end
19
-
20
- def failure_message
21
- "Expected #{@klass} to #{description}; instead got #{@negative_message}"
22
- end
23
-
24
- def negative_failure_message
25
- "Expected #{@klass} to not #{description}; instead got #{@positive_message}"
26
- end
27
-
28
- def description
29
- "validate #{@type} of #{@attr}"
30
- end
31
-
32
- private
33
-
34
- def check_validator
35
- if @validator
36
- @positive_message = "#{@type} validator for #{@attr}"
37
- @negative_message = "#{@type} validator for #{@attr}"
38
- else
39
- @negative_message = "no #{@type} validator for #{@attr}"
40
- @result = false
41
- end
42
- end
43
-
44
- def validate_invalid_options! *options
45
- if options.all? &:nil?
46
- raise ArgumentError, 'You have to supply an option for this matcher'
47
- end
48
- end
49
- end
50
- end
51
- end
52
- end
@@ -1,7 +0,0 @@
1
- module MiniTest
2
- module Matchers
3
- module ActiveModel
4
- VERSION = '0.0.1'
5
- end
6
- end
7
- end