/
ignore_interference_by_writer.rb
101 lines (84 loc) · 2.5 KB
/
ignore_interference_by_writer.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
module Shoulda
module Matchers
module ActiveModel
module Qualifiers
# @private
class IgnoreInterferenceByWriter
attr_reader :setting, :condition
def initialize(argument = :always)
set(argument)
@changed = false
end
def set(argument)
if argument.is_a?(self.class)
@setting = argument.setting
@condition = argument.condition
else
case argument
when true, :always
@setting = :always
when false, :never
@setting = :never
else
@setting = :sometimes
if argument.is_a?(Hash)
@condition = argument.fetch(:when)
else
raise invalid_argument_error(argument)
end
end
end
@changed = true
self
rescue KeyError
raise invalid_argument_error(argument)
end
def default_to(argument)
temporary_ignore_interference_by_writer =
IgnoreInterferenceByWriter.new(argument)
unless changed?
@setting = temporary_ignore_interference_by_writer.setting
@condition = temporary_ignore_interference_by_writer.condition
end
self
end
def considering?(value)
case setting
when :always then true
when :never then false
else condition_matches?(value)
end
end
def always?
setting == :always
end
def never?
setting == :never
end
def changed?
@changed
end
private
def invalid_argument_error(invalid_argument)
ArgumentError.new(<<-ERROR)
Unknown argument: #{invalid_argument.inspect}.
ignoring_interference_by_writer takes one of three arguments:
* A symbol, either :never or :always.
* A boolean, either true (which means always) or false (which means
never).
* A hash with a single key, :when, and a single value, which is either
the name of a method or a Proc.
ERROR
end
def condition_matches?(value)
if condition.respond_to?(:call)
condition.call(value)
else
value.public_send(condition)
end
end
end
end
end
end
end