mongoid-rspec 3.0.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE +1 -1
  3. data/README.md +217 -111
  4. data/Rakefile +8 -5
  5. data/lib/matchers/accept_nested_attributes.rb +22 -23
  6. data/lib/matchers/allow_mass_assignment.rb +12 -12
  7. data/lib/matchers/associations.rb +36 -37
  8. data/lib/matchers/be_dynamic_document.rb +26 -0
  9. data/lib/matchers/be_mongoid_document.rb +26 -0
  10. data/lib/matchers/be_stored_in.rb +55 -0
  11. data/lib/matchers/have_field.rb +90 -0
  12. data/lib/matchers/have_timestamps.rb +61 -0
  13. data/lib/matchers/indexes/have_index_for.rb +16 -0
  14. data/lib/matchers/indexes/v3/have_index_for.rb +59 -0
  15. data/lib/matchers/indexes/v4/have_index_for.rb +54 -0
  16. data/lib/matchers/validations.rb +30 -11
  17. data/lib/matchers/validations/associated.rb +1 -1
  18. data/lib/matchers/validations/confirmation_of.rb +0 -7
  19. data/lib/matchers/validations/custom_validation_of.rb +1 -4
  20. data/lib/matchers/validations/exclusion_of.rb +5 -5
  21. data/lib/matchers/validations/format_of.rb +2 -2
  22. data/lib/matchers/validations/inclusion_of.rb +5 -5
  23. data/lib/matchers/validations/length_of.rb +13 -35
  24. data/lib/matchers/validations/numericality_of.rb +32 -16
  25. data/lib/matchers/validations/presence_of.rb +1 -1
  26. data/lib/matchers/validations/uniqueness_of.rb +7 -10
  27. data/lib/mongoid/rspec.rb +17 -5
  28. data/lib/mongoid/rspec/version.rb +2 -2
  29. data/spec/models/article.rb +6 -6
  30. data/spec/models/comment.rb +1 -1
  31. data/spec/models/log.rb +3 -3
  32. data/spec/models/message.rb +11 -0
  33. data/spec/models/movie_article.rb +1 -2
  34. data/spec/models/person.rb +1 -1
  35. data/spec/models/profile.rb +2 -2
  36. data/spec/models/record.rb +1 -1
  37. data/spec/models/user.rb +11 -11
  38. data/spec/spec_helper.rb +9 -9
  39. data/spec/unit/accept_nested_attributes_spec.rb +1 -1
  40. data/spec/unit/associations_spec.rb +11 -7
  41. data/spec/unit/be_dynamic_document_spec.rb +21 -0
  42. data/spec/unit/be_mongoid_document_spec.rb +25 -0
  43. data/spec/unit/be_stored_in.rb +54 -0
  44. data/spec/unit/document_spec.rb +5 -14
  45. data/spec/unit/have_index_for_spec.rb +46 -0
  46. data/spec/unit/have_timestamps_spec.rb +71 -0
  47. data/spec/unit/validations_spec.rb +22 -15
  48. data/spec/validators/ssn_validator.rb +6 -6
  49. metadata +63 -29
  50. data/.document +0 -5
  51. data/.gitignore +0 -6
  52. data/.ruby-gemset +0 -1
  53. data/.ruby-version +0 -1
  54. data/.travis.yml +0 -10
  55. data/Gemfile +0 -4
  56. data/lib/matchers/collections.rb +0 -9
  57. data/lib/matchers/document.rb +0 -173
  58. data/lib/matchers/indexes.rb +0 -69
  59. data/lib/matchers/validations/with_message.rb +0 -27
  60. data/mongoid-rspec.gemspec +0 -26
  61. data/spec/unit/collections_spec.rb +0 -7
  62. data/spec/unit/indexes_spec.rb +0 -17
