policy 1.2.0 → 2.0.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/Guardfile +4 -4
- data/README.md +177 -78
- data/config/metrics/flay.yml +1 -1
- data/config/metrics/roodi.yml +2 -2
- data/lib/policy.rb +52 -33
- data/lib/policy/base.rb +122 -0
- data/lib/policy/base/and.rb +38 -0
- data/lib/policy/base/negator.rb +52 -0
- data/lib/policy/base/node.rb +59 -0
- data/lib/policy/base/not.rb +42 -0
- data/lib/policy/base/or.rb +39 -0
- data/lib/policy/base/xor.rb +39 -0
- data/lib/policy/cli.rb +8 -3
- data/lib/policy/cli/attribute.rb +49 -0
- data/lib/policy/cli/locale.erb +1 -2
- data/lib/policy/cli/policy.erb +33 -6
- data/lib/policy/cli/spec.erb +31 -11
- data/lib/policy/follower.rb +54 -94
- data/lib/policy/follower/name_error.rb +53 -0
- data/lib/policy/follower/policies.rb +104 -0
- data/lib/policy/follower/violation_error.rb +60 -0
- data/lib/policy/version.rb +2 -2
- data/policy.gemspec +2 -3
- data/spec/support/composer.rb +28 -0
- data/spec/tests/lib/policy/base/and_spec.rb +62 -0
- data/spec/tests/lib/policy/base/negator_spec.rb +49 -0
- data/spec/tests/lib/policy/base/not_spec.rb +50 -0
- data/spec/tests/lib/policy/base/or_spec.rb +62 -0
- data/spec/tests/lib/policy/base/xor_spec.rb +73 -0
- data/spec/tests/lib/policy/base_spec.rb +123 -0
- data/spec/tests/lib/policy/cli/attribute_spec.rb +52 -0
- data/spec/tests/{policy → lib/policy}/cli_spec.rb +25 -24
- data/spec/tests/lib/policy/follower/name_error_spec.rb +51 -0
- data/spec/tests/lib/policy/follower/policies_spec.rb +156 -0
- data/spec/tests/lib/policy/follower/violation_error_spec.rb +60 -0
- data/spec/tests/lib/policy/follower_spec.rb +153 -0
- data/spec/tests/lib/policy_spec.rb +52 -0
- metadata +43 -44
- data/lib/policy/follower/followed_policies.rb +0 -45
- data/lib/policy/follower/followed_policy.rb +0 -104
- data/lib/policy/follower/names.rb +0 -29
- data/lib/policy/interface.rb +0 -48
- data/lib/policy/validations.rb +0 -28
- data/lib/policy/violation_error.rb +0 -52
- data/spec/features/follower_spec.rb +0 -95
- data/spec/tests/policy/follower/followed_policies_spec.rb +0 -87
- data/spec/tests/policy/follower/followed_policy_spec.rb +0 -117
- data/spec/tests/policy/follower/names_spec.rb +0 -19
- data/spec/tests/policy/follower_spec.rb +0 -220
- data/spec/tests/policy/interface_spec.rb +0 -83
- data/spec/tests/policy/validations_spec.rb +0 -13
- data/spec/tests/policy/violation_error_spec.rb +0 -75
- data/spec/tests/policy_spec.rb +0 -35
@@ -1,52 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Policy
|
4
|
-
|
5
|
-
# An exception to be risen by {Policy::Interface#apply}
|
6
|
-
class ViolationError < RuntimeError
|
7
|
-
include Adamantium
|
8
|
-
|
9
|
-
# @!attribute [r] policy
|
10
|
-
# The violated policy object
|
11
|
-
#
|
12
|
-
# @return [Policy::Follower]
|
13
|
-
attr_reader :policy
|
14
|
-
|
15
|
-
# @!attribute [r] messages
|
16
|
-
# The list of messages from the broken policy
|
17
|
-
#
|
18
|
-
# @return [Array<String>]
|
19
|
-
attr_reader :messages
|
20
|
-
|
21
|
-
# @!scope class
|
22
|
-
# @!method new(policy)
|
23
|
-
# Constructs an exception
|
24
|
-
#
|
25
|
-
# @param [Policy::Follower] policy
|
26
|
-
# the violated policy object
|
27
|
-
#
|
28
|
-
# @return [Policy::ViolationError]
|
29
|
-
def initialize(policy)
|
30
|
-
@policy = policy.dup
|
31
|
-
@messages = @policy.messages
|
32
|
-
end
|
33
|
-
|
34
|
-
# The human-readable description for the exception
|
35
|
-
#
|
36
|
-
# @return [String]
|
37
|
-
def inspect
|
38
|
-
"#<#{ self }: #{ message }>"
|
39
|
-
end
|
40
|
-
|
41
|
-
# The human-readable exception message
|
42
|
-
#
|
43
|
-
# @return [String]
|
44
|
-
def message
|
45
|
-
"#{ policy } violated: #{ messages }"
|
46
|
-
end
|
47
|
-
|
48
|
-
memoize :policy, :messages
|
49
|
-
|
50
|
-
end # module Follower
|
51
|
-
|
52
|
-
end # module Policy
|
@@ -1,95 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
# The integration test for policy follower
|
4
|
-
describe Policy::Follower do
|
5
|
-
|
6
|
-
before do
|
7
|
-
|
8
|
-
Transaction = Class.new Struct.new(:sum)
|
9
|
-
|
10
|
-
module Policies
|
11
|
-
|
12
|
-
class Consistency < Policy.new(:debet, :credit)
|
13
|
-
|
14
|
-
validates :debet, :credit, presence: true
|
15
|
-
validates :sum, numericality: { equal_to: 0 }, allow_nil: true
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def sum
|
20
|
-
debet && credit && (credit.sum + debet.sum)
|
21
|
-
end
|
22
|
-
|
23
|
-
end # class Consistency
|
24
|
-
|
25
|
-
end # module Policy
|
26
|
-
|
27
|
-
# The follower class to be tested
|
28
|
-
class Transfer < Struct.new(:withdrawal, :enrollment)
|
29
|
-
include Policy::Follower
|
30
|
-
|
31
|
-
use_policies Policies do
|
32
|
-
follow_policy :Consistency, :withdrawal, :enrollment, as: :consistency
|
33
|
-
end
|
34
|
-
|
35
|
-
end # class Transfer
|
36
|
-
|
37
|
-
end # before
|
38
|
-
|
39
|
-
let(:withdrawal) { Transaction.new(-100) }
|
40
|
-
subject { Transfer.new withdrawal, enrollment }
|
41
|
-
|
42
|
-
describe "#follow_policies!" do
|
43
|
-
|
44
|
-
context "when policy is met" do
|
45
|
-
|
46
|
-
let(:enrollment) { Transaction.new(100) }
|
47
|
-
|
48
|
-
it "passes if the policy is met" do
|
49
|
-
expect { subject.follow_policies! }.not_to raise_error
|
50
|
-
end
|
51
|
-
|
52
|
-
end # context
|
53
|
-
|
54
|
-
context "when policy is broken" do
|
55
|
-
|
56
|
-
let(:enrollment) { Transaction.new(200) }
|
57
|
-
|
58
|
-
it "fails if the policy is broken" do
|
59
|
-
expect { subject.follow_policies! }.to raise_error
|
60
|
-
end
|
61
|
-
|
62
|
-
end # context
|
63
|
-
|
64
|
-
end # describe #follow_policies!
|
65
|
-
|
66
|
-
describe "#follow_policies?" do
|
67
|
-
|
68
|
-
context "when policy is met" do
|
69
|
-
|
70
|
-
let(:enrollment) { Transaction.new(100) }
|
71
|
-
|
72
|
-
it "returns true if the policy is met" do
|
73
|
-
expect(subject).to be_follow_policies
|
74
|
-
end
|
75
|
-
|
76
|
-
end # context
|
77
|
-
|
78
|
-
context "when policy is broken" do
|
79
|
-
|
80
|
-
let(:enrollment) { Transaction.new(200) }
|
81
|
-
|
82
|
-
it "returns false if the policy is broken" do
|
83
|
-
expect(subject).not_to be_follow_policies
|
84
|
-
end
|
85
|
-
|
86
|
-
end # context
|
87
|
-
|
88
|
-
end # describe #follow_policies!
|
89
|
-
|
90
|
-
after do
|
91
|
-
%i(Transaction Transfer Policies)
|
92
|
-
.each { |const| Object.__send__(:remove_const, const) }
|
93
|
-
end
|
94
|
-
|
95
|
-
end # describe Policy::Follower
|
@@ -1,87 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require "ostruct"
|
3
|
-
|
4
|
-
describe Policy::Follower::FollowedPolicies do
|
5
|
-
|
6
|
-
it "is a hash" do
|
7
|
-
expect(subject).to be_kind_of Hash
|
8
|
-
end
|
9
|
-
|
10
|
-
describe "#add" do
|
11
|
-
|
12
|
-
let(:policy) { double :policy, name: :foo }
|
13
|
-
|
14
|
-
it "registers a policy" do
|
15
|
-
expect { subject.add policy }.to change { subject }.to(foo: policy)
|
16
|
-
end
|
17
|
-
|
18
|
-
end # describe #add
|
19
|
-
|
20
|
-
describe "#apply_to" do
|
21
|
-
|
22
|
-
let(:follower) { double }
|
23
|
-
|
24
|
-
before do
|
25
|
-
%i(first second third).each do |item|
|
26
|
-
subject.add double(name: item, apply_to: nil)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
shared_examples "applying policies" do |applied_policies = nil|
|
31
|
-
|
32
|
-
before { applied_policies ||= subject.keys }
|
33
|
-
let(:skipped_policies) { subject.keys - applied_policies }
|
34
|
-
|
35
|
-
it "[applies policies]" do
|
36
|
-
policies = applied_policies.map(&subject.method(:[]))
|
37
|
-
|
38
|
-
policies.each do |policy|
|
39
|
-
expect(policy).to receive(:apply_to).with(follower).ordered
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
it "[skips policies]" do
|
44
|
-
policies = skipped_policies.map(&subject.method(:[]))
|
45
|
-
|
46
|
-
policies.each do |policy|
|
47
|
-
expect(policy).not_to receive(:apply_to)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
end # shared examples
|
52
|
-
|
53
|
-
context "by default" do
|
54
|
-
|
55
|
-
after { subject.apply_to follower }
|
56
|
-
|
57
|
-
it_behaves_like "applying policies"
|
58
|
-
|
59
|
-
end # context
|
60
|
-
|
61
|
-
context "with a list of names" do
|
62
|
-
|
63
|
-
after { subject.apply_to follower, :third, :first }
|
64
|
-
|
65
|
-
it_behaves_like "applying policies", %i(third first)
|
66
|
-
|
67
|
-
end # context
|
68
|
-
|
69
|
-
context "with a repetitive names" do
|
70
|
-
|
71
|
-
after { subject.apply_to follower, :third, :third, :third }
|
72
|
-
|
73
|
-
it_behaves_like "applying policies", %i(third third third)
|
74
|
-
|
75
|
-
end # context
|
76
|
-
|
77
|
-
context "with an array of names" do
|
78
|
-
|
79
|
-
after { subject.apply_to follower, %w(third first forth) }
|
80
|
-
|
81
|
-
it_behaves_like "applying policies", %i(third first)
|
82
|
-
|
83
|
-
end # context
|
84
|
-
|
85
|
-
end # describe #apply_to
|
86
|
-
|
87
|
-
end # describe Policy::Follower::FollowedPolicies
|
@@ -1,117 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require "ostruct"
|
3
|
-
|
4
|
-
describe Policy::Follower::FollowedPolicy do
|
5
|
-
|
6
|
-
before { module Namespace; class Policy < ::Policy.new(:foo, :bar); end; end }
|
7
|
-
after { Object.send :remove_const, :Namespace }
|
8
|
-
|
9
|
-
let(:namespace) { Namespace }
|
10
|
-
let(:policy_class) { Namespace::Policy }
|
11
|
-
|
12
|
-
describe ".new" do
|
13
|
-
|
14
|
-
shared_examples "refusing wrong number of attributes" do |*list|
|
15
|
-
|
16
|
-
subject { described_class.new nil, policy_class, :policy, *list }
|
17
|
-
|
18
|
-
it "raises ArgumentError" do
|
19
|
-
expect { subject }.to raise_error(ArgumentError)
|
20
|
-
end
|
21
|
-
|
22
|
-
it "sets a proper message for the exception" do
|
23
|
-
begin
|
24
|
-
subject
|
25
|
-
rescue => err
|
26
|
-
expect(err.message).to eq(
|
27
|
-
"#{ policy_class } requires 2 attribute(s)." \
|
28
|
-
" #{ list } cannot be assigned."
|
29
|
-
)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
end # shared examples
|
34
|
-
|
35
|
-
it_behaves_like "refusing wrong number of attributes", :foo
|
36
|
-
it_behaves_like "refusing wrong number of attributes", :foo, :bar, :baz
|
37
|
-
|
38
|
-
end # describe .new
|
39
|
-
|
40
|
-
describe "#name" do
|
41
|
-
|
42
|
-
context "when name is set to nil" do
|
43
|
-
|
44
|
-
subject { described_class.new nil, policy_class, nil, :foo, :bar }
|
45
|
-
|
46
|
-
it "assigns uuid" do
|
47
|
-
expect(subject.name.to_s).to match(/^\h{8}-(\h{4}-){3}\h{12}$/)
|
48
|
-
end
|
49
|
-
|
50
|
-
it "is a symbol" do
|
51
|
-
expect(subject.name).to be_kind_of Symbol
|
52
|
-
end
|
53
|
-
|
54
|
-
end # context
|
55
|
-
|
56
|
-
context "when name is set explicitly" do
|
57
|
-
|
58
|
-
subject { described_class.new nil, policy_class, "policy", :foo, :bar }
|
59
|
-
|
60
|
-
it "returns the symbolized name" do
|
61
|
-
expect(subject.name).to eq :policy
|
62
|
-
end
|
63
|
-
|
64
|
-
end # context
|
65
|
-
|
66
|
-
end # describe #name
|
67
|
-
|
68
|
-
describe "#policy" do
|
69
|
-
|
70
|
-
let(:policy_name) { :Policy }
|
71
|
-
|
72
|
-
shared_examples "policy object class" do
|
73
|
-
|
74
|
-
it "returns the constant" do
|
75
|
-
expect(subject.policy).to eq policy_class
|
76
|
-
end
|
77
|
-
|
78
|
-
end # context
|
79
|
-
|
80
|
-
it_behaves_like "policy object class" do
|
81
|
-
subject { described_class.new :foo, policy_class, :foo, :bar, :baz }
|
82
|
-
end
|
83
|
-
|
84
|
-
it_behaves_like "policy object class" do
|
85
|
-
subject { described_class.new namespace, policy_name, :foo, :bar, :baz }
|
86
|
-
end
|
87
|
-
|
88
|
-
end # describe #policy
|
89
|
-
|
90
|
-
describe "#attributes" do
|
91
|
-
|
92
|
-
let(:attributes) { %i(foo bar) }
|
93
|
-
subject { described_class.new nil, policy_class, :foo, *attributes }
|
94
|
-
|
95
|
-
it "is set by the initializer" do
|
96
|
-
expect(subject.attributes).to eq attributes
|
97
|
-
end
|
98
|
-
|
99
|
-
end # describe #attributes
|
100
|
-
|
101
|
-
describe "#apply_to" do
|
102
|
-
|
103
|
-
let(:attributes) { { foo: :bar, bar: :baz } }
|
104
|
-
let(:follower) { OpenStruct.new(attributes) }
|
105
|
-
|
106
|
-
subject do
|
107
|
-
described_class.new nil, policy_class, nil, *attributes.keys
|
108
|
-
end
|
109
|
-
|
110
|
-
it "calls policy_class validation with follower attributes" do
|
111
|
-
expect(policy_class).to receive(:apply).with(*attributes.values)
|
112
|
-
subject.apply_to(follower)
|
113
|
-
end
|
114
|
-
|
115
|
-
end # describe #apply_to
|
116
|
-
|
117
|
-
end # describe Policy::Follower::Policy
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
describe Policy::Follower::Names do
|
4
|
-
|
5
|
-
describe ".from" do
|
6
|
-
|
7
|
-
shared_examples "normalizing from" do |*source|
|
8
|
-
|
9
|
-
subject { described_class.from(*source) }
|
10
|
-
it { is_expected.to eq %i(foo bar baz foo) }
|
11
|
-
|
12
|
-
end # shared examples
|
13
|
-
|
14
|
-
it_behaves_like "normalizing from", %w(foo bar baz foo)
|
15
|
-
it_behaves_like "normalizing from", *%w(foo bar baz foo)
|
16
|
-
|
17
|
-
end # describe .from
|
18
|
-
|
19
|
-
end # describe Policy::Follower::Names
|
@@ -1,220 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
describe Policy::Follower do
|
4
|
-
|
5
|
-
before { Test = Class.new.__send__(:include, described_class) }
|
6
|
-
after { Object.send :remove_const, :Test }
|
7
|
-
|
8
|
-
let(:test_class) { Test }
|
9
|
-
subject { test_class.new }
|
10
|
-
|
11
|
-
it "includes Policy::Validations" do
|
12
|
-
expect(test_class).to include Policy::Validations
|
13
|
-
end
|
14
|
-
|
15
|
-
describe ".followed_policies" do
|
16
|
-
|
17
|
-
let(:followed_policies) { Policy::Follower::FollowedPolicies }
|
18
|
-
|
19
|
-
it "returns the AppiedPolicies object" do
|
20
|
-
expect(test_class.followed_policies).to be_kind_of followed_policies
|
21
|
-
end
|
22
|
-
|
23
|
-
end # describe .followed_policies
|
24
|
-
|
25
|
-
describe ".follow_policy" do
|
26
|
-
|
27
|
-
let(:followed_policy) { Policy::Follower::FollowedPolicy }
|
28
|
-
|
29
|
-
let(:policy) { double name: :foo }
|
30
|
-
let(:policy_class) { double }
|
31
|
-
let(:name) { double }
|
32
|
-
let(:attributes) { [double, double] }
|
33
|
-
|
34
|
-
before { allow(followed_policy).to receive(:new) { policy } }
|
35
|
-
|
36
|
-
context "by default" do
|
37
|
-
|
38
|
-
after { test_class.follow_policy policy_class, *attributes }
|
39
|
-
|
40
|
-
it "creates new followed policy" do
|
41
|
-
expect(followed_policy)
|
42
|
-
.to receive(:new)
|
43
|
-
.with(test_class, policy_class, nil, *attributes)
|
44
|
-
end
|
45
|
-
|
46
|
-
it "adds new policy to .followed_policies" do
|
47
|
-
expect(test_class.followed_policies).to receive(:add).with(policy)
|
48
|
-
end
|
49
|
-
|
50
|
-
end # context
|
51
|
-
|
52
|
-
context "as: name" do
|
53
|
-
|
54
|
-
after { test_class.follow_policy(policy_class, *attributes, as: name) }
|
55
|
-
|
56
|
-
it "creates named followed policy" do
|
57
|
-
expect(followed_policy)
|
58
|
-
.to receive(:new)
|
59
|
-
.with(test_class, policy_class, name, *attributes)
|
60
|
-
end
|
61
|
-
|
62
|
-
end # context
|
63
|
-
|
64
|
-
context "inside #use_policies" do
|
65
|
-
|
66
|
-
let(:namespace) { double }
|
67
|
-
|
68
|
-
subject do
|
69
|
-
test_class.use_policies namespace do
|
70
|
-
follow_policy :foo, as: :bar
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
it "sends the namespace to followed policy" do
|
75
|
-
expect(followed_policy)
|
76
|
-
.to receive(:new).with(namespace, :foo, :bar)
|
77
|
-
subject
|
78
|
-
end
|
79
|
-
|
80
|
-
it "doesn't change default namespace" do
|
81
|
-
subject
|
82
|
-
expect(followed_policy)
|
83
|
-
.to receive(:new).with(test_class, :foo, :bar)
|
84
|
-
test_class.follow_policy :foo, as: :bar
|
85
|
-
end
|
86
|
-
|
87
|
-
end # context
|
88
|
-
|
89
|
-
end # describe .follow_policy
|
90
|
-
|
91
|
-
describe "#follow_policies!" do
|
92
|
-
|
93
|
-
context "without names" do
|
94
|
-
|
95
|
-
after { subject.follow_policies! }
|
96
|
-
|
97
|
-
it "applies .followed_policies to itself" do
|
98
|
-
expect(test_class.followed_policies)
|
99
|
-
.to receive(:apply_to).with(subject)
|
100
|
-
end
|
101
|
-
|
102
|
-
end # context
|
103
|
-
|
104
|
-
context "with names" do
|
105
|
-
|
106
|
-
let(:names) { %i(foo bar baz) }
|
107
|
-
after { subject.follow_policies!(*names) }
|
108
|
-
|
109
|
-
it "applies .followed_policies to itself with names" do
|
110
|
-
expect(test_class.followed_policies)
|
111
|
-
.to receive(:apply_to).with(subject, *names)
|
112
|
-
end
|
113
|
-
|
114
|
-
end # context
|
115
|
-
|
116
|
-
context "when a ViolationError is raised" do
|
117
|
-
|
118
|
-
let(:error) { Policy::ViolationError.allocate }
|
119
|
-
let(:messages) { %w(foo bar baz) }
|
120
|
-
|
121
|
-
before do
|
122
|
-
allow(error).to receive(:messages) { messages }
|
123
|
-
allow(test_class.followed_policies).to receive(:apply_to) { fail error }
|
124
|
-
end
|
125
|
-
|
126
|
-
it "populates messages with errors" do
|
127
|
-
expect { subject.follow_policies! rescue nil }
|
128
|
-
.to change { subject.__send__(:errors).messages }
|
129
|
-
.to(base: messages)
|
130
|
-
end
|
131
|
-
|
132
|
-
it "re-raises the exception" do
|
133
|
-
expect { subject.follow_policies! }.to raise_error(error)
|
134
|
-
end
|
135
|
-
|
136
|
-
end # context
|
137
|
-
|
138
|
-
end # describe #follow_policies!
|
139
|
-
|
140
|
-
describe "#follow_policies?" do
|
141
|
-
|
142
|
-
before { allow(subject).to receive(:follow_policies!) }
|
143
|
-
|
144
|
-
it "calls #follow_policies! without names" do
|
145
|
-
expect(subject).to receive(:follow_policies!)
|
146
|
-
subject.follow_policies?
|
147
|
-
end
|
148
|
-
|
149
|
-
it "calls #follow_policies! with names" do
|
150
|
-
names = %i(foo bar baz)
|
151
|
-
|
152
|
-
expect(subject).to receive(:follow_policies!).with(*names)
|
153
|
-
subject.follow_policies?(*names)
|
154
|
-
end
|
155
|
-
|
156
|
-
context "wheh #follow_policies! doesn't raise an error" do
|
157
|
-
|
158
|
-
before { allow(subject).to receive(:follow_policies!) { nil } }
|
159
|
-
|
160
|
-
it "returns true" do
|
161
|
-
expect(subject.follow_policies?).to eq true
|
162
|
-
end
|
163
|
-
|
164
|
-
end # context
|
165
|
-
|
166
|
-
context "wheh #folow_policies! raises ViolationError" do
|
167
|
-
|
168
|
-
let(:error) { Policy::ViolationError.allocate }
|
169
|
-
before { allow(subject).to receive(:follow_policies!) { fail error } }
|
170
|
-
|
171
|
-
it "returns false" do
|
172
|
-
expect(subject.follow_policies?).to eq false
|
173
|
-
end
|
174
|
-
|
175
|
-
end # context
|
176
|
-
|
177
|
-
context "wheh #follow_policies! raises RuntimeError" do
|
178
|
-
|
179
|
-
let(:error) { StandardError.allocate }
|
180
|
-
before { allow(subject).to receive(:follow_policies!) { fail error } }
|
181
|
-
|
182
|
-
it "fails" do
|
183
|
-
expect { subject.follow_policies? }.to raise_error(error)
|
184
|
-
end
|
185
|
-
|
186
|
-
end # context
|
187
|
-
|
188
|
-
end # describe #follow_policies?
|
189
|
-
|
190
|
-
describe "#follow_policy!" do
|
191
|
-
|
192
|
-
before { allow(subject).to receive(:follow_policies!) }
|
193
|
-
|
194
|
-
it "is an alias for #follow_policies!" do
|
195
|
-
expect(subject).to receive(:follow_policies!).with :foo
|
196
|
-
subject.follow_policy! :foo
|
197
|
-
end
|
198
|
-
|
199
|
-
it "requires an argument" do
|
200
|
-
expect(subject.method(:follow_policy!).arity).to eq 1
|
201
|
-
end
|
202
|
-
|
203
|
-
end # describe #follow_policy!
|
204
|
-
|
205
|
-
describe "#follow_policy?" do
|
206
|
-
|
207
|
-
before { allow(subject).to receive(:follow_policies?) }
|
208
|
-
|
209
|
-
it "is an alias for #follow_policies?" do
|
210
|
-
expect(subject).to receive(:follow_policies?).with :foo
|
211
|
-
subject.follow_policy? :foo
|
212
|
-
end
|
213
|
-
|
214
|
-
it "requires an argument" do
|
215
|
-
expect(subject.method(:follow_policy?).arity).to eq 1
|
216
|
-
end
|
217
|
-
|
218
|
-
end # describe #follow_policy?
|
219
|
-
|
220
|
-
end # describe Policy::Follower
|