tablesalt 0.23.2 → 0.23.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 32be8f4aba8c2345d143f8e7ec32497c38fdb93283d001dcff734ed3a24e2280
4
- data.tar.gz: c289b11fdf258b1e8515d2eab9872809302749339b44322080a3af8b07974bee
3
+ metadata.gz: 32b2974935a587bd2189cf801e9525259500458aa4ca280a072146d9135ac16a
4
+ data.tar.gz: 16f152b1f455fa7ea0f98f1e132f5becba475b45884c683780e05660106ce36c
5
5
  SHA512:
6
- metadata.gz: bd04098eb17d5bc9bbc2ab6b679c38c8b06eee2c0dc66634b3b15e126191c6dc39f2c463dae4720191055d647515a0d3bc79411567d028ab5ad136ae09d1396e
7
- data.tar.gz: 3a72138c4968b8b777d873c5b1ebf9b591e34b8285aa8c3efc63880a144fcfcdcab2b094610c366013c6656676adbd507b30b2f69e30a573967e1066e8769397
6
+ metadata.gz: 51d8b5e463199792b30de3c8c8aaea89a0588e838fb6c1b28d444dfae9e0d91df34be6266958bb4be63c40c60a29f571c6c59c76122577697a7e31bfa99a877b
7
+ data.tar.gz: d5ca1fa8ca4ad95a5df47b03fa31dc93cbfc9dc6ce2790d1c4aad97b4089afe0ddd6d3f924305062617fd5dffd20d800a9a29b3c9d3916008c035fd28fe1c1ab
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/keys"
4
+
5
+ # RSpec matcher to assert the definition of a thread accessor
6
+ #
7
+ # class MyClass
8
+ # include Tablesalt::ConfigDelegation
9
+ #
10
+ # thread_reader :a_thread_key
11
+ # end
12
+ #
13
+ # RSpec.describe MyClass do
14
+ # subject { described_class }
15
+ #
16
+ # it { is_expected.to define_thread_reader :a_thread_key, private: false }
17
+ # end
18
+ RSpec::Matchers.define :define_thread_reader do |method_name, thread_key, **options|
19
+ attr_reader :subject, :method_name, :thread_key, :private_opt
20
+
21
+ description { "defines#{a_private} thread reader #{method_name.inspect} with thread key #{thread_key.inspect}" }
22
+
23
+ failure_message { "expected #{subject_module} to define#{a_private} thread reader #{method_name.inspect} with thread key #{thread_key.inspect}" }
24
+ failure_message_when_negated { "expected #{subject_module} not to define#{a_private} thread reader #{method_name.inspect} with thread key #{thread_key.inspect}" }
25
+
26
+ match_unless_raises do |subject|
27
+ options.assert_valid_keys(:private)
28
+
29
+ @subject = subject
30
+ @method_name = method_name
31
+ @thread_key = thread_key.to_sym
32
+ @private_opt = options.fetch(:private, true)
33
+
34
+ with_value_on_thread do
35
+ expect(instance).to be_respond_to(method_name, true)
36
+ expect(klass).to be_respond_to(method_name, true)
37
+
38
+ expect(instance.__send__(method_name)).to eq stubbed_value
39
+ expect(klass.__send__(method_name)).to eq stubbed_value
40
+
41
+ if private_opt
42
+ expect { instance.public_send(method_name) }.to raise_error NoMethodError
43
+ expect { klass.public_send(method_name) }.to raise_error NoMethodError
44
+ end
45
+ end
46
+
47
+ true
48
+ end
49
+
50
+ private
51
+
52
+ def with_value_on_thread
53
+ Thread.current[thread_key] = stubbed_value
54
+
55
+ yield
56
+
57
+ Thread.current[thread_key] = nil
58
+ end
59
+
60
+ def subject_module
61
+ subject.is_a?(Module) ? subject : subject.class
62
+ end
63
+
64
+ def klass
65
+ @klass ||=
66
+ case subject
67
+ when Class
68
+ subject
69
+ when Module
70
+ Class.new(subject)
71
+ else
72
+ subject.class
73
+ end
74
+ end
75
+
76
+ def instance
77
+ return subject unless subject.is_a?(Module)
78
+
79
+ @instance ||= begin
80
+ allow(klass).to receive(:initialize).with(any_args)
81
+ subject.new
82
+ end
83
+ end
84
+
85
+ def stubbed_value
86
+ @stubbed_value ||= double("Thread value")
87
+ end
88
+
89
+ def a_private
90
+ return unless private_opt
91
+
92
+ " a private"
93
+ end
94
+ end
@@ -1,3 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "custom_matchers/define_thread_reader"
3
4
  require_relative "custom_matchers/isolate"
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tablesalt
4
+ module ThreadAccessor
5
+ extend ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+ private
9
+
10
+ # Defines an instance method and a singleton method to read from a given key in Thread.current
11
+ #
12
+ # @example
13
+ # class SomeClass
14
+ # include Tablesalt::ThreadAccessor
15
+ #
16
+ # thread_reader :current_foo, :foo, private: false
17
+ # end
18
+ #
19
+ # Thread.current[:foo] = "bar"
20
+ # SomeClass.current_foo
21
+ # => "bar"
22
+ #
23
+ # SomeClass.new.current_foo
24
+ # => "bar"
25
+ #
26
+ # @param method [String, Symbol] The name of the reader method
27
+ # @param thread_key [String, Symbol] The key to read from Thread.current
28
+ # @option :private [Boolean] If true, both defined methods will be private. Default: true
29
+ def thread_reader(method, thread_key, **options)
30
+ define_method(method) { Thread.current[thread_key] }
31
+ define_singleton_method(method) { Thread.current[thread_key] }
32
+
33
+ return unless options.fetch(:private, true)
34
+
35
+ private method
36
+ private_class_method method
37
+ end
38
+
39
+ # Defines an instance method and a singleton method to write to a given key in Thread.current
40
+ #
41
+ # @example
42
+ # class SomeClass
43
+ # include Tablesalt::ThreadAccessor
44
+ #
45
+ # thread_writer :current_foo, :foo, private: false
46
+ # end
47
+ #
48
+ # SomeClass.current_foo = "bar"
49
+ #
50
+ # Thread.current[:foo]
51
+ # => "bar"
52
+ #
53
+ # @param method [String, Symbol] The name of the writer method
54
+ # @param thread_key [String, Symbol] The key to write to on Thread.current
55
+ # @option :private [Boolean] If true, both defined methods will be private. Default: true
56
+ def thread_writer(method, thread_key, **options)
57
+ method_name = "#{method}="
58
+
59
+ define_method(method_name) { |value| Thread.current[thread_key] = value }
60
+ define_singleton_method(method_name) { |value| Thread.current[thread_key] = value }
61
+
62
+ return unless options.fetch(:private, true)
63
+
64
+ private method_name
65
+ private_class_method method_name
66
+ end
67
+
68
+ # Defines instance methods and singleton methods to read/write a given key in Thread.current
69
+ #
70
+ # @example
71
+ # class SomeClass
72
+ # include Tablesalt::ThreadAccessor
73
+ #
74
+ # thread_accessor :current_foo, :foo, private: false
75
+ # end
76
+ #
77
+ # SomeClass.current_foo = "bar"
78
+ # SomeClass.current_foo
79
+ # => "bar"
80
+ #
81
+ # SomeClass.new.current_foo = "baz"
82
+ # SomeClass.new.current_foo
83
+ # => "baz"
84
+ #
85
+ # Thread.current[:foo]
86
+ # => "baz"
87
+ #
88
+ # @param method [String, Symbol] The name of the writer method
89
+ # @param thread_key [String, Symbol] The key to write to on Thread.current
90
+ # @option :private [Boolean] If true, all defined methods will be private. Default: true
91
+ def thread_accessor(method, thread_key, **options)
92
+ thread_reader(method, thread_key, **options)
93
+ thread_writer(method, thread_key, **options)
94
+ end
95
+ end
96
+ end
97
+ end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Tablesalt
4
4
  # This constant is managed by spicerack