@@ -0,0 +1,16 @@
1
+ module Mongoid
2
+ module Matchers
3
+ class HaveIndexForBase
4
+ attr_reader :index_key, :index_options, :model
5
+
6
+ def initialize(index_key)
7
+ @index_key = index_key.symbolize_keys
8
+ end
9
+
10
+ def with_options(index_options = {})
11
+ @index_options = index_options
12
+ self
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,59 @@
1
+ module Mongoid
2
+ module Matchers
3
+ def have_index_for(index_key)
4
+ HaveIndexFor.new(index_key)
5
+ end
6
+
7
+ class HaveIndexFor < Mongoid::Matchers::HaveIndexForBase
8
+ def matches?(klass)
9
+ @model = klass.is_a?(Class) ? klass : klass.class
10
+ @errors = []
11
+
12
+ if model.index_options[index_key]
13
+ if !index_options.nil? && !index_options.empty?
14
+ index_options.each do |option, option_value|
15
+ if denormalising_options(model.index_options[index_key])[option] != option_value
16
+ @errors.push "index for #{index_key.inspect} with options of #{model.index_options[index_key].inspect}"
17
+ end
18
+ end
19
+ end
20
+ else
21
+ @errors.push "no index for #{index_key}"
22
+ end
23
+
24
+ @errors.empty?
25
+ end
26
+
27
+ def failure_message_for_should
28
+ "Expected #{model.inspect} to #{description}, got #{@errors.to_sentence}"
29
+ end
30
+
31
+ def failure_message_for_should_not
32
+ "Expected #{model.inspect} to not #{description}, got #{model.inspect} to #{description}"
33
+ end
34
+
35
+ alias failure_message failure_message_for_should
36
+ alias failure_message_when_negated failure_message_for_should_not
37
+
38
+ def description
39
+ desc = "have an index for #{index_key.inspect}"
40
+ desc << " with options of #{index_options.inspect}" if index_options
41
+ desc
42
+ end
43
+
44
+ private
45
+
46
+ MAPPINGS = {
47
+ dropDups: :drop_dups
48
+ }.freeze
49
+
50
+ def denormalising_options(opts)
51
+ options = {}
52
+ opts.each_pair do |option, value|
53
+ options[MAPPINGS[option] || option] = value
54
+ end
55
+ options
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,54 @@
1
+ module Mongoid
2
+ module Matchers
3
+ def have_index_for(index_key)
4
+ HaveIndexFor.new(index_key)
5
+ end
6
+
7
+ class HaveIndexFor < Mongoid::Matchers::HaveIndexForBase
8
+ def matches?(actual)
9
+ @model = actual.is_a?(Class) ? actual : actual.class
10
+
11
+ actual_index &&
12
+ expected_index.key == actual_index.key &&
13
+ expected_index.fields == actual_index.fields &&
14
+ (expected_index.options.to_a - actual_index.options.to_a).empty?
15
+ end
16
+
17
+ def failure_message
18
+ message = "Expected #{model.inspect} to #{description},"
19
+ message << if actual_index.nil?
20
+ ' found no index'
21
+ else
22
+ " got #{index_description(actual_index)}"
23
+ end
24
+ message
25
+ end
26
+
27
+ def failure_message_when_negated
28
+ "Expected #{model.inspect} to not #{description}, got #{index_description(actual_index)}"
29
+ end
30
+
31
+ def description
32
+ "have an index #{index_description(expected_index)}"
33
+ end
34
+
35
+ private
36
+
37
+ def index_description(index)
38
+ desc = index.key.inspect.to_s
39
+ desc << " for fields #{index.fields.inspect}" if index.fields.present?
40
+ desc << " including options #{index.options.inspect}" if index.options.present?
41
+ desc
42
+ end
43
+
44
+ def expected_index
45
+ @expected_index ||=
46
+ Mongoid::Indexable::Specification.new(model, index_key, index_options)
47
+ end
48
+
49
+ def actual_index
50
+ @actual_index ||= model.index_specification(expected_index.key)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -1,9 +1,7 @@
1
1
  module Mongoid
2
2
  module Matchers
3
3
  module Validations
4
-
5
4
  class HaveValidationMatcher
6
-
7
5
  def initialize(field, validation_type)
8
6
  @field = field.to_s
9
7
  @type = validation_type.to_s
@@ -13,9 +11,9 @@ module Mongoid
13
11
  def matches?(actual)
14
12
  @klass = actual.is_a?(Class) ? actual : actual.class
15
13
 
16
- @validator = @klass.validators_on(@field).detect{ |v|
17
- v.kind.to_s == @type and (!v.options[:on] or on_options_matches?(v))
18
- }
14
+ @validator = @klass.validators_on(@field).detect do |v|
15
+ (v.kind.to_s == @type) && (!v.options[:on] || on_options_matches?(v))
16
+ end
19
17
 
