forked from thoughtbot/shoulda-matchers
/
have_implicit_order_column.rb
106 lines (92 loc) · 2.99 KB
/
have_implicit_order_column.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
module Shoulda
module Matchers
module ActiveRecord
# The `have_implicit_order_column` matcher tests that the model has `implicit_order_column`
# assigned to one of the table columns. (Rails 6+ only)
#
# class Product < ApplicationRecord
# self.implicit_order_column = :created_at
# end
#
# # RSpec
# RSpec.describe Product, type: :model do
# it { should have_implicit_order_column(:created_at) }
# end
#
# # Minitest (Shoulda)
# class ProductTest < ActiveSupport::TestCase
# should have_implicit_order_column(:created_at)
# end
#
# @return [HaveImplicitOrderColumnMatcher]
#
if RailsShim.active_record_gte_6?
def have_implicit_order_column(column_name)
HaveImplicitOrderColumnMatcher.new(column_name)
end
end
# @private
class HaveImplicitOrderColumnMatcher
attr_reader :failure_message
def initialize(column_name)
@column_name = column_name
end
def matches?(subject)
@subject = subject
check_column_exists!
check_implicit_order_column_matches!
true
rescue SecondaryCheckFailedError => e
@failure_message = Shoulda::Matchers.word_wrap(
"Expected #{model.name} to #{expectation}, " +
"but that could not be proved: #{e.message}.",
)
false
rescue PrimaryCheckFailedError => e
@failure_message = Shoulda::Matchers.word_wrap(
"Expected #{model.name} to #{expectation}, but #{e.message}.",
)
false
end
def failure_message_when_negated
Shoulda::Matchers.word_wrap(
"Expected #{model.name} not to #{expectation}, but it did.",
)
end
def description
expectation
end
private
attr_reader :column_name, :subject
def check_column_exists!
matcher = HaveDbColumnMatcher.new(column_name)
if !matcher.matches?(@subject)
raise SecondaryCheckFailedError.new(
"The :#{model.table_name} table does not have a " +
":#{column_name} column",
)
end
end
def check_implicit_order_column_matches!
if model.implicit_order_column.to_s != column_name.to_s
message =
if model.implicit_order_column.nil?
'implicit_order_column is not set'
else
"it is :#{model.implicit_order_column}"
end
raise PrimaryCheckFailedError.new(message)
end
end
def model
subject.class
end
def expectation
"have an implicit_order_column of :#{column_name}"
end
class SecondaryCheckFailedError < StandardError; end
class PrimaryCheckFailedError < StandardError; end
end
end
end
end