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.
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