shoulda-matchers 3.0.1 → 3.1.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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +3 -3
- data/CONTRIBUTING.md +60 -28
- data/Gemfile +1 -0
- data/Gemfile.lock +15 -12
- data/NEWS.md +111 -0
- data/README.md +94 -6
- data/Rakefile +10 -8
- data/custom_plan.rb +88 -0
- data/gemfiles/4.0.0.gemfile +1 -0
- data/gemfiles/4.0.0.gemfile.lock +21 -18
- data/gemfiles/4.0.1.gemfile +1 -0
- data/gemfiles/4.0.1.gemfile.lock +21 -18
- data/gemfiles/4.1.gemfile +1 -0
- data/gemfiles/4.1.gemfile.lock +21 -18
- data/gemfiles/4.2.gemfile +1 -0
- data/gemfiles/4.2.gemfile.lock +24 -21
- data/lib/shoulda/matchers/action_controller/permit_matcher.rb +6 -11
- data/lib/shoulda/matchers/active_model.rb +10 -1
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +258 -180
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error.rb +45 -0
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_does_not_exist_error.rb +23 -0
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter.rb +236 -0
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter_and_validator.rb +62 -0
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters.rb +40 -0
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb +48 -0
- data/lib/shoulda/matchers/active_model/allow_value_matcher/successful_check.rb +14 -0
- data/lib/shoulda/matchers/active_model/allow_value_matcher/successful_setting.rb +14 -0
- data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +34 -14
- data/lib/shoulda/matchers/active_model/helpers.rb +9 -17
- data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +13 -6
- data/lib/shoulda/matchers/active_model/numericality_matchers/even_number_matcher.rb +13 -2
- data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +19 -35
- data/lib/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher.rb +13 -2
- data/lib/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher.rb +12 -2
- data/lib/shoulda/matchers/active_model/qualifiers.rb +12 -0
- data/lib/shoulda/matchers/active_model/qualifiers/ignore_interference_by_writer.rb +101 -0
- data/lib/shoulda/matchers/active_model/qualifiers/ignoring_interference_by_writer.rb +21 -0
- data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +30 -32
- data/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +5 -8
- data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +22 -22
- data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +27 -16
- data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +58 -15
- data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +22 -12
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +165 -87
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +7 -9
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +111 -49
- data/lib/shoulda/matchers/active_model/validation_matcher/build_description.rb +60 -0
- data/lib/shoulda/matchers/active_model/validator.rb +71 -52
- data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +19 -5
- data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +450 -124
- data/lib/shoulda/matchers/util.rb +43 -0
- data/lib/shoulda/matchers/util/word_wrap.rb +59 -31
- data/lib/shoulda/matchers/version.rb +1 -1
- data/script/update_gem_in_all_appraisals +1 -1
- data/script/update_gems_in_all_appraisals +1 -1
- data/spec/acceptance/multiple_libraries_integration_spec.rb +5 -2
- data/spec/acceptance/rails_integration_spec.rb +6 -2
- data/spec/spec_helper.rb +1 -3
- data/spec/support/acceptance/helpers/step_helpers.rb +4 -1
- data/spec/support/tests/current_bundle.rb +21 -7
- data/spec/support/unit/active_record/create_table.rb +54 -0
- data/spec/support/unit/attribute.rb +47 -0
- data/spec/support/unit/capture.rb +6 -0
- data/spec/support/unit/change_value.rb +111 -0
- data/spec/support/unit/create_model_arguments/basic.rb +135 -0
- data/spec/support/unit/create_model_arguments/has_many.rb +15 -0
- data/spec/support/unit/create_model_arguments/uniqueness_matcher.rb +74 -0
- data/spec/support/unit/helpers/active_record_versions.rb +1 -1
- data/spec/support/unit/helpers/class_builder.rb +61 -47
- data/spec/support/unit/helpers/database_helpers.rb +5 -3
- data/spec/support/unit/helpers/model_builder.rb +77 -97
- data/spec/support/unit/helpers/validation_matcher_scenario_helpers.rb +44 -0
- data/spec/support/unit/load_environment.rb +12 -0
- data/spec/support/unit/matchers/fail_with_message_including_matcher.rb +2 -2
- data/spec/support/unit/matchers/fail_with_message_matcher.rb +12 -1
- data/spec/support/unit/model_creation_strategies/active_model.rb +111 -0
- data/spec/support/unit/model_creation_strategies/active_record.rb +77 -0
- data/spec/support/unit/model_creators.rb +19 -0
- data/spec/support/unit/model_creators/active_model.rb +39 -0
- data/spec/support/unit/model_creators/active_record.rb +43 -0
- data/spec/support/unit/model_creators/active_record/has_and_belongs_to_many.rb +95 -0
- data/spec/support/unit/model_creators/active_record/has_many.rb +67 -0
- data/spec/support/unit/model_creators/active_record/uniqueness_matcher.rb +42 -0
- data/spec/support/unit/model_creators/basic.rb +97 -0
- data/spec/support/unit/rails_application.rb +1 -1
- data/spec/support/unit/record_validating_confirmation_builder.rb +3 -7
- data/spec/support/unit/shared_examples/ignoring_interference_by_writer.rb +79 -0
- data/spec/support/unit/validation_matcher_scenario.rb +62 -0
- data/spec/unit/shoulda/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +4 -0
- data/spec/unit/shoulda/matchers/active_model/allow_value_matcher_spec.rb +575 -140
- data/spec/unit/shoulda/matchers/active_model/validate_absence_of_matcher_spec.rb +115 -15
- data/spec/unit/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +42 -4
- data/spec/unit/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +92 -6
- data/spec/unit/shoulda/matchers/active_model/validate_exclusion_of_matcher_spec.rb +122 -10
- data/spec/unit/shoulda/matchers/active_model/validate_inclusion_of_matcher_spec.rb +306 -58
- data/spec/unit/shoulda/matchers/active_model/validate_length_of_matcher_spec.rb +122 -3
- data/spec/unit/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +805 -131
- data/spec/unit/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +196 -29
- data/spec/unit/shoulda/matchers/active_record/define_enum_for_matcher_spec.rb +82 -40
- data/spec/unit/shoulda/matchers/active_record/validate_uniqueness_of_matcher_spec.rb +600 -101
- data/spec/unit/shoulda/matchers/util/word_wrap_spec.rb +88 -33
- data/spec/unit_spec_helper.rb +10 -22
- data/zeus.json +11 -0
- metadata +64 -23
- data/lib/shoulda/matchers/active_model/strict_validator.rb +0 -51
- data/spec/support/unit/shared_examples/numerical_type_submatcher.rb +0 -15
- data/spec/unit/shoulda/matchers/active_model/numericality_matchers/comparison_matcher_spec.rb +0 -288
- data/spec/unit/shoulda/matchers/active_model/numericality_matchers/even_number_matcher_spec.rb +0 -100
- data/spec/unit/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher_spec.rb +0 -100
- data/spec/unit/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher_spec.rb +0 -100
@@ -30,6 +30,49 @@ module Shoulda
|
|
30
30
|
indentation = ' ' * width
|
31
31
|
string.split(/[\n\r]/).map { |line| indentation + line }.join("\n")
|
32
32
|
end
|
33
|
+
|
34
|
+
def self.a_or_an(next_word)
|
35
|
+
if next_word =~ /\A[aeiou]/i
|
36
|
+
"an #{next_word}"
|
37
|
+
else
|
38
|
+
"a #{next_word}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.inspect_value(value)
|
43
|
+
"‹#{value.inspect}›"
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.inspect_values(values)
|
47
|
+
values.map { |value| inspect_value(value) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.inspect_range(range)
|
51
|
+
"#{inspect_value(range.first)} to #{inspect_value(range.last)}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.dummy_value_for(column_type, array: false)
|
55
|
+
if array
|
56
|
+
[dummy_value_for(column_type, array: false)]
|
57
|
+
else
|
58
|
+
case column_type
|
59
|
+
when :integer
|
60
|
+
0
|
61
|
+
when :date
|
62
|
+
Date.new(2100, 1, 1)
|
63
|
+
when :datetime, :timestamp
|
64
|
+
DateTime.new(2100, 1, 1)
|
65
|
+
when :time
|
66
|
+
Time.new(2100, 1, 1)
|
67
|
+
when :uuid
|
68
|
+
SecureRandom.uuid
|
69
|
+
when :boolean
|
70
|
+
true
|
71
|
+
else
|
72
|
+
'dummy value'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
33
76
|
end
|
34
77
|
end
|
35
78
|
end
|
@@ -1,14 +1,15 @@
|
|
1
1
|
module Shoulda
|
2
2
|
module Matchers
|
3
3
|
# @private
|
4
|
-
def self.word_wrap(document)
|
5
|
-
Document.new(document).wrap
|
4
|
+
def self.word_wrap(document, options = {})
|
5
|
+
Document.new(document, options).wrap
|
6
6
|
end
|
7
7
|
|
8
8
|
# @private
|
9
9
|
class Document
|
10
|
-
def initialize(document)
|
10
|
+
def initialize(document, indent: 0)
|
11
11
|
@document = document
|
12
|
+
@indent = indent
|
12
13
|
end
|
13
14
|
|
14
15
|
def wrap
|
@@ -17,7 +18,7 @@ module Shoulda
|
|
17
18
|
|
18
19
|
protected
|
19
20
|
|
20
|
-
attr_reader :document
|
21
|
+
attr_reader :document, :indent
|
21
22
|
|
22
23
|
private
|
23
24
|
|
@@ -27,7 +28,7 @@ module Shoulda
|
|
27
28
|
|
28
29
|
def wrapped_paragraphs
|
29
30
|
paragraphs.map do |paragraph|
|
30
|
-
Paragraph.new(paragraph).wrap
|
31
|
+
Paragraph.new(paragraph, indent: indent).wrap
|
31
32
|
end
|
32
33
|
end
|
33
34
|
end
|
@@ -51,8 +52,9 @@ module Shoulda
|
|
51
52
|
|
52
53
|
# @private
|
53
54
|
class Paragraph
|
54
|
-
def initialize(paragraph)
|
55
|
+
def initialize(paragraph, indent: 0)
|
55
56
|
@paragraph = Text.new(paragraph)
|
57
|
+
@indent = indent
|
56
58
|
end
|
57
59
|
|
58
60
|
def wrap
|
@@ -67,7 +69,7 @@ module Shoulda
|
|
67
69
|
|
68
70
|
protected
|
69
71
|
|
70
|
-
attr_reader :paragraph
|
72
|
+
attr_reader :paragraph, :indent
|
71
73
|
|
72
74
|
private
|
73
75
|
|
@@ -92,11 +94,11 @@ module Shoulda
|
|
92
94
|
end
|
93
95
|
|
94
96
|
def wrap_lines(lines)
|
95
|
-
lines.map { |line| Line.new(line).wrap }
|
97
|
+
lines.map { |line| Line.new(line, indent: indent).wrap }
|
96
98
|
end
|
97
99
|
|
98
100
|
def wrap_generic_paragraph
|
99
|
-
Line.new(combine_paragraph_into_one_line).wrap
|
101
|
+
Line.new(combine_paragraph_into_one_line, indent: indent).wrap
|
100
102
|
end
|
101
103
|
|
102
104
|
def combine_paragraph_into_one_line
|
@@ -107,72 +109,98 @@ module Shoulda
|
|
107
109
|
# @private
|
108
110
|
class Line
|
109
111
|
TERMINAL_WIDTH = 72
|
112
|
+
OFFSETS = { left: -1, right: +1 }
|
110
113
|
|
111
|
-
def initialize(line)
|
114
|
+
def initialize(line, indent: 0)
|
115
|
+
@indent = indent
|
112
116
|
@original_line = @line_to_wrap = Text.new(line)
|
113
|
-
@indentation =
|
117
|
+
@indentation = ' ' * indent
|
118
|
+
@indentation_read = false
|
114
119
|
end
|
115
120
|
|
116
121
|
def wrap
|
117
|
-
lines = []
|
118
|
-
|
119
122
|
if line_to_wrap.indented?
|
120
|
-
|
123
|
+
[line_to_wrap]
|
121
124
|
else
|
125
|
+
lines = []
|
126
|
+
|
122
127
|
loop do
|
128
|
+
@previous_line_to_wrap = line_to_wrap
|
123
129
|
new_line = (indentation || '') + line_to_wrap
|
124
130
|
result = wrap_line(new_line)
|
125
|
-
lines << result[:fitted_line]
|
126
|
-
|
131
|
+
lines << normalize_whitespace(result[:fitted_line])
|
132
|
+
|
133
|
+
unless @indentation_read
|
134
|
+
@indentation = read_indentation
|
135
|
+
@indentation_read = true
|
136
|
+
end
|
137
|
+
|
127
138
|
@line_to_wrap = result[:leftover]
|
128
139
|
|
129
|
-
if line_to_wrap.empty? ||
|
140
|
+
if line_to_wrap.to_s.empty? || previous_line_to_wrap == line_to_wrap
|
130
141
|
break
|
131
142
|
end
|
132
143
|
end
|
133
|
-
end
|
134
144
|
|
135
|
-
|
145
|
+
lines
|
146
|
+
end
|
136
147
|
end
|
137
148
|
|
138
149
|
protected
|
139
150
|
|
140
|
-
attr_reader :original_line, :line_to_wrap, :indentation
|
151
|
+
attr_reader :indent, :original_line, :line_to_wrap, :indentation,
|
152
|
+
:previous_line_to_wrap
|
141
153
|
|
142
154
|
private
|
143
155
|
|
144
156
|
def read_indentation
|
157
|
+
initial_indentation = ' ' * indent
|
145
158
|
match = line_to_wrap.match_as_list_item
|
146
159
|
|
147
160
|
if match
|
148
|
-
' ' * match[1].length
|
161
|
+
initial_indentation + (' ' * match[1].length)
|
149
162
|
else
|
150
|
-
|
163
|
+
initial_indentation
|
151
164
|
end
|
152
165
|
end
|
153
166
|
|
154
|
-
def wrap_line(line)
|
167
|
+
def wrap_line(line, direction: :left)
|
168
|
+
index = nil
|
169
|
+
|
155
170
|
if line.length > TERMINAL_WIDTH
|
156
|
-
index = determine_where_to_break_line(line)
|
157
|
-
|
158
|
-
|
159
|
-
|
171
|
+
index = determine_where_to_break_line(line, direction: :left)
|
172
|
+
|
173
|
+
if index == -1
|
174
|
+
index = determine_where_to_break_line(line, direction: :right)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
if index.nil? || index == -1
|
160
179
|
fitted_line = line
|
161
180
|
leftover = ''
|
181
|
+
else
|
182
|
+
fitted_line = line[0..index].rstrip
|
183
|
+
leftover = line[index + 1 .. -1]
|
162
184
|
end
|
163
185
|
|
164
186
|
{ fitted_line: fitted_line, leftover: leftover }
|
165
187
|
end
|
166
188
|
|
167
|
-
def determine_where_to_break_line(line)
|
168
|
-
|
189
|
+
def determine_where_to_break_line(line, args)
|
190
|
+
direction = args.fetch(:direction)
|
191
|
+
index = TERMINAL_WIDTH
|
192
|
+
offset = OFFSETS.fetch(direction)
|
169
193
|
|
170
|
-
while line[index] !~ /\s/
|
171
|
-
index
|
194
|
+
while line[index] !~ /\s/ && (0...line.length).cover?(index)
|
195
|
+
index += offset
|
172
196
|
end
|
173
197
|
|
174
198
|
index
|
175
199
|
end
|
200
|
+
|
201
|
+
def normalize_whitespace(string)
|
202
|
+
indentation + string.strip.squeeze(' ')
|
203
|
+
end
|
176
204
|
end
|
177
205
|
end
|
178
206
|
end
|
@@ -5,7 +5,7 @@ gem="$1"
|
|
5
5
|
|
6
6
|
update-gem-for-version() {
|
7
7
|
local version="$1"
|
8
|
-
(export RBENV_VERSION=$version; bundle update "$gem"
|
8
|
+
(export RBENV_VERSION=$version; bundle update "$gem"; bundle exec appraisal update "$gem")
|
9
9
|
}
|
10
10
|
|
11
11
|
for version in $SUPPORTED_VERSIONS; do
|
@@ -4,7 +4,7 @@ SUPPORTED_VERSIONS=$(<script/SUPPORTED_VERSIONS)
|
|
4
4
|
|
5
5
|
update-gems-for-version() {
|
6
6
|
local version="$1"
|
7
|
-
(export RBENV_VERSION=$version; bundle update "${@:2}"
|
7
|
+
(export RBENV_VERSION=$version; bundle update "${@:2}"; bundle exec appraisal update "${@:2}")
|
8
8
|
}
|
9
9
|
|
10
10
|
for version in $SUPPORTED_VERSIONS; do
|
@@ -25,6 +25,7 @@ describe 'shoulda-matchers integrates with multiple libraries' do
|
|
25
25
|
|
26
26
|
add_rspec_file 'spec/models/user_spec.rb', <<-FILE
|
27
27
|
describe User do
|
28
|
+
subject { User.new(name: "John Smith") }
|
28
29
|
it { should validate_presence_of(:name) }
|
29
30
|
it { should validate_uniqueness_of(:name) }
|
30
31
|
end
|
@@ -43,9 +44,11 @@ describe 'shoulda-matchers integrates with multiple libraries' do
|
|
43
44
|
it 'allows the use of matchers from both libraries' do
|
44
45
|
result = run_rspec_suite
|
45
46
|
expect(result).to have_output('2 examples, 0 failures')
|
46
|
-
expect(result).to have_output('should require name to be set')
|
47
47
|
expect(result).to have_output(
|
48
|
-
'should
|
48
|
+
'should validate that :name cannot be empty/falsy'
|
49
|
+
)
|
50
|
+
expect(result).to have_output(
|
51
|
+
'should validate that :name is case-sensitively unique'
|
49
52
|
)
|
50
53
|
end
|
51
54
|
end
|
@@ -124,7 +124,9 @@ describe 'shoulda-matchers integrates with Rails' do
|
|
124
124
|
result = run_n_unit_test_suite
|
125
125
|
|
126
126
|
expect(result).to indicate_that_tests_were_run(unit: 1, functional: 1)
|
127
|
-
expect(result).to have_output(
|
127
|
+
expect(result).to have_output(
|
128
|
+
'User should validate that :name cannot be empty/falsy'
|
129
|
+
)
|
128
130
|
expect(result).to have_output('should respond with 200')
|
129
131
|
end
|
130
132
|
|
@@ -146,7 +148,9 @@ describe 'shoulda-matchers integrates with Rails' do
|
|
146
148
|
result = run_rspec_suite
|
147
149
|
|
148
150
|
expect(result).to have_output('2 examples, 0 failures')
|
149
|
-
expect(result).to have_output(
|
151
|
+
expect(result).to have_output(
|
152
|
+
'should validate that :name cannot be empty/falsy'
|
153
|
+
)
|
150
154
|
expect(result).to have_output('should respond with 200')
|
151
155
|
end
|
152
156
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -18,6 +18,7 @@ module AcceptanceTests
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def create_generic_bundler_project
|
21
|
+
fs.clean
|
21
22
|
fs.create
|
22
23
|
run_command! 'bundle init'
|
23
24
|
end
|
@@ -61,7 +62,9 @@ module AcceptanceTests
|
|
61
62
|
end
|
62
63
|
|
63
64
|
def create_rails_application
|
64
|
-
|
65
|
+
fs.clean
|
66
|
+
|
67
|
+
command = "bundle exec rails new #{fs.project_directory} --skip-bundle --no-rc"
|
65
68
|
|
66
69
|
run_command!(command) do |runner|
|
67
70
|
runner.directory = nil
|
@@ -8,21 +8,33 @@ module Tests
|
|
8
8
|
include Singleton
|
9
9
|
|
10
10
|
def assert_appraisal!
|
11
|
-
unless
|
11
|
+
unless appraisal_in_use?
|
12
12
|
message = <<EOT
|
13
13
|
|
14
14
|
|
15
15
|
Please run tests starting with `appraisal <appraisal_name>`.
|
16
|
-
Possible appraisals are: #{
|
16
|
+
Possible appraisals are: #{available_appraisals}
|
17
17
|
|
18
18
|
EOT
|
19
19
|
raise AppraisalNotSpecified, message
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
+
def appraisal_in_use?
|
24
|
+
path.dirname == root.join('gemfiles')
|
25
|
+
end
|
26
|
+
|
27
|
+
def current_or_latest_appraisal
|
28
|
+
current_appraisal || latest_appraisal
|
29
|
+
end
|
30
|
+
|
31
|
+
def latest_appraisal
|
32
|
+
available_appraisals.sort.last
|
33
|
+
end
|
34
|
+
|
23
35
|
private
|
24
36
|
|
25
|
-
def
|
37
|
+
def available_appraisals
|
26
38
|
appraisals = []
|
27
39
|
|
28
40
|
Appraisal::File.each do |appraisal|
|
@@ -32,12 +44,14 @@ EOT
|
|
32
44
|
appraisals
|
33
45
|
end
|
34
46
|
|
35
|
-
def
|
36
|
-
|
47
|
+
def current_appraisal
|
48
|
+
if appraisal_in_use?
|
49
|
+
File.basename(path, ".gemfile")
|
50
|
+
end
|
37
51
|
end
|
38
52
|
|
39
|
-
def
|
40
|
-
|
53
|
+
def path
|
54
|
+
Bundler.default_gemfile
|
41
55
|
end
|
42
56
|
|
43
57
|
def root
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module UnitTests
|
2
|
+
module ActiveRecord
|
3
|
+
class CreateTable
|
4
|
+
def self.call(table_name, columns)
|
5
|
+
new(table_name, columns).call
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(table_name, columns)
|
9
|
+
@table_name = table_name
|
10
|
+
@columns = columns
|
11
|
+
end
|
12
|
+
|
13
|
+
def call
|
14
|
+
if columns.key?(:id) && columns[:id] == false
|
15
|
+
columns.delete(:id)
|
16
|
+
UnitTests::ModelBuilder.create_table(
|
17
|
+
table_name,
|
18
|
+
id: false,
|
19
|
+
&method(:add_columns_to_table)
|
20
|
+
)
|
21
|
+
else
|
22
|
+
UnitTests::ModelBuilder.create_table(
|
23
|
+
table_name,
|
24
|
+
&method(:add_columns_to_table)
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
attr_reader :table_name, :columns
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def add_columns_to_table(table)
|
36
|
+
columns.each do |column_name, column_specification|
|
37
|
+
add_column_to_table(table, column_name, column_specification)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def add_column_to_table(table, column_name, column_specification)
|
42
|
+
if column_specification.is_a?(Hash)
|
43
|
+
column_type = column_specification.fetch(:type)
|
44
|
+
column_options = column_specification.fetch(:options, {})
|
45
|
+
else
|
46
|
+
column_type = column_specification
|
47
|
+
column_options = {}
|
48
|
+
end
|
49
|
+
|
50
|
+
table.column(column_name, column_type, column_options)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|