tram-policy 1.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 54f65bae74cb48be0cc7d481cb3abd8528f43749
4
- data.tar.gz: 4a100e49ec40986bc4f8781304169e6ecd2d5baf
2
+ SHA256:
3
+ metadata.gz: 3bf029c2eff265f0a29f13d7f1c44b8f8a1a9d5a336a61a9804c9740142eba17
4
+ data.tar.gz: ccee1509e523eeb4e55208b357e561f03100844d32ec3a14d879ad6991b8f538
5
5
  SHA512:
6
- metadata.gz: 107d99cdd79742b7ae85b5b1f8783f5eb6114c864cbfb7732251c2a4542261effec81ec171d61dbc0da6787ca576efc581dae43f76f75ef4a16d2d7934edea9f
7
- data.tar.gz: 3dc2b45735369a9097b525b1681ea8dee24ed84675bc8cfde67b1f87394647f345abedd45db4c12d3725d3cd56df8193e70b8c92e5ec62e9e1c14970097c6ee8
6
+ metadata.gz: d193c0d20344f0ab8c2b015e7a5eee330ef4fec64182c298ad750b06081894d6d8f51d89c064bc8aa7561e7f8d68ccd3f03f55a4378677781ba0bdf4e8376cd0
7
+ data.tar.gz: 0b0214db5420f51dadb31028d1a75b2cb54b762ccf013d6948a6eb47fb2b6ca4825dfe747921b80aa732de0b27e89faf74a353a005a5c0237c0267df8681a421
data/.gitignore CHANGED
@@ -9,3 +9,4 @@
9
9
  /tmp/
