rom-support 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 70f13f90c6f93d61be77682813072314e9e56ebf
4
- data.tar.gz: e69c62e1fb470e01d7e866608abffcf660f02c88
3
+ metadata.gz: b27f4c3a3be6027778b10770424d5756992cafe6
4
+ data.tar.gz: 4e0688221d2acb412596ad320ae45f4bdc695266
5
5
  SHA512:
6
- metadata.gz: d2c8cec18d5f6fd3f9a152bf1821466981437e4dcbb418207bfb7d398d06093a9cc4739a6d796397ef2e777ba163a23bed37d9598383d24edad44ac07aa103c2
7
- data.tar.gz: 8b76767a81f8df0002cf4f40b29ca3d79b2114e94ec84a0c699b35c9dba0d12d92e97057bee6fc35c6b93cd5cb694b479fe075b921fced7e8d17f97fe104e5f8
6
+ metadata.gz: 251b204b77b54f3a31d592a1f90e5ae7e34bc41ab950dda14d92c54248da6dc25b6ea237dcfb0fbd82ce8e62c142cd2d7d2f34ae60cb90076f8d29c6e8a7bc7a
7
+ data.tar.gz: faf12e5b17d7ef787538e3b197b479607b6fed4178f107d4ac682dc8460e42d029096cd83d61107e284b491a389f076f010d3736f5b713a1af3c3aa3dab3ba95
@@ -6,12 +6,11 @@ env:
6
6
  bundler_args: --without tools
7
7
  script: "bundle exec rake spec"
8
8
  rvm:
9
- - 2.0
10
9
  - 2.1
11
10
  - 2.2
12
- - 2.3.0
11
+ - 2.3.1
13
12
  - rbx-2
14
- - jruby-9000
13
+ - jruby-9.0.5.0
15
14
  - ruby-head
16
15
  - jruby-head
17
16
  env:
@@ -1,3 +1,18 @@
1
+ ## v2.0.0 2016-07-27
2
+
3
+ ### Added
4
+
5
+ * `AutoCurry.auto_curried_methods` returning a list of methods that were auto-curried (solnic)
6
+ * `ROM::Cache` extension providing `#fetch_or_store` and `.fetch_or_store` (solnic)
7
+ * `ROM::Deprecations.set_logger!` which allows setting a custom logger (solnic)
8
+
9
+ ### Changed
10
+
11
+ * Refactored `AutoCurry` to use module prepend (solnic)
12
+ * `AutoCurry` skips private methods and methods with 0 arity (solnic)
13
+
14
+ [Compare v1.0.0...v2.0.0](https://github.com/rom-rb/rom-support/compare/v1.0.0...v2.0.0)
15
+
1
16
  ## v1.0.0 2016-01-06
2
17
 
3
18
  ### Added
data/Gemfile CHANGED
@@ -2,16 +2,13 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'transproc', github: 'solnic/transproc', branch: 'master'
6
- gem 'rom-mapper', github: 'rom-rb/rom-mapper', branch: 'master'
7
-
8
5
  group :console do
9
6
  gem 'pry'
10
7
  gem 'pg', platforms: [:mri]
11
8
  end
12
9
 
13
10
  group :test do
14
- gem 'activesupport'
11
+ gem 'activesupport', '~> 4.2'
15
12
  gem 'inflecto', '~> 0.0', '>= 0.0.2'
16
13
 
17
14
  platforms :rbx do
@@ -27,7 +24,7 @@ group :tools do
27
24
  gem 'guard-rspec'
28
25
  gem 'guard-rubocop'
29
26
 
30
- gem 'byebug'
27
+ gem 'byebug', platform: :mri
31
28
 
32
29
  platform :mri do
33
30
  gem 'mutant', '>= 0.8.0', github: 'mbj/mutant', branch: 'master'
data/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  [![Gem Version](https://badge.fury.io/rb/rom-support.svg)][gem]
10
10
  [![Build Status](https://travis-ci.org/rom-rb/rom-support.svg?branch=master)][travis]
11
- [![Dependency Status](https://gemnasium.com/rom-rb/rom-support.png)][gemnasium]
11
+ [![Dependency Status](https://gemnasium.com/rom-rb/rom-support.svg)][gemnasium]
12
12
  [![Code Climate](https://codeclimate.com/github/rom-rb/rom-support/badges/gpa.svg)][codeclimate]
13
13
  [![Test Coverage](https://codeclimate.com/github/rom-rb/rom-support/badges/coverage.svg)][codeclimate]
14
14
  [![Inline docs](http://inch-ci.org/github/rom-rb/rom-support.svg?branch=master)][inchpages]
@@ -19,25 +19,37 @@ module ROM
19
19
  @__auto_curry_busy__ ||= false
20
20
  end
21
21
 
22
+ def auto_curried_methods
23
+ @__auto_curried_methods__ ||= []
24
+ end
25
+
22
26
  def auto_curry(name, &block)
23
- curried = self.curried
24
- meth = instance_method(name)
25
- arity = meth.arity
26
-
27
- define_method(name) do |*args|
28
- response =
29
- if arity < 0 || arity == args.size
30
- meth.bind(self).(*args)
27
+ arity = instance_method(name).arity
28
+
29
+ return if private_instance_methods.include?(name) || arity == 0
30
+
31
+ mod = Module.new
32
+
33
+ mod.module_eval do
34
+ define_method(name) do |*args|
35
+ response =
36
+ if arity < 0 || arity == args.size
37
+ super(*args)
38
+ else
39
+ self.class.curried.new(self, name: name, curry_args: args, arity: arity)
40
+ end
41
+
42
+ if block
43
+ response.instance_exec(&block)
31
44
  else
32
- curried.new(self, name: name, curry_args: args, arity: arity)
45
+ response
33
46
  end
34
-
35
- if block
36
- response.instance_exec(&block)
37
- else
38
- response
39
47
  end
40
48
  end
49
+
50
+ auto_curried_methods << name
51
+
52
+ prepend(mod)
41
53
  end
42
54
  end
43
55
  end
@@ -0,0 +1,25 @@
1
+ require 'concurrent/map'
2
+
3
+ module ROM
4
+ module Cache
5
+ def self.extended(klass)
6
+ super
7
+ klass.include(Methods)
8
+ klass.instance_variable_set(:@__cache__, Concurrent::Map.new)
9
+ end
10
+
11
+ def cache
12
+ @__cache__
13
+ end
14
+
15
+ def fetch_or_store(*args, &block)
16
+ cache.fetch_or_store(args.hash, &block)
17
+ end
18
+
19
+ module Methods
20
+ def fetch_or_store(*args, &block)
21
+ self.class.fetch_or_store(*args, &block)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -33,6 +33,10 @@ module ROM
33
33
  name
34
34
  end
35
35
 
36
+ def self.to_str
37
+ name
38
+ end
39
+
36
40
  def self.to_s
37
41
  name
38
42
  end
@@ -2,4 +2,5 @@ module ROM
2
2
  Undefined = Object.new.freeze
3
3
  EMPTY_HASH = {}.freeze
4
4
  EMPTY_ARRAY = [].freeze
5
+ EMPTY_STRING = ''.freeze
5
6
  end
@@ -1,3 +1,5 @@
1
+ require 'logger'
2
+
1
3
  module ROM
2
4
  module Deprecations
3
5
  # @api private
@@ -14,23 +16,63 @@ module ROM
14
16
  end
15
17
 
16
18
  def deprecate_class_method(old_name, new_name, msg = nil)
19
+ full_msg =
20
+ if new_name.is_a?(Symbol)
21
+ full_msg = Deprecations.deprecation_message "#{self.name}.#{old_name}", <<-MSG
22
+ Please use #{self.name}.#{new_name} instead.
23
+ #{msg}
24
+ MSG
25
+ else
26
+ Deprecations.deprecation_message "#{self.name}.#{old_name}", new_name
27
+ end
28
+
29
+ meth = new_name.is_a?(Symbol) ? method(new_name) : method(old_name)
30
+ instance_eval "undef #{old_name}"
31
+
17
32
  class_eval do
18
33
  define_singleton_method(old_name) do |*args, &block|
19
- ROM::Deprecations.announce"#{self}.#{old_name} is", <<-MSG
20
- Please use #{self}.#{new_name} instead.
21
- #{msg}
22
- MSG
23
- __send__(new_name, *args, &block)
34
+ Deprecations.warn(full_msg)
35
+ meth.call(*args, &block)
24
36
  end
25
37
  end
26
38
  end
27
39
 
40
+ def self.warn(msg)
41
+ logger.warn(msg.gsub(/^\s+/, ''))
42
+ end
43
+
28
44
  def self.announce(name, msg)
29
- warn <<-MSG.gsub(/^\s+/, '')
30
- #{name} deprecated and will be removed in 1.0.0.
45
+ warn(deprecation_message(name, msg))
46
+ end
47
+
48
+ def self.deprecation_message(name, msg)
49
+ <<-MSG
50
+ #{name} is deprecated and will be removed in the next major version
51
+ #{message(msg)}
52
+ MSG
53
+ end
54
+
55
+ def self.message(msg)
56
+ <<-MSG
31
57
  #{msg}
32
58
  #{caller.detect { |l| !l.include?('lib/rom')}}
33
59
  MSG
34
60
  end
61
+
62
+ def self.logger(output = nil)
63
+ if defined?(@logger)
64
+ @logger
65
+ else
66
+ set_logger!(output)
67
+ end
68
+ end
69
+
70
+ def self.set_logger!(output = nil)
71
+ @logger = Logger.new(output || $stdout)
72
+ @logger.formatter = proc { |severity, datetime, progname, msg|
73
+ "[rom] #{msg}\n"
74
+ }
75
+ @logger
76
+ end
35
77
  end
36
78
  end
@@ -23,12 +23,17 @@ module ROM
23
23
  end
24
24
 
25
25
  def key?(name)
26
- elements.key?(name)
26
+ elements.key?(name.to_sym)
27
27
  end
28
28
 
29
- def [](key)
30
- elements.fetch(key) { raise ElementNotFoundError.new(key, name) }
29
+ def fetch(key)
30
+ elements.fetch(key.to_sym) do
31
+ return yield if block_given?
32
+
33
+ raise ElementNotFoundError.new(key, name)
34
+ end
31
35
  end
36
+ alias_method :[], :fetch
32
37
 
33
38
  def respond_to_missing?(name, include_private = false)
34
39
  elements.key?(name) || super
@@ -1,5 +1,5 @@
1
1
  module ROM
2
2
  module Support
3
- VERSION = '1.0.0'.freeze
3
+ VERSION = '2.0.0'.freeze
4
4
  end
5
5
  end
@@ -15,6 +15,7 @@ Gem::Specification.new do |gem|
15
15
  gem.test_files = `git ls-files -- {spec}/*`.split("\n")
16
16
  gem.license = 'MIT'
17
17
 
18
+ gem.add_runtime_dependency 'concurrent-ruby', '~> 1.0'
18
19
  gem.add_runtime_dependency 'dry-equalizer', '~> 0.2'
19
20
  gem.add_runtime_dependency 'wisper', '~> 1.6', '>= 1.6.0'
20
21
  gem.add_runtime_dependency 'transproc', '~> 0.4.0'
@@ -8,7 +8,6 @@ if RUBY_ENGINE == "rbx"
8
8
  end
9
9
 
10
10
  require 'rom-support'
11
- require 'rom-mapper'
12
11
 
13
12
  begin
14
13
  require 'byebug'
@@ -40,7 +39,3 @@ RSpec.configure do |config|
40
39
  ConstantLeakFinder.find(example)
41
40
  end
42
41
  end
43
-
44
- def T(*args)
45
- ROM::Processor::Transproc::Functions[*args]
46
- end
@@ -6,7 +6,7 @@ describe ROM::ArrayDataset do
6
6
  include ROM::ArrayDataset
7
7
 
8
8
  def self.row_proc
9
- T(:symbolize_keys)
9
+ -> i { i.each_with_object({}) { |(k,v),h| h[k.to_sym] = v } }
10
10
  end
11
11
  end
12
12
  end
@@ -32,6 +32,10 @@ RSpec.describe ROM::AutoCurry do
32
32
  end
33
33
  end
34
34
 
35
+ it 'registers auto-curried methods' do
36
+ expect(object.class.auto_curried_methods).to eql(%i[arity_1 arity_2 arity_many])
37
+ end
38
+
35
39
  it 'auto-curries method with arity == 0' do
36
40
  expect(object.arity_0).to be(0)
37
41
  end
@@ -0,0 +1,24 @@
1
+ require 'rom/support/cache'
2
+
3
+ RSpec.describe ROM::Cache do
4
+ subject(:klass) do
5
+ Class.new do
6
+ extend ROM::Cache
7
+ end
8
+ end
9
+
10
+ describe '#fetch_or_store' do
11
+ it 'stores and fetches a value' do
12
+ args = [1, 2, 3]
13
+ value = 'foo'
14
+
15
+ expect(klass.fetch_or_store(*args) { value }).to be(value)
16
+ expect(klass.fetch_or_store(*args)).to be(value)
17
+
18
+ object = klass.new
19
+
20
+ expect(object.fetch_or_store(*args) { value }).to be(value)
21
+ expect(object.fetch_or_store(*args)).to be(value)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,73 @@
1
+ require 'rom/support/deprecations'
2
+ require 'tempfile'
3
+
4
+ RSpec.describe ROM::Deprecations do
5
+ let(:log_file) do
6
+ Tempfile.new('rom_deprecations')
7
+ end
8
+
9
+ before do
10
+ ROM::Deprecations.set_logger!(log_file)
11
+ end
12
+
13
+ let(:output) do
14
+ log_file.close
15
+ log_file.open.read
16
+ end
17
+
18
+ describe '.warn' do
19
+ it 'logs a warning message' do
20
+ ROM::Deprecations.warn('hello world')
21
+ expect(output).to include('[rom] hello world')
22
+ end
23
+ end
24
+
25
+ describe '.announce' do
26
+ it 'warns about a deprecated method' do
27
+ ROM::Deprecations.announce(:foo, 'hello world')
28
+ expect(output).to include('[rom] foo is deprecated and will be removed')
29
+ expect(output).to include('hello world')
30
+ end
31
+ end
32
+
33
+ describe '.deprecate_class_method' do
34
+ subject(:klass) do
35
+ Class.new do
36
+ extend ROM::Deprecations
37
+
38
+ def self.name
39
+ "Test"
40
+ end
41
+
42
+ def self.log(msg)
43
+ "log: #{msg}"
44
+ end
45
+
46
+ def self.hello(word)
47
+ "hello #{word}"
48
+ end
49
+ deprecate_class_method :hello, "is no more"
50
+
51
+ def self.logging(msg)
52
+ "logging: #{msg}"
53
+ end
54
+ deprecate_class_method :logging, :log
55
+ end
56
+ end
57
+
58
+ it 'deprecates method that is to be removed' do
59
+ res = klass.hello("world")
60
+
61
+ expect(res).to eql("hello world")
62
+ expect(output).to include('[rom] Test.hello is deprecated and will be removed')
63
+ expect(output).to include('is no more')
64
+ end
65
+
66
+ it 'deprecates a method in favor of another' do
67
+ res = klass.logging('foo')
68
+
69
+ expect(res).to eql('log: foo')
70
+ expect(output).to include('[rom] Test.logging is deprecated and will be removed')
71
+ end
72
+ end
73
+ end
@@ -6,7 +6,7 @@ describe ROM::EnumerableDataset do
6
6
  include ROM::EnumerableDataset
7
7
 
8
8
  def self.row_proc
9
- T(:symbolize_keys)
9
+ -> i { i.each_with_object({}) { |(k,v),h| h[k.to_sym] = v } }
10
10
  end
11
11
  end
12
12
  end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+ require 'rom/support/registry'
3
+
4
+ shared_examples_for 'registry fetch' do
5
+ it 'returns registered element identified by name' do
6
+ expect(registry.public_send(fetch_method, :mars)).to be(mars)
7
+ end
8
+
9
+ it 'raises error when element is not found' do
10
+ expect { registry.public_send(fetch_method, :twix) }.to raise_error(
11
+ ROM::Registry::ElementNotFoundError,
12
+ ":twix doesn't exist in Candy registry"
13
+ )
14
+ end
15
+
16
+ it 'returns the value from an optional block when key is not found' do
17
+ value = registry.public_send(fetch_method, :candy) { :twix }
18
+
19
+ expect(value).to eq(:twix)
20
+ end
21
+
22
+ it 'calls #to_sym on a key before fetching' do
23
+ expect(registry.public_send(fetch_method, double(to_sym: :mars))).to be(mars)
24
+ end
25
+ end
26
+
27
+ describe ROM::Registry do
28
+ subject(:registry) { registry_class.new(mars: mars) }
29
+
30
+ let(:mars) { double('mars') }
31
+
32
+ let(:registry_class) do
33
+ Class.new(ROM::Registry) do
34
+ def self.name
35
+ 'Candy'
36
+ end
37
+ end
38
+ end
39
+
40
+ describe '#fetch' do
41
+ let(:fetch_method) { :fetch }
42
+
43
+ it_behaves_like 'registry fetch'
44
+ end
45
+
46
+ describe '#[]' do
47
+ let(:fetch_method) { :[] }
48
+
49
+ it_behaves_like 'registry fetch'
50
+ end
51
+
52
+ describe '#method_missing' do
53
+ it 'returns registered element identified by name' do
54
+ expect(registry.mars).to be(mars)
55
+ end
56
+
57
+ it 'raises no-method error when element is not there' do
58
+ expect { registry.twix }.to raise_error(NoMethodError)
59
+ end
60
+ end
61
+ end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rom-support
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Solnica
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-06 00:00:00.000000000 Z
11
+ date: 2016-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: concurrent-ruby
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: dry-equalizer
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -104,6 +118,7 @@ files:
104
118
  - lib/rom-support.rb
105
119
  - lib/rom/support/array_dataset.rb
106
120
  - lib/rom/support/auto_curry.rb
121
+ - lib/rom/support/cache.rb
107
122
  - lib/rom/support/class_builder.rb
108
123
  - lib/rom/support/class_macros.rb
109
124
  - lib/rom/support/constants.rb
@@ -125,10 +140,13 @@ files:
125
140
  - spec/support/mutant.rb
126
141
  - spec/unit/rom/support/array_dataset_spec.rb
127
142
  - spec/unit/rom/support/auto_curry_spec.rb
143
+ - spec/unit/rom/support/cache_spec.rb
128
144
  - spec/unit/rom/support/class_builder_spec.rb
145
+ - spec/unit/rom/support/deprecations_spec.rb
129
146
  - spec/unit/rom/support/enumerable_dataset_spec.rb
130
147
  - spec/unit/rom/support/inflector_spec.rb
131
148
  - spec/unit/rom/support/options_spec.rb
149
+ - spec/unit/rom/support/registry_spec.rb
132
150
  homepage: http://rom-rb.org
133
151
  licenses:
134
152
  - MIT
@@ -149,7 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
149
167
  version: '0'
150
168
  requirements: []
151
169
  rubyforge_project:
152
- rubygems_version: 2.4.5.1
170
+ rubygems_version: 2.5.1
153
171
  signing_key:
154
172
  specification_version: 4
155
173
  summary: Ruby Object Mapper - Support libraries