policy 1.2.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/Guardfile +4 -4
  3. data/README.md +177 -78
  4. data/config/metrics/flay.yml +1 -1
  5. data/config/metrics/roodi.yml +2 -2
  6. data/lib/policy.rb +52 -33
  7. data/lib/policy/base.rb +122 -0
  8. data/lib/policy/base/and.rb +38 -0
  9. data/lib/policy/base/negator.rb +52 -0
  10. data/lib/policy/base/node.rb +59 -0
  11. data/lib/policy/base/not.rb +42 -0
  12. data/lib/policy/base/or.rb +39 -0
  13. data/lib/policy/base/xor.rb +39 -0
  14. data/lib/policy/cli.rb +8 -3
  15. data/lib/policy/cli/attribute.rb +49 -0
  16. data/lib/policy/cli/locale.erb +1 -2
  17. data/lib/policy/cli/policy.erb +33 -6
  18. data/lib/policy/cli/spec.erb +31 -11
  19. data/lib/policy/follower.rb +54 -94
  20. data/lib/policy/follower/name_error.rb +53 -0
  21. data/lib/policy/follower/policies.rb +104 -0
  22. data/lib/policy/follower/violation_error.rb +60 -0
  23. data/lib/policy/version.rb +2 -2
  24. data/policy.gemspec +2 -3
  25. data/spec/support/composer.rb +28 -0
  26. data/spec/tests/lib/policy/base/and_spec.rb +62 -0
  27. data/spec/tests/lib/policy/base/negator_spec.rb +49 -0
  28. data/spec/tests/lib/policy/base/not_spec.rb +50 -0
  29. data/spec/tests/lib/policy/base/or_spec.rb +62 -0
  30. data/spec/tests/lib/policy/base/xor_spec.rb +73 -0
  31. data/spec/tests/lib/policy/base_spec.rb +123 -0
  32. data/spec/tests/lib/policy/cli/attribute_spec.rb +52 -0
  33. data/spec/tests/{policy → lib/policy}/cli_spec.rb +25 -24
  34. data/spec/tests/lib/policy/follower/name_error_spec.rb +51 -0
  35. data/spec/tests/lib/policy/follower/policies_spec.rb +156 -0
  36. data/spec/tests/lib/policy/follower/violation_error_spec.rb +60 -0
  37. data/spec/tests/lib/policy/follower_spec.rb +153 -0
  38. data/spec/tests/lib/policy_spec.rb +52 -0
  39. metadata +43 -44
  40. data/lib/policy/follower/followed_policies.rb +0 -45
  41. data/lib/policy/follower/followed_policy.rb +0 -104
  42. data/lib/policy/follower/names.rb +0 -29
  43. data/lib/policy/interface.rb +0 -48
  44. data/lib/policy/validations.rb +0 -28
  45. data/lib/policy/violation_error.rb +0 -52
  46. data/spec/features/follower_spec.rb +0 -95
  47. data/spec/tests/policy/follower/followed_policies_spec.rb +0 -87
  48. data/spec/tests/policy/follower/followed_policy_spec.rb +0 -117
  49. data/spec/tests/policy/follower/names_spec.rb +0 -19
  50. data/spec/tests/policy/follower_spec.rb +0 -220
  51. data/spec/tests/policy/interface_spec.rb +0 -83
  52. data/spec/tests/policy/validations_spec.rb +0 -13
  53. data/spec/tests/policy/violation_error_spec.rb +0 -75
  54. data/spec/tests/policy_spec.rb +0 -35
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+
3
+ describe Policy do
4
+
5
+ let(:one) { double :one }
6
+ let(:two) { double :two }
7
+
8
+ describe ".and" do
9
+
10
+ let(:composer) { Policy::Base::And }
11
+
12
+ it "composes policies with And composer" do
13
+ expect(composer).to receive(:new).with(one, two)
14
+ described_class.and one, two
15
+ end
16
+
17
+ end # describe .and
18
+
19
+ describe ".or" do
20
+
21
+ let(:composer) { Policy::Base::Or }
22
+
23
+ it "composes policies with Or composer" do
24
+ expect(composer).to receive(:new).with(one, two)
25
+ described_class.or one, two
26
+ end
27
+
28
+ end # describe .or
29
+
30
+ describe ".xor" do
31
+
32
+ let(:composer) { Policy::Base::Xor }
33
+
34
+ it "composes policies with Xor composer" do
35
+ expect(composer).to receive(:new).with(one, two)
36
+ described_class.xor one, two
37
+ end
38
+
39
+ end # describe .xor
40
+
41
+ describe ".not" do
42
+
43
+ let(:composer) { Policy::Base::Not }
44
+
45
+ it "composes policies with Not composer" do
46
+ expect(composer).to receive(:new).with(one)
47
+ described_class.not one
48
+ end
49
+
50
+ end # describe .not
51
+
52
+ end # describe Policy
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: policy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kozin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-18 00:00:00.000000000 Z
11
+ date: 2015-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.1'
27
- - !ruby/object:Gem::Dependency
28
- name: adamantium
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '0.2'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '0.2'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: hexx-cli
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -45,7 +31,7 @@ dependencies:
45
31
  - - "~>"
