beyond_the_api_test_helpers 0.0.1

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.
@@ -0,0 +1,80 @@
1
+ module Shoulda
2
+ module Matchers
3
+ module ActiveModel
4
+ def have_model_translations(options = {})
5
+ HaveModelTranslationsMatcher.new(options)
6
+ end
7
+
8
+ # @private
9
+ class HaveModelTranslationsMatcher
10
+ def initialize(options = {})
11
+ @options = options
12
+ end
13
+
14
+ def matches?(subject)
15
+ @subject = subject
16
+ matches_model_name? && matches_attributes?
17
+ end
18
+
19
+ def matches_model_name?
20
+ I18n.available_locales.each do |locale|
21
+ I18n.locale = locale
22
+ return false unless model_name.human == I18n.t("#{i18n_path}.one")
23
+ return false unless model_name.human(count: 2) == I18n.t("#{i18n_path}.other")
24
+ end
25
+ end
26
+
27
+ def matches_attributes?
28
+ attributes = @options[:attributes]
29
+ return true unless attributes
30
+ attributes.each do |attribute|
31
+ return false unless assert_translated_attribute(attribute)
32
+ end
33
+ true
34
+ end
35
+
36
+ def assert_translated_attribute(attribute)
37
+ begin
38
+ translated_attr = I18n.t('activerecord.attributes.' \
39
+ "#{model_class.to_s.underscore}.#{attribute}")
40
+ rescue
41
+ translated_attr = I18n.t("attributes.#{attribute}")
42
+ end
43
+ model_class.human_attribute_name(attribute) == translated_attr
44
+ end
45
+
46
+ def failure_message
47
+ "Expected #{expectation} (#{@missing})"
48
+ end
49
+ alias failure_message_for_should failure_message
50
+
51
+ def failure_message_when_negated
52
+ "Did not expect #{expectation}"
53
+ end
54
+ alias failure_message_for_should_not failure_message_when_negated
55
+
56
+ def description
57
+ 'have model translations'
58
+ end
59
+
60
+ private
61
+
62
+ def expectation
63
+ "#{model_class.name} to #{description}"
64
+ end
65
+
66
+ def model_class
67
+ @subject.class
68
+ end
69
+
70
+ def model_name
71
+ model_class.model_name
72
+ end
73
+
74
+ def i18n_path
75
+ "activerecord.models.#{model_class.name.underscore}"
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,51 @@
1
+ module Shoulda
2
+ module Matchers
3
+ module ActiveRecord
4
+ def have_valid_association(association)
5
+ HaveValidAssociationMatcher.new(association)
6
+ end
7
+
8
+ # @private
9
+ class HaveValidAssociationMatcher
10
+ def initialize(association)
11
+ @association = association
12
+ @options = {}
13
+ end
14
+
15
+ def matches?(subject)
16
+ @subject = subject
17
+
18
+ @expected_message ||= :required
19
+
20
+ @subject.send("#{@association}_id=", 999_967)
21
+ @subject.valid?
22
+ @subject.errors[@association].include? I18n.t("errors.messages.#{@expected_message}")
23
+ end
24
+
25
+ def failure_message
26
+ "Expected #{expectation} (#{@missing})"
27
+ end
28
+ alias failure_message_for_should failure_message
29
+
30
+ def failure_message_when_negated
31
+ "Did not expect #{expectation}"
32
+ end
33
+ alias failure_message_for_should_not failure_message_when_negated
34
+
35
+ def description
36
+ "have a valid association called #{@association}"
37
+ end
38
+
39
+ private
40
+
41
+ def expectation
42
+ "#{model_class.name} to #{description}"
43
+ end
44
+
45
+ def model_class
46
+ @subject.class
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,60 @@
1
+ module Shoulda
2
+ module Matchers
3
+ module ActiveRecord
4
+ def have_valid_enum(field, enum_klass)
5
+ HaveValidEnumMatcher.new(field, enum_klass)
6
+ end
7
+
8
+ # @private
9
+ class HaveValidEnumMatcher
10
+ def initialize(field, enum_klass)
11
+ @field = field
12
+ @enum_klass = enum_klass
13
+ end
14
+
15
+ def matches?(subject)
16
+ @subject = subject
17
+ @expected_message ||= :inclusion
18
+
19
+ matches_positive? && matches_negative?
20
+ end
21
+
22
+ def matches_positive?
23
+ @subject.send("#{@field}=", 999)
24
+ @subject.valid?
25
+ @subject.errors[@field].include? I18n.t("errors.messages.#{@expected_message}")
26
+ end
27
+
28
+ def matches_negative?
29
+ @subject.send("#{@field}=", @enum_klass.list.sample)
30
+ @subject.valid?
31
+ !@subject.errors[@field].include? I18n.t("errors.messages.#{@expected_message}")
32
+ end
33
+
34
+ def failure_message
35
+ "Expected #{expectation} (#{@missing})"
36
+ end
37
+ alias failure_message_for_should failure_message
38
+
39
+ def failure_message_when_negated
40
+ "Did not expect #{expectation}"
41
+ end
42
+ alias failure_message_for_should_not failure_message_when_negated
43
+
44
+ def description
45
+ "have a valid enum #{@enum_klass} called #{@field}"
46
+ end
47
+
48
+ private
49
+
50
+ def expectation
51
+ "#{model_class.name} to #{description}"
52
+ end
53
+
54
+ def model_class
55
+ @subject.class
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,51 @@
1
+ module Shoulda
2
+ module Matchers
3
+ module ActiveRecord
4
+ def require_association(association)
5
+ RequireAssociationMatcher.new(association)
6
+ end
7
+
8
+ # @private
9
+ class RequireAssociationMatcher
10
+ def initialize(association)
11
+ @association = association
12
+ @options = {}
13
+ end
14
+
15
+ def matches?(subject)
16
+ @subject = subject
17
+
18
+ @expected_message ||= :required
19
+
20
+ @subject.send("#{@association}=", nil)
21
+ @subject.valid?
22
+ @subject.errors[@association].include? I18n.t("errors.messages.#{@expected_message}")
23
+ end
24
+
25
+ def failure_message
26
+ "Expected #{expectation} (#{@missing})"
27
+ end
28
+ alias failure_message_for_should failure_message
29
+
30
+ def failure_message_when_negated
31
+ "Did not expect #{expectation}"
32
+ end
33
+ alias failure_message_for_should_not failure_message_when_negated
34
+
35
+ def description
36
+ "have a required association called #{@association}"
37
+ end
38
+
39
+ private
40
+
41
+ def expectation
42
+ "#{model_class.name} to #{description}"
43
+ end
44
+
45
+ def model_class
46
+ @subject.class
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,179 @@
1
+ module Shoulda
2
+ module Matchers
3
+ module ActiveModel
4
+ def validate_timeliness(attribute, date_type)
5
+ ValidateTimelinessMatcher.new(attribute, date_type)
6
+ end
7
+
8
+ # @private
9
+ class ValidateTimelinessMatcher
10
+ def initialize(attribute, date_type)
11
+ @attribute = attribute
12
+ @date_type = date_type
13
+ @options = {}
14
+ end
15
+
16
+ [:on_or_before, :before,
17
+ :on_or_after, :after,
18
+ :between].each do |method_name|
19
+ define_method(method_name) do |value|
20
+ @options[method_name] = value
21
+ self
22
+ end
23
+ end
24
+
25
+ def matches?(subject)
26
+ @subject = subject
27
+ valid_date_according_to_type? && valid_date_according_to_options?
28
+ end
29
+
30
+ def failure_message
31
+ "Expected #{expectation} (#{@missing})"
32
+ end
33
+ alias failure_message_for_should failure_message
34
+
35
+ def failure_message_when_negated
36
+ "Did not expect #{expectation}"
37
+ end
38
+ alias failure_message_for_should_not failure_message_when_negated
39
+
40
+ def description
41
+ description = "ensure #{@attribute} has a valid #{@date_type} "
42
+ %w(before on_or_before after on_or_after between).each do |validator|
43
+ symbolized_validator = validator.to_sym
44
+ if @options.key?(symbolized_validator)
45
+ description << "#{validator.tr('_', ' ')} #{@options[symbolized_validator]}"
46
+ end
47
+ end
48
+ description
49
+ end
50
+
51
+ private
52
+
53
+ def expectation
54
+ "#{model_class.name} to #{description}"
55
+ end
56
+
57
+ def model_class
58
+ @subject.class
59
+ end
60
+
61
+ def valid_date_according_to_type?
62
+ @subject.send("#{@attribute}=", 'string')
63
+ @subject.valid?
64
+ return false if @subject.send(@attribute)
65
+ return false unless valid_datetime?
66
+ true
67
+ end
68
+
69
+ def valid_datetime?
70
+ message = message_base("invalid_#{@date_type}")
71
+
72
+ valid_datetime_by_value?(9999, message)
73
+
74
+ correct_date = Date.new(1990, 2, 1)
75
+ valid_datetime_by_value?('1990-02-01', message, correct_date)
76
+ valid_datetime_by_value?('1990/02/01', message, correct_date)
77
+ valid_datetime_by_value?('01/02/1990', message, correct_date)
78
+
79
+ true
80
+ end
81
+
82
+ def valid_datetime_by_value?(value, message, correct_date = nil)
83
+ @subject.send("#{@attribute}=", value)
84
+ @subject.valid?
85
+ return false if @subject.errors[@attribute].include? message
86
+ return false unless valid_correct_date?(correct_date)
87
+ true
88
+ end
89
+
90
+ def valid_correct_date?(correct_date)
91
+ return true unless correct_date
92
+ @subject.send(@attribute) == correct_date
93
+ end
94
+
95
+ def valid_date_according_to_options?
96
+ assertions = [true]
97
+
98
+ [:on_or_before, :before,
99
+ :on_or_after, :after,
100
+ :between].each do |method_name|
101
+ assertions << send("#{method_name}?") if @options[method_name]
102
+ end
103
+ assertions.all? { |assertion| assertion }
104
+ end
105
+
106
+ [:on_or_before, :before,
107
+ :on_or_after, :after].each do |method_name|
108
+ define_method("#{method_name}?") do
109
+ message = message_base(method_name).gsub('%{restriction}', '')
110
+ date_value = @options[method_name]
111
+
112
+ # Validate for before as informed
113
+ before_assertion = assertion_date_options(add_datetime(date_value), message)
114
+ before_assertion = !before_assertion unless method_name.to_s.include?('before')
115
+ return false unless before_assertion
116
+
117
+ # Validate for same date as informed
118
+ same_date_assertion = assertion_date_options(date_value, message)
119
+ same_date_assertion = !same_date_assertion if method_name.to_s.starts_with?('on')
120
+ return false unless same_date_assertion
121
+
122
+ # Validate for after as informed
123
+ after_assertion = assertion_date_options(subtract_datetime(date_value), message)
124
+ after_assertion = !after_assertion unless method_name.to_s.include?('after')
125
+ return false unless after_assertion
126
+
127
+ true
128
+ end
129
+ end
130
+
131
+ def convert_to_date(object)
132
+ converted = Time.zone.parse(object)
133
+ converted = converted.to_date if @date_type == :date
134
+ converted
135
+ end
136
+
137
+ def add_datetime(object)
138
+ converted_to_date = convert_to_date(object)
139
+ if is_time?
140
+ converted_to_date + 1.second
141
+ else
142
+ converted_to_date + 1.day
143
+ end
144
+ end
145
+
146
+ def subtract_datetime(object)
147
+ converted_to_date = convert_to_date(object)
148
+ if is_time?
149
+ converted_to_date - 1.second
150
+ else
151
+ converted_to_date - 1.day
152
+ end
153
+ end
154
+
155
+ def is_time?
156
+ @date_type == :datetime || @date_type == :time
157
+ end
158
+
159
+ def assertion_date_options(date_manipulated, message)
160
+ @subject.send("#{@attribute}=", date_manipulated)
161
+ @subject.valid?
162
+ @subject.errors[@attribute].join(' ').include? message
163
+ end
164
+
165
+ def message_base(message_id)
166
+ underscored_klass = @subject.class.name.underscore
167
+ begin
168
+ I18n.t("activerecord.errors.models.#{underscored_klass}.attributes." \
169
+ "#{@attribute}.#{message_id}")
170
+ rescue RuntimeError
171
+ I18n.t("activerecord.errors.models.#{underscored_klass}.#{message_id}")
172
+ end
173
+ rescue RuntimeError
174
+ I18n.t("errors.messages.#{message_id}")
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,3 @@
1
+ module BeyondTheApiTestHelpers
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: beyond_the_api_test_helpers
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - William Weckl
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-11-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: minitest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mocha
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: shoulda
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 3.5.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 3.5.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.11'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.11'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ description: Test helpers for beyond the API.
84
+ email:
85
+ - william.weckl@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rubocop.yml"
92
+ - ".ruby-version"
93
+ - LICENSE.txt
94
+ - README.md
95
+ - beyond_the_api_test_helpers.gemspec
96
+ - config.reek
97
+ - lib/beyond_the_api_test_helpers.rb
98
+ - lib/beyond_the_api_test_helpers/i18n_test_helpers.rb
99
+ - lib/beyond_the_api_test_helpers/request/common_assertions.rb
100
+ - lib/beyond_the_api_test_helpers/request/create_assertions.rb
101
+ - lib/beyond_the_api_test_helpers/request/destroy_assertions.rb
102
+ - lib/beyond_the_api_test_helpers/request/helpers.rb
103
+ - lib/beyond_the_api_test_helpers/request/index_assertions.rb
104
+ - lib/beyond_the_api_test_helpers/request/restore_assertions.rb
105
+ - lib/beyond_the_api_test_helpers/request/show_assertions.rb
106
+ - lib/beyond_the_api_test_helpers/request/update_assertions.rb
107
+ - lib/beyond_the_api_test_helpers/shoulda/have_foreign_key.rb
108
+ - lib/beyond_the_api_test_helpers/shoulda/have_model_translations.rb
109
+ - lib/beyond_the_api_test_helpers/shoulda/have_valid_association.rb
110
+ - lib/beyond_the_api_test_helpers/shoulda/have_valid_enum.rb
111
+ - lib/beyond_the_api_test_helpers/shoulda/require_association.rb
112
+ - lib/beyond_the_api_test_helpers/shoulda/validate_timeliness.rb
113
+ - lib/beyond_the_api_test_helpers/version.rb
114
+ homepage: http://rubygems.org/gems/beyond_the_api_test_helpers
115
+ licenses:
116
+ - MIT
117
+ metadata: {}
118
+ post_install_message:
119
+ rdoc_options: []
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubyforge_project:
134
+ rubygems_version: 2.6.7
135
+ signing_key:
136
+ specification_version: 4
137
+ summary: Test helpers for beyond the API.
138
+ test_files: []