20
18
  if @validator
21
19
  @negative_result_message = "#{@type.inspect} validator on #{@field.inspect}"
@@ -26,6 +24,7 @@ module Mongoid
26
24
  end
27
25
  @result = true
28
26
  check_on if @options[:on]
27
+ check_expected_message if @expected_message
29
28
  @result
30
29
  end
31
30
 
@@ -37,12 +36,14 @@ module Mongoid
37
36
  "Expected #{@klass.inspect} to not #{description}; instead got #{@positive_result_message}"
38
37
  end
39
38
 
40
- alias :failure_message :failure_message_for_should
41
- alias :failure_message_when_negated :failure_message_for_should_not
39
+ alias failure_message failure_message_for_should
40
+ alias failure_message_when_negated failure_message_for_should_not
42
41
 
43
42
  def description
44
43
  desc = "have #{@type.inspect} validator on #{@field.inspect}"
45
44
  desc << " on #{@options[:on]}" if @options[:on]
45
+ desc << " with message #{@expected_message.inspect}" if @expected_message
46
+
46
47
  desc
47
48
  end
48
49
 
@@ -51,13 +52,20 @@ module Mongoid
51
52
  self
52
53
  end
53
54
 
55
+ def with_message(message)
56
+ @expected_message = message
57
+ self
58
+ end
59
+
60
+ private
61
+
54
62
  def check_on
55
63
  validator_on_methods = [@validator.options[:on]].flatten
56
64
 
57
65
  if validator_on_methods.any?
58
66
  message = " on methods: #{validator_on_methods}"
59
67
 
60
- if on_options_covered_by?( @validator )
68
+ if on_options_covered_by?(@validator)
61
69
  @positive_result_message << message
62
70
  else
63
71
  @negative_result_message << message
@@ -66,15 +74,26 @@ module Mongoid
66
74
  end
67
75
  end
68
76
 
69
- private
70
-
71
77
  def on_options_matches?(validator)
72
- @options[:on] and validator.options[:on] and on_options_covered_by?(validator)
78
+ @options[:on] && validator.options[:on] && on_options_covered_by?(validator)
73
79
  end
74
80
 
75
81
  def on_options_covered_by?(validator)
76
82
  ([@options[:on]].flatten - [validator.options[:on]].flatten).empty?
77
83
  end
84
+
85
+ def check_expected_message
86
+ actual_message = @validator.options[:message]
87
+ if actual_message.nil?
88
+ @negative_result_message << ' with no custom message'
89
+ @result = false
90
+ elsif actual_message == @expected_message
91
+ @positive_result_message << " with custom message '#{@expected_message}'"
92
+ else
93
+ @negative_result_message << " got message '#{actual_message}'"
94
+ @result = false
95
+ end
96
+ end
78
97
  end
79
98
  end
80
99
  end
@@ -16,4 +16,4 @@ module Mongoid
16
16
  end
17
17
  end
18
18
  end
19
- end
19
+ end
@@ -2,16 +2,9 @@ module Mongoid
2
2
  module Matchers
3
3
  module Validations
4
4
  class ValidateConfirmationOfMatcher < HaveValidationMatcher
5
- include WithMessage
6
-
7
5
  def initialize(name)
8
6
  super(name, :confirmation)
9
7
  end
10
-
11
- def with_message(message)
12
- @expected_message = message
13
- self
14
- end
15
8
  end
16
9
 
17
10
  def validate_confirmation_of(field)
@@ -2,7 +2,6 @@ module Mongoid
2
2
  module Matchers
3
3
  module Validations
4
4
  class ValidateWithCustomValidatorMatcher < HaveValidationMatcher
5
- include WithMessage
6
5
  def initialize(field)
7
6
  super(field, :custom)
8
7
  end
@@ -15,7 +14,6 @@ module Mongoid
15
14
  def matches?(actual)
16
15
  return false unless (@result = super(actual))
17
16
  check_custom_validator if @custom_validator
18
- check_expected_message if @expected_message
19
17
 
20
18
  @result
21
19
  end
@@ -23,14 +21,13 @@ module Mongoid
23
21
  def description
24
22
  options_desc = []
25
23
  options_desc << " with custom validator #{@custom_validator.name}" if @validator
26
- options_desc << " with message '#{@expected_message}'" if @expected_message
27
24
  "validate field #{@field.inspect}" << options_desc.to_sentence
28
25
  end
29
26
 
30
27
  private
31
28
 
32
29
  def check_custom_validator
33
- if @validator.kind_of? @custom_validator
30
+ if @validator.is_a? @custom_validator
34
31
  @positive_result_message << " with custom validator of type #{@custom_validator.name}"
35
32
  else
36
33
  @negative_result_message << " with custom validator not of type #{@custom_validator.name}"
@@ -18,13 +18,13 @@ module Mongoid
18
18
  raw_validator_not_allowed_values = @validator.options[:in]
19
19
 
20
20
  validator_not_allowed_values = case raw_validator_not_allowed_values
21
- when Range then raw_validator_not_allowed_values.to_a
22
- when Proc then raw_validator_not_allowed_values.call(actual)
23
- else raw_validator_not_allowed_values end
21
+ when Range then raw_validator_not_allowed_values.to_a
22
+ when Proc then raw_validator_not_allowed_values.call(actual)
23
+ else raw_validator_not_allowed_values end
24
24
 
25
25
  allowed_values = @not_allowed_values - validator_not_allowed_values
26
26
  if allowed_values.empty?
27
- @positive_result_message = @positive_result_message << " not allowing all values mentioned"
27
+ @positive_result_message = @positive_result_message << ' not allowing all values mentioned'
28
28
  else
29
29
  @negative_result_message = @negative_result_message << " allowing the following the ff. values: #{allowed_values.inspect}"
30
30
  result = false
@@ -46,4 +46,4 @@ module Mongoid
46
46
  end
47
47
  end
48
48
  end
49
- end
49
+ end
@@ -43,7 +43,7 @@ module Mongoid
43
43
  end
44
44
 
45
45
  if @invalid_value
46
- if !(@invalid_value =~ @validator.options[:with])
46
+ if @invalid_value !~ @validator.options[:with]
47
47
  @positive_result_message = @positive_result_message << " with #{@invalid_value.inspect} as an invalid value"
48
48
  else
49
49
  @negative_result_message = @negative_result_message << " with #{@invalid_value.inspect} as a valid value"
@@ -68,4 +68,4 @@ module Mongoid
68
68
  end
69
69
  end
70
70
  end
71
- end
71
+ end
@@ -18,13 +18,13 @@ module Mongoid
18
18
  raw_validator_allowed_values = @validator.options[:in]
19
19
 
20
20
  validator_allowed_values = case raw_validator_allowed_values
21
- when Range then raw_validator_allowed_values.to_a
22
- when Proc then raw_validator_allowed_values.call(actual)
23
- else raw_validator_allowed_values end
21
+ when Range then raw_validator_allowed_values.to_a
22
+ when Proc then raw_validator_allowed_values.call(actual)
23
+ else raw_validator_allowed_values end
24
24
 
25
25
  not_allowed_values = @allowed_values - validator_allowed_values
26
26
  if not_allowed_values.empty?
27
- @positive_result_message = @positive_result_message << " allowing all values mentioned"
27
+ @positive_result_message = @positive_result_message << ' allowing all values mentioned'
28
28
  else
29
29
  @negative_result_message = @negative_result_message << " not allowing these values: #{not_allowed_values.inspect}"
30
30
  result = false
@@ -46,4 +46,4 @@ module Mongoid
46
46
  end
47
47
  end
48
48
  end
49
- end
49
+ end
@@ -2,8 +2,6 @@ module Mongoid
2
2
  module Matchers
3
3
  module Validations
4
4
  class ValidateLengthOfMatcher < HaveValidationMatcher
5
- include WithMessage
6
-
7
5
  def initialize(name)
8
6
  super(name, :length)
9
7
  end
@@ -12,30 +10,25 @@ module Mongoid
12
10
  @maximum = value
13
11
  self
14
12
  end
15
- alias :less_than :with_maximum
13
+ alias less_than with_maximum
16
14
 
17
15
  def with_minimum(value)
18
16
  @minimum = value
19
17
  self
20
18
  end
21
- alias :greater_than :with_minimum
19
+ alias greater_than with_minimum
22
20
 
23
21
  def within(value)
24
22
  @within = value
25
23
  self
26
24
  end
27
- alias :in :within
25
+ alias in within
28
26
 
29
27
  def as_exactly(value)
30
28
  @is = value
31
29
  self
32
30
  end
33
- alias :is :as_exactly
34
-
35
- def with_message(message)
36
- @expected_message = message
37
- self
38
- end
31
+ alias is as_exactly
39
32
 
40
33
  def matches?(actual)
41
34
  return false unless @result = super(actual)
@@ -44,7 +37,6 @@ module Mongoid
44
37
  check_minimum if @minimum
45
38
  check_range if @within
46
39
  check_exact if @is
47
- check_expected_message if @expected_message
48
40
 
49
41
  @result
50
42
  end
@@ -55,7 +47,6 @@ module Mongoid
55
47
  options_desc << "with maximum of #{@maximum}" if @maximum
56
48
  options_desc << "within the range of #{@within}" if @within
57
49
  options_desc << "as exactly #{@is}" if @is
58
- options_desc << "with message '#{@expected_message}'" if @expected_message
59
50
  super << " #{options_desc.to_sentence}"
60
51
  end
61
52
 
@@ -63,7 +54,7 @@ module Mongoid
63
54
 
64
55
  def check_maximum
65
56
  if actual_max.nil?
66
- @negative_result_message << " with no maximum"
57
+ @negative_result_message << ' with no maximum'
67
58
  @result = false
68
59
  elsif actual_max == @maximum
69
60
  @positive_result_message << " with maximum of #{@maximum}"
@@ -75,7 +66,7 @@ module Mongoid
75
66
 
76
67
  def check_minimum
77
68
  if actual_min.nil?
78
- @negative_result_message << " with no minimum"
69
+ @negative_result_message << ' with no minimum'
79
70
  @result = false
80
71
  elsif actual_min == @minimum
81
72
  @positive_result_message << " with minimum of #{@minimum}"
@@ -86,15 +77,15 @@ module Mongoid
86
77
  end
87
78
 
88
79
  def check_range
89
- min, max = [@within.min, @within.max]
90
- if !actual_min.nil? and actual_max.nil?
80
+ min, max = @within.minmax
81
+ if !actual_min.nil? && actual_max.nil?
91
82
  @negative_result_message << " with no minimum but with maximum of #{actual_max}"
92
83
  @result = false
93
- elsif actual_min.nil? and !actual_max.nil?
84
+ elsif actual_min.nil? && !actual_max.nil?
94
85
  @negative_result_message << " with minimum_of #{actual_min} but no maximum"
95
86
  @result = false
96
- elsif actual_min.nil? and actual_max.nil?
97
- @negative_result_message << " with no minimum and maximum"
87
+ elsif actual_min.nil? && actual_max.nil?
88
+ @negative_result_message << ' with no minimum and maximum'
98
89
  @result = false
99
90
  elsif actual_min == min && actual_max == max
100
91
  @positive_result_message << " within the range of #{@within.inspect}"
@@ -113,29 +104,16 @@ module Mongoid
113
104
  end
114
105
  end
115
106
 
116
- def check_expected_message
117
- actual_message = @validator.options[:message]
118
- if actual_message.nil?
119
- @negative_result_message << " with no custom message"
120
- @result = false
121
- elsif actual_message == @expected_message
122
- @positive_result_message << " with custom message '#{@expected_message}'"
123
- else
124
- @negative_result_message << " got message '#{actual_message}'"
125
- @result = false
126
- end
127
- end
128
-
129
107
  def actual_is
130
108
  actual_is = @validator.options[:is]
131
109
  end
132
110
 
133
111
  def actual_min
134
- @validator.options[:minimum] || ((@validator.options[:in] || @validator.options[:within]).try(&:min))
112
+ @validator.options[:minimum] || (@validator.options[:in] || @validator.options[:within]).try(&:min)
135
113
  end
136
114
 
137
115
  def actual_max
138
- @validator.options[:maximum] || ((@validator.options[:in] || @validator.options[:within]).try(&:max))
116
+ @validator.options[:maximum] || (@validator.options[:in] || @validator.options[:within]).try(&:max)
139
117
  end
140
118
  end
141
119