10
10
  /*.gem
11
11
  .rspec_status
12
+ .idea/
data/.travis.yml CHANGED
@@ -8,18 +8,15 @@ script:
8
8
  - bundle exec rubocop
9
9
  rvm:
10
10
  - 2.3.0
11
- - 2.4.0
11
+ - 2.6.2
12
12
  - ruby-head
13
- - jruby-9.1.0.0
14
- - rbx-3
13
+ - jruby-9.2.7.0
14
+ - truffleruby
15
15
  env:
16
16
  global:
17
17
  - JRUBY_OPTS='--dev -J-Xmx1024M'
18
18
  matrix:
19
19
  allow_failures:
20
- - rvm: rbx-3
21
20
  - rvm: ruby-head
22
21
  - rvm: jruby-head
23
- include:
24
- - rvm: jruby-head
25
- before_install: gem install bundler --no-ri --no-rdoc
22
+ - rvm: truffleruby
data/CHANGELOG.md CHANGED
@@ -4,6 +4,35 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/).
6
6
 
7
+ ## [2.1.0] - [2021-11-30]
8
+
9
+ ### Fixed
10
+ - Difference between last positional and keyword arguments in Ruby 3.0+ (mrexox)
11
+
12
+ ## [2.0.1] - [2019-11-14]
13
+
14
+ ### Fixed
15
+ - Allow translation :scope to be customized in the #merge operation (sclinede)
16
+ Before the fix, the customized value was always replaced by the default value.
17
+
18
+ ## [2.0.0] - [2019-07-04]
19
+
20
+ ### Changed
21
+
22
+ - [BREAKING] separate `Tram::Policy::Errors` from a policy (nepalez, sclinede)
23
+
24
+ Instead of the policy, the collection refers to the explicit scope used for error messages' translation.
25
+ This change breaks the signature of `Tram::Policy::Error` and `Tram::Policy::Errors`.
26
+
27
+ ## [1.0.1] - [2019-05-06]
28
+
29
+ ### Added
30
+ - Support of `dry-initializer` v3.0+ (nepalez)
31
+
32
+ ### Fixed
33
+ - Fix be_invalid RSpec matcher if non-policy model is passed (Envek)
34
+ - Disable translation check for non-strings in rspec matcher (Envek)
35
+
7
36
  ## [1.0.0] - [2018-02-17]
8
37
 
9
38
  ### Changed
@@ -191,3 +220,8 @@ This is a first public release (@nepalez, @charlie-wasp, @JewelSam, @sergey-chec
191
220
  [0.3.0]: https://github.com/tram-rb/tram-policy/compare/v0.2.5...v0.3.0
192
221
  [0.3.1]: https://github.com/tram-rb/tram-policy/compare/v0.3.0...v0.3.1
193
222
  [0.4.0]: https://github.com/tram-rb/tram-policy/compare/v0.3.1...v0.4.0
223
+ [1.0.0]: https://github.com/tram-rb/tram-policy/compare/v0.4.0...v1.0.0
224
+ [1.0.1]: https://github.com/tram-rb/tram-policy/compare/v1.0.0...v1.0.1
225
+ [2.0.0]: https://github.com/tram-rb/tram-policy/compare/v1.0.1...v2.0.0
226
+ [2.0.1]: https://github.com/tram-rb/tram-policy/compare/v2.0.0...v2.0.1
227
+ [2.1.0]: https://github.com/tram-rb/tram-policy/compare/v2.0.1...v2.1.0
data/README.md CHANGED
@@ -7,7 +7,6 @@ Policy Object Pattern
7
7
 
8
8
  [![Gem Version][gem-badger]][gem]
9
9
  [![Build Status][travis-badger]][travis]
10
- [![Dependency Status][gemnasium-badger]][gemnasium]
11
10
  [![Inline docs][inch-badger]][inch]
12
11
 
13
12
  ## Intro
@@ -128,7 +127,7 @@ You can change the root scope if you will (this could be useful in libraries):
128
127
 
129
128
  ```ruby
130
129
  class MyGemPolicy < Tram::Policy
131
- scope "mygem", "policies" # inherited by subclasses
130
+ root_scope "mygem", "policies" # inherited by subclasses
132
131
  end
133
132
 
134
133
  class Article::ReadinessPolicy < MyGemPolicy
@@ -338,8 +337,6 @@ The gem is available as open source under the terms of the [MIT License](http://
338
337
  [codeclimate]: https://codeclimate.com/github/tram-rb/tram-policy
339
338
  [gem-badger]: https://img.shields.io/gem/v/tram-policy.svg?style=flat
340
339
  [gem]: https://rubygems.org/gems/tram-policy
341
- [gemnasium-badger]: https://img.shields.io/gemnasium/tram-rb/tram-policy.svg?style=flat
342
- [gemnasium]: https://gemnasium.com/tram-rb/tram-policy
343
340
  [inch-badger]: http://inch-ci.org/github/tram-rb/tram-policy.svg
344
341
  [inch]: https://inch-ci.org/github/tram-rb/tram-policy
345
342
  [travis-badger]: https://img.shields.io/travis/tram-rb/tram-policy/master.svg?style=flat
@@ -18,8 +18,8 @@ class Tram::Policy
18
18
  # @param [Object] *args
19
19
  # @return [Tram::Policy]
20
20
  #
21
- def [](*args)
22
- new(*args)
21
+ def [](*args, **kwargs)
22
+ new(*args, **kwargs)
23
23
  end
24
24
 
25
25
  # Sets the root scope of the policy and its subclasses
@@ -12,10 +12,10 @@ class Tram::Policy
12
12
  # If another error is send to the constructor, the error returned unchanged
13
13
  #
14
14
  # @param [Tram::Policy::Error, #to_s] value
15
- # @param [Hash<Symbol, Object>] opts
15
+ # @param [Hash<Symbol, Object>] tags
16
16
  # @return [Tram::Policy::Error]
17
17
  #
18
- def self.new(value, **opts)
18
+ def self.new(value, **tags)
19
19
  value.instance_of?(self) ? value : super
20
20
  end
21
21
 
@@ -27,7 +27,7 @@ class Tram::Policy
27
27
  # @return [Hash<Symbol, Object>] error tags
28
28
  attr_reader :tags
29
29
 
30
- # The list of arguments for [I18n.t]
30
+ # List of arguments for [I18n.t]
31
31
  #
32
32
  # @return [Array]
33
33
  #
@@ -36,7 +36,7 @@ class Tram::Policy
36
36
  end
37
37
  alias to_a item
38
38
 
39
- # The text of error message translated to the current locale
39
+ # Text of error message translated to the current locale
40
40
  #
41
41
  # @return [String]
42
42
  #
@@ -60,8 +60,8 @@ class Tram::Policy
60
60
  # @param [Proc] block
61
61
  # @return [Object]
62
62
  #
63
- def fetch(tag, default = Dry::Initializer::UNDEFINED, &block)
64
- if default == Dry::Initializer::UNDEFINED
63
+ def fetch(tag, default = UNDEFINED, &block)
64
+ if default == UNDEFINED
65
65
  tags.fetch(tag.to_sym, &block)
66
66
  else
67
67
  tags.fetch(tag.to_sym, default, &block)
@@ -92,17 +92,21 @@ class Tram::Policy
92
92
 
93
93
  private
94
94
 
95
+ UNDEFINED = Dry::Initializer::UNDEFINED
96
+ DEFAULT_SCOPE = %w[tram-policy errors].freeze
97
+
95
98
  def initialize(key, **tags)
96
99
  @key = key
97
100
  @tags = tags
101
+ @tags[:scope] = @tags.fetch(:scope) { DEFAULT_SCOPE } if key.is_a?(Symbol)
98
102
  end
99
103
 
100
104
  def respond_to_missing?(*)
101
105
  true
102
106
  end
103
107
 
104
- def method_missing(name, *args, &block)
105
- args.any? || block ? super : tags[name]
108
+ def method_missing(name, *args, **kwargs, &block)
109
+ args.any? || kwargs.any? || block ? super : tags[name]
106
110
  end
107
111
  end
108
112
  end
@@ -1,4 +1,5 @@
1
1
  class Tram::Policy
2
+ #
2
3
  # Enumerable collection of unique unordered validation errors
3
4
  #
4
5
  # Notice: A collection is context-dependent;
@@ -8,11 +9,9 @@ class Tram::Policy
8
9
  class Errors
9
10
  include Enumerable
10
11
 
11
- # @!attribute [r] policy
12
- #
13
- # @return [Tram::Policy] the poplicy errors provided by
14
- #
15
- attr_reader :policy
12
+ # @!attribute [r] scope
13
+ # @return [Array<String>] the scope for error messages' translation
14
+ attr_reader :scope
16
15
 
17
16
  # @!method add(message, tags)
18
17
  # Adds error message to the collection
@@ -22,9 +21,12 @@ class Tram::Policy
22
21
  # @return [self] the collection
23
22
  #
24
23
  def add(message, **tags)
25
- tags = tags.merge(scope: policy.scope) unless tags.key?(:scope)
26
24
  raise ArgumentError.new("Error message should be defined") unless message
27
- tap { @set << Tram::Policy::Error.new(message, **tags) }
25
+
26
+ tap do
27
+ tags = { scope: scope }.merge(tags) if message.is_a?(Symbol)
28
+ @set << Tram::Policy::Error.new(message, **tags)
29
+ end
28
30
  end
29
31
 
30
32
  # Iterates by collected errors
@@ -47,7 +49,7 @@ class Tram::Policy
47
49
  list = each_with_object(Set.new) do |error, obj|
48
50
  obj << error if error.contain?(key, tags)
49
51
  end
50
- self.class.new(policy, list)
52
+ self.class.new(scope: scope, errors: list)
51
53
  end
52
54
 
53
55
  # @!method empty?
@@ -101,9 +103,9 @@ class Tram::Policy
101
103
 
102
104
  private
103
105
 
104
- def initialize(policy, errors = [])
105
- @policy = policy
106
- @set = Set.new(errors)
106
+ def initialize(**options)
107
+ @scope = options[:scope] || Error::DEFAULT_SCOPE
108
+ @set = Set.new options[:errors].to_a
107
109
  end
108
110
  end
109
111
  end
@@ -17,8 +17,11 @@ RSpec::Matchers.define :be_invalid_at do |**tags|
17
17
 
18
18
  def missed_translations
19
19
  @missed_translations ||= \
20
- errors.flat_map { |rec| rec.values_at(*locales) }
21
- .select { |message| message.start_with? "translation missing" }
20
+ errors
21
+ .flat_map { |rec| rec.values_at(*locales) }
22
+ .select do |message|
23
+ message.is_a?(String) && message.start_with?("translation missing")
24
+ end
22
25
  end
23
26
 
24
27
  def report_errors
@@ -57,10 +60,12 @@ end
57
60
 
58
61
  RSpec::Matchers.define :be_invalid do
59
62
  match do |policy|
63
+ return expect(policy.valid?).to(be_falsey) unless policy.is_a?(Tram::Policy)
60
64
  expect(policy).to be_invalid_at
61
65
  end
62
66
 
63
67
  match_when_negated do |policy|
68
+ return expect(policy.valid?).to(be_truthy) unless policy.is_a?(Tram::Policy)
64
69
  expect(policy).not_to be_invalid_at
65
70
  end
66
71
  end
data/lib/tram/policy.rb CHANGED
@@ -40,7 +40,7 @@ module Tram
40
40
  # @return [Tram::Policy::Errors]
41
41
  #
42
42
  def errors
43
- @errors ||= Errors.new(self)
43
+ @errors ||= Errors.new(scope: scope)
44
44
  end
45
45
 
46
46
  # The array of error items for lazy translation
@@ -101,7 +101,7 @@ module Tram
101
101
 
102
102
  private
103
103
 
104
- def initialize(*)
104
+ def initialize(*, **)
105
105
  super
106
106
 
107
107
  self.class.validators.each do |validator|
@@ -1,11 +1,12 @@
1
1
  RSpec.describe Tram::Policy::Error do
2
2
  subject(:error) { described_class.new :bad, options }
3
3
 
4
- let(:options) { { level: "warning", scope: %w[tram-policy] } }
4
+ let(:scope) { %w[tram-policy] }
5
+ let(:options) { { level: "warning", scope: scope } }
5
6
 
6
7
  describe "#item" do
7
8
  subject { error.item }
8
- it { is_expected.to eq [:bad, level: "warning", scope: %w[tram-policy]] }
9
+ it { is_expected.to eq [:bad, level: "warning", scope: scope] }
9
10
  end
10
11
 
11
12
  describe "#message" do
@@ -1,6 +1,6 @@
1
1
  RSpec.describe Tram::Policy::Errors do
2
- let(:policy) { double :policy, scope: %w[tram-policy] }
3
- let(:errors) { described_class.new(policy) }
2
+ let(:scope) { %w[tram-policy] }
3
+ let(:errors) { described_class.new(scope: scope) }
4
4
 
5
5
  describe ".new" do
6
6
  subject { errors }
@@ -8,7 +8,7 @@ RSpec.describe Tram::Policy::Errors do
8
8
  it { is_expected.to be_kind_of Enumerable }
9
9
  it { is_expected.to respond_to :empty? }
10
10
  it { is_expected.to be_empty }
11
- its(:policy) { is_expected.to eql policy }
11
+ its(:scope) { is_expected.to eql scope }
12
12
  end
13
13
 
14
14
  describe "#add" do
@@ -21,7 +21,7 @@ RSpec.describe Tram::Policy::Errors do
21
21
 
22
22
  expect(error).to be_kind_of Tram::Policy::Error
23
23
  expect(error)
24
- .to eq [:omg, level: "info", field: "name", scope: %w[tram-policy]]
24
+ .to eq [:omg, level: "info", field: "name", scope: scope]
25
25
  end
26
26
  end
27
27
 
@@ -45,11 +45,11 @@ RSpec.describe Tram::Policy::Errors do
45
45
  end
46
46
 
47
47
  describe "#merge" do
48
- let(:other) { described_class.new(policy) }
48
+ let(:other) { described_class.new(scope: scope) }
49
49
 
50
50
  before do
51
- errors.add "D'OH!", level: "disaster"
52
- other.add "OUCH!", level: "error"
51
+ errors.add :"D'OH!", level: "disaster"
52
+ other.add "OUCH!", level: "error"
53
53
  end
54
54
 
55
55
  context "without a block:" do
@@ -58,8 +58,8 @@ RSpec.describe Tram::Policy::Errors do
58
58
  it "merges other collection as is" do
59
59
  expect(subject).to be_a Tram::Policy::Errors
60
60
  expect(subject.items).to match_array [
61
- ["D'OH!", level: "disaster", scope: %w[tram-policy]],
62
- ["OUCH!", level: "error", scope: %w[tram-policy]]
61
+ [:"D'OH!", level: "disaster", scope: scope],
62
+ ["OUCH!", level: "error"]
63
63
  ]
64
64
  end
65
65
  end
@@ -70,8 +70,8 @@ RSpec.describe Tram::Policy::Errors do
70
70
  it "merges filtered collection as is" do
71
71
  expect(subject).to be_a Tram::Policy::Errors
72
72
  expect(subject.items).to match_array [
73
- ["D'OH!", level: "disaster", scope: %w[tram-policy]],
74
- ["OUCH!", level: "error", scope: %w[tram-policy], source: "Homer"]
73
+ [:"D'OH!", level: "disaster", scope: scope],
74
+ ["OUCH!", level: "error", source: "Homer"]
75
75
  ]
76
76
  end
77
77
  end
@@ -82,8 +82,8 @@ RSpec.describe Tram::Policy::Errors do
82
82
  it "merges other collection with given options" do
83
83
  expect(subject).to be_a Tram::Policy::Errors
84
84
  expect(subject.items).to match_array [
85
- ["D'OH!", level: "disaster", scope: %w[tram-policy]],
86
- ["OUCH!", level: "error", scope: %w[tram-policy], source: "Homer"]
85
+ [:"D'OH!", level: "disaster", scope: scope],
86
+ ["OUCH!", level: "error", source: "Homer"]
87
87
  ]
88
88
  end
89
89
  end
@@ -94,8 +94,8 @@ RSpec.describe Tram::Policy::Errors do
94
94
  it "merges filtered collection with given options" do
95
95
  expect(subject).to be_a Tram::Policy::Errors
96
96
  expect(subject.items).to match_array [
97
- ["D'OH!", level: "disaster", scope: %w[tram-policy]],
98
- ["OUCH!", level: "error", scope: %w[tram-policy], id: 5, age: 4]
97
+ [:"D'OH!", level: "disaster", scope: scope],
98
+ ["OUCH!", level: "error", id: 5, age: 4]
99
99
  ]
100
100
  end
101
101
  end
@@ -125,8 +125,8 @@ RSpec.describe Tram::Policy::Errors do
125
125
 
126
126
  it "returns selected errors only" do
127
127
  expect(subject).to match_array [
128
- [:foo, field: "name", level: "error", scope: %w[tram-policy]],
129
- [:foo, field: "email", level: "error", scope: %w[tram-policy]]
128
+ [:foo, field: "name", level: "error", scope: scope],
129
+ [:foo, field: "email", level: "error", scope: scope]
130
130
  ]
131
131
  end
132
132
  end
@@ -46,4 +46,19 @@ RSpec.describe "RSpec support:" do
46
46
  .to raise_error RSpec::Expectations::ExpectationNotMetError
47
47
  end
48
48
  end
49
+
50
+ describe "to be_invalid" do
51
+ subject { double("model") }
52
+
53
+ it "fails with valid non-policy object" do
54
+ allow(subject).to receive(:valid?).and_return(true)
55
+ expect { expect(subject).to be_invalid }
56
+ .to raise_error RSpec::Expectations::ExpectationNotMetError
57
+ end
58
+
59
+ it "passes with invalid non-policy object" do
60
+ allow(subject).to receive(:valid?).and_return(false)
61
+ expect { expect(subject).to be_invalid }.not_to raise_error
62
+ end
63
+ end
49
64
  end
@@ -63,8 +63,8 @@ RSpec.describe Tram::Policy do
63
63
  describe "#errors" do
64
64
  subject { policy.errors }
65
65
 
66
- its(:class) { is_expected.to eq Tram::Policy::Errors }
67
- its(:policy) { is_expected.to eql policy }
66
+ its(:class) { is_expected.to eq Tram::Policy::Errors }
67
+ its(:scope) { is_expected.to eql policy.scope }
68
68
  end
69
69
 
70
70
  describe "#valid?" do
data/tram-policy.gemspec CHANGED
@@ -1,9 +1,9 @@
1
1
  Gem::Specification.new do |gem|
2
2
  gem.name = "tram-policy"
3
- gem.version = "1.0.0"
3
+ gem.version = "2.1.0"
4
4
  gem.author = ["Viktor Sokolov (gzigzigzeo)", "Andrew Kozin (nepalez)"]
5
5
  gem.email = "andrew.kozin@gmail.com"
6
- gem.homepage = "https://github.com/tram/tram-policy"
6
+ gem.homepage = "https://github.com/tram-rb/tram-policy"
7
7
  gem.summary = "Policy Object Pattern"
8
8
  gem.license = "MIT"
9
9
 
@@ -14,7 +14,7 @@ Gem::Specification.new do |gem|
14
14
 
15
15
  gem.required_ruby_version = ">= 2.3"
16
16
 
17
- gem.add_runtime_dependency "dry-initializer", "~> 2.0"
17
+ gem.add_runtime_dependency "dry-initializer", "> 2", "< 4"
18
18
  gem.add_runtime_dependency "i18n", "~> 1.0"
19
19
 
20
20
  gem.add_development_dependency "rake", "> 10"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tram-policy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Viktor Sokolov (gzigzigzeo)
@@ -9,22 +9,28 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-02-17 00:00:00.000000000 Z
12
+ date: 2021-11-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: dry-initializer
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - "~>"
18
+ - - ">"
19
+ - !ruby/object:Gem::Version
20
+ version: '2'
21
+ - - "<"
19
22
  - !ruby/object:Gem::Version
20
- version: '2.0'
23
+ version: '4'
21
24
  type: :runtime
22
25
  prerelease: false
23
26
  version_requirements: !ruby/object:Gem::Requirement
24
27
  requirements:
25
- - - "~>"
28
+ - - ">"
29
+ - !ruby/object:Gem::Version
30
+ version: '2'
31
+ - - "<"
26
32
  - !ruby/object:Gem::Version
27
- version: '2.0'
33
+ version: '4'
28
34
  - !ruby/object:Gem::Dependency
29
35
  name: i18n
30
36
  requirement: !ruby/object:Gem::Requirement
@@ -154,7 +160,7 @@ files:
154
160
  - spec/tram/policy/validation_error_spec.rb
155
161
  - spec/tram/policy_spec.rb
156
162
  - tram-policy.gemspec
157
- homepage: https://github.com/tram/tram-policy
163
+ homepage: https://github.com/tram-rb/tram-policy
158
164
  licenses:
159
165
  - MIT
160
166
  metadata: {}
@@ -173,8 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
173
179
  - !ruby/object:Gem::Version
174
180
  version: '0'
175
181
  requirements: []
176
- rubyforge_project:
177
- rubygems_version: 2.6.14
182
+ rubygems_version: 3.1.6
178
183
  signing_key:
179
184
  specification_version: 4
180
185
  summary: Policy Object Pattern