46
32
  - !ruby/object:Gem::Version
47
33
  version: '0.0'
48
- type: :runtime
34
+ type: :development
49
35
  prerelease: false
50
36
  version_requirements: !ruby/object:Gem::Requirement
51
37
  requirements:
@@ -66,7 +52,7 @@ dependencies:
66
52
  - - "~>"
67
53
  - !ruby/object:Gem::Version
68
54
  version: '0.3'
69
- description: A tiny library implementing the Policy Object pattern.
55
+ description: A small library implementing the Policy Object pattern.
70
56
  email: andrew.kozin@gmail.com
71
57
  executables:
72
58
  - policy
@@ -101,31 +87,40 @@ files:
101
87
  - config/metrics/simplecov.yml
102
88
  - config/metrics/yardstick.yml
103
89
  - lib/policy.rb
90
+ - lib/policy/base.rb
91
+ - lib/policy/base/and.rb
92
+ - lib/policy/base/negator.rb
93
+ - lib/policy/base/node.rb
94
+ - lib/policy/base/not.rb
95
+ - lib/policy/base/or.rb
96
+ - lib/policy/base/xor.rb
104
97
  - lib/policy/cli.rb
98
+ - lib/policy/cli/attribute.rb
105
99
  - lib/policy/cli/locale.erb
106
100
  - lib/policy/cli/policy.erb
107
101
  - lib/policy/cli/spec.erb
108
102
  - lib/policy/follower.rb
109
- - lib/policy/follower/followed_policies.rb
110
- - lib/policy/follower/followed_policy.rb
111
- - lib/policy/follower/names.rb
112
- - lib/policy/interface.rb
113
- - lib/policy/validations.rb
103
+ - lib/policy/follower/name_error.rb
104
+ - lib/policy/follower/policies.rb
105
+ - lib/policy/follower/violation_error.rb
114
106
  - lib/policy/version.rb
115
- - lib/policy/violation_error.rb
116
107
  - policy.gemspec
117
- - spec/features/follower_spec.rb
118
108
  - spec/spec_helper.rb
109
+ - spec/support/composer.rb
119
110
  - spec/tests/bin/policy_spec.rb
120
- - spec/tests/policy/cli_spec.rb
121
- - spec/tests/policy/follower/followed_policies_spec.rb
122
- - spec/tests/policy/follower/followed_policy_spec.rb
123
- - spec/tests/policy/follower/names_spec.rb
124
- - spec/tests/policy/follower_spec.rb
125
- - spec/tests/policy/interface_spec.rb
126
- - spec/tests/policy/validations_spec.rb
127
- - spec/tests/policy/violation_error_spec.rb
128
- - spec/tests/policy_spec.rb
111
+ - spec/tests/lib/policy/base/and_spec.rb
112
+ - spec/tests/lib/policy/base/negator_spec.rb
113
+ - spec/tests/lib/policy/base/not_spec.rb
114
+ - spec/tests/lib/policy/base/or_spec.rb
115
+ - spec/tests/lib/policy/base/xor_spec.rb
116
+ - spec/tests/lib/policy/base_spec.rb
117
+ - spec/tests/lib/policy/cli/attribute_spec.rb
118
+ - spec/tests/lib/policy/cli_spec.rb
119
+ - spec/tests/lib/policy/follower/name_error_spec.rb
120
+ - spec/tests/lib/policy/follower/policies_spec.rb
121
+ - spec/tests/lib/policy/follower/violation_error_spec.rb
122
+ - spec/tests/lib/policy/follower_spec.rb
123
+ - spec/tests/lib/policy_spec.rb
129
124
  homepage: https://github.com/nepalez/policy
130
125
  licenses:
131
126
  - MIT
@@ -152,15 +147,19 @@ specification_version: 4
152
147
  summary: Policy Objects for Ruby.
153
148
  test_files:
154
149
  - spec/spec_helper.rb
155
- - spec/tests/policy_spec.rb
150
+ - spec/tests/lib/policy_spec.rb
151
+ - spec/tests/lib/policy/base/or_spec.rb
152
+ - spec/tests/lib/policy/base/and_spec.rb
153
+ - spec/tests/lib/policy/base/xor_spec.rb
154
+ - spec/tests/lib/policy/base/negator_spec.rb
155
+ - spec/tests/lib/policy/base/not_spec.rb
156
+ - spec/tests/lib/policy/cli_spec.rb
157
+ - spec/tests/lib/policy/follower_spec.rb
158
+ - spec/tests/lib/policy/cli/attribute_spec.rb
159
+ - spec/tests/lib/policy/base_spec.rb
160
+ - spec/tests/lib/policy/follower/violation_error_spec.rb
161
+ - spec/tests/lib/policy/follower/name_error_spec.rb
162
+ - spec/tests/lib/policy/follower/policies_spec.rb
156
163
  - spec/tests/bin/policy_spec.rb
157
- - spec/tests/policy/cli_spec.rb
158
- - spec/tests/policy/follower_spec.rb
159
- - spec/tests/policy/interface_spec.rb
160
- - spec/tests/policy/validations_spec.rb
161
- - spec/tests/policy/follower/followed_policies_spec.rb
162
- - spec/tests/policy/follower/followed_policy_spec.rb
163
- - spec/tests/policy/follower/names_spec.rb
164
- - spec/tests/policy/violation_error_spec.rb
165
- - spec/features/follower_spec.rb
164
+ - spec/support/composer.rb
166
165
  has_rdoc:
@@ -1,45 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Policy
4
-
5
- module Follower
6
-
7
- # Describes the list of followed policies
8
- #
9
- # @api private
10
- class FollowedPolicies < Hash
11
-
12
- # Registers followed policy with given unique key
13
- #
14
- # @param [Policy::Follower::FollowedPolicy] policy
15
- #
16
- # @return [undefined]
17
- def add(policy)
18
- self[policy.name] = policy
19
- end
20
-
21
- # Applies to follower the policies, selected by names
22
- #
23
- # @param [Policy::Follower] follower
24
- # @param [Array<#to_s>] names
25
- #
26
- # @raise [Policy::ViolationError]
27
- # unless all policies are met
28
- #
29
- # @return [undefined]
30
- def apply_to(follower, *names)
31
- named_by(names).each { |policy| policy.apply_to(follower) }
32
- end
33
-
34
- private
35
-
36
- def named_by(list)
37
- names = Names.from list
38
- names.any? ? names.map(&method(:[])).compact : values
39
- end
40
-
41
- end # class FollowedPolicies
42
-
43
- end # module Follower
44
-
45
- end # module Policy
@@ -1,104 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Policy
4
-
5
- module Follower
6
-
7
- # Stores the policy to be applied to all instances of the follower
8
- #
9
- # The policy object can be set either as a constant, or by name
10
- # in given namespace. Namespace and policy name can be set separately.
11
- #
12
- # The separation is used at the {Policy::Follower#apply_policies}.
13
- #
14
- # @example The policy can be constant
15
- # FollowedPolicy.new nil, Foo::Bar::Baz, :baz_policy, :baz
16
- #
17
- # @example The policy can be name, relative to the namespace
18
- # FollowedPolicy.new Foo::Bar, :Baz, :baz_policy, :baz
19
- # # Foo::Bar::Baz policy object will be used
20
- #
21
- # @api private
22
- class FollowedPolicy
23
-
24
- # @!scope class
25
- # @!method new(namespace, policy, name, *attributes)
26
- # Creates the immutable policy to be followed by given object
27
- #
28
- # @param [Module] namespace
29
- # the namespace for the policy, given by name
30
- # @param [Class, #to_s] policy
31
- # the class for applicable policy
32
- # @param [#to_sym, nil] name
33
- # the name for the policy
34
- # @param [Array<Symbol>] attributes
35
- # the list of follower attributes to apply the policy to
36
- #
37
- # @return [Policy::Follower::FollowedPolicy]
38
- # immutable object
39
- def initialize(namespace, policy, name, *attributes)
40
- @policy = find_policy(namespace, policy)
41
- @name = (name || SecureRandom.uuid).to_sym
42
- @attributes = check_attributes attributes
43
- end
44
-
45
- # @!attribute [r] name
46
- # The name for the policy
47
- #
48
- # @return [Symbol]
49
- attr_reader :name
50
-
51
- # @!attribute [r] policy
52
- # The policy object class to be followed
53
- #
54
- # @return [Class]
55
- attr_reader :policy
56
-
57
- # @!attribute [r] attributes
58
- # The list of follower attributes to be send to the policy object
59
- #
60
- # @return [Array<Symbol>]
61
- attr_reader :attributes
62
-
63
- # Applies the policy to follower instance
64
- #
65
- # @param [Policy::Follower]
66
- # follower
67
- #
68
- # @raise [Policy::ViolationError]
69
- # it the follower doesn't meet the policy
70
- #
71
- # @return [undefined]
72
- def apply_to(follower)
73
- policy.apply(*attributes_of(follower))
74
- end
75
-
76
- private
77
-
78
- def find_policy(namespace, policy)
79
- return policy if policy.instance_of?(Class)
80
- instance_eval [namespace, policy].join("::")
81
- end
82
-
83
- def attributes_of(follower)
84
- attributes.map(&follower.method(:send))
85
- end
86
-
87
- def check_attributes(attributes)
88
- number = policy.members.count
89
- return attributes if attributes.count.equal?(number)
90
- fail wrong_number(number, attributes)
91
- end
92
-
93
- def wrong_number(number, attributes)
94
- ArgumentError.new [
95
- "#{ policy } requires #{ number } attribute(s).",
96
- "#{ attributes } cannot be assigned."
97
- ].join(" ")
98
- end
99
-
100
- end # class FollowedPolicy
101
-
102
- end # module Follower
103
-
104
- end # module Policy
@@ -1,29 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Policy
4
-
5
- module Follower
6
-
7
- # Converter of items to array of unique symbols
8
- #
9
- # @api private
10
- module Names
11
-
12
- # Converts items to array of unique symbols
13
- #
14
- # @example
15
- # Policy::Follower::Names.from "foo", [:foo, "bar"], "baz"
16
- # # => [:foo, :bar, :baz]
17
- #
18
- # @param [Array<#to_sym>] items
19
- #
20
- # @return [Array<Symbol>]
21
- def self.from(*items)
22
- items.flatten.map(&:to_sym)
23
- end
24
-
25
- end
26
-
27
- end
28
-
29
- end
@@ -1,48 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Policy
4
-
5
- # Policy object interface
6
- module Interface
7
-
8
- # @private
9
- def self.included(klass)
10
- klass.extend(ClassMethods).__send__(:include, Validations)
11
- end
12
-
13
- # Container for the policy class methods
14
- module ClassMethods
15
-
16
- # Creates and validates the policy object
17
- #
18
- # @param (see Policy.new)
19
- #
20
- # @raise (see Policy::Interface#apply)
21
- #
22
- # @return [undefined]
23
- def apply(*attributes)
24
- new(*attributes).apply
25
- end
26
-
27
- end
28
-
29
- # Returns the list of error messages
30
- #
31
- # @return [Array<String>]
32
- def messages
33
- errors.messages.values.flatten
34
- end
35
-
36
- # Validates the policy object
37
- #
38
- # @raise [ViolationError]
39
- # if a policy is invalid
40
- #
41
- # @return [undefined]
42
- def apply
43
- fail ViolationError.new(self) unless valid?
44
- end
45
-
46
- end # class Interface
47
-
48
- end # module Policy
@@ -1,28 +0,0 @@
1
- # encoding: utf-8
2
- require "active_model"
3
-
4
- module Policy
5
-
6
- # Wrapper around the ActiveModel::Validations
7
- #
8
- # Provides shared interface for [Policy::Inteface] and [Policy::Follower].
9
- #
10
- # @todo Implement it later from scratch without excessive features
11
- #
12
- # @example
13
- # MyClass.include, Policy::Validations
14
- #
15
- # @private
16
- module Validations
17
-
18
- # The implementation for validations
19
- IMPLEMENTATION = ActiveModel::Validations
20
-
21
- # @private
22
- def self.included(klass)
23
- klass.__send__(:include, IMPLEMENTATION)
24
- end
25
-
26
- end # module Validations
27
-
28
- end # module Policy