5
- VERSION = "0.23.2"
5
+ VERSION = "0.23.3"
6
6
  end
data/lib/tablesalt.rb CHANGED
@@ -8,6 +8,7 @@ require "tablesalt/version"
8
8
  require "tablesalt/dsl_accessor"
9
9
  require "tablesalt/isolation"
10
10
  require "tablesalt/stringable_object"
11
+ require "tablesalt/thread_accessor"
11
12
  require "tablesalt/uses_hash_for_equality"
12
13
 
13
14
  module Tablesalt; end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tablesalt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.23.2
4
+ version: 0.23.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Minneti
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-20 00:00:00.000000000 Z
11
+ date: 2020-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -53,9 +53,11 @@ files:
53
53
  - lib/tablesalt/dsl_accessor.rb
54
54
  - lib/tablesalt/isolation.rb
55
55
  - lib/tablesalt/rspec/custom_matchers.rb
56
+ - lib/tablesalt/rspec/custom_matchers/define_thread_reader.rb
56
57
  - lib/tablesalt/rspec/custom_matchers/isolate.rb
57
58
  - lib/tablesalt/spec_helper.rb
58
59
  - lib/tablesalt/stringable_object.rb
60
+ - lib/tablesalt/thread_accessor.rb
59
61
  - lib/tablesalt/uses_hash_for_equality.rb
60
62
  - lib/tablesalt/version.rb
61
63
  homepage: https://github.com/Freshly/spicerack/tree/master/tablesalt
@@ -65,7 +67,7 @@ metadata:
65
67
  homepage_uri: https://github.com/Freshly/spicerack/tree/master/tablesalt
66
68
  source_code_uri: https://github.com/Freshly/spicerack/tree/master/tablesalt
67
69
  changelog_uri: https://github.com/Freshly/spicerack/blob/master/tablesalt/CHANGELOG.md
68
- documentation_uri: https://www.rubydoc.info/gems/tablesalt/0.23.2
70
+ documentation_uri: https://www.rubydoc.info/gems/tablesalt/0.23.3
69
71
  post_install_message:
70
72
  rdoc_options: []
71
73
  require_paths: