minitest-activemodel 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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