attr_extras 4.3.0 → 4.4.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: 7a2e11ff4aab1d128893a0145fb72ebc026ac4b5
4
- data.tar.gz: 2bf233446caf0aefb3f7e16db7e388bc216cde34
3
+ metadata.gz: 9a302397db869ccd71c2f96bed2c343468d4c1fb
4
+ data.tar.gz: 4753ba73b9809a4f4d24943058329bb491a796ee
5
5
  SHA512:
6
- metadata.gz: 2d61715715969959cf37ee1e7c6ba1a553675e14bd516cfddd76ea5c0758cb7518af05e3a437407392152e7960c5b3e389350a52c57f3b4297caa29b4c9a36c6
7
- data.tar.gz: ac7e05c8f8cb05e554b59b644e5d0115f195b0bb9555e06d5918c1c0f46995c2c96224b94ccb52b203410df7696a04ec931fe2c5622f4b5a5d228ba0e558f664
6
+ metadata.gz: dc2e5f3b692f3881884296fea5495bfd7da4986ff992552d4bb84eafd789495b2985c3dbac6f0f4bb0d232fdcd1333ad8540bb8c6d474a633aa110d8c13b65bc
7
+ data.tar.gz: 641b94a27502ff6263a13f5451970a92d5202897c4a3b8b2430e812db9e5403865396f3f6d51d2cf1729fce791e8693bf12371e9a90beb5b0e8e507eafaba74a
data/.travis.yml CHANGED
@@ -1,5 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.2
4
- - 1.9.3
3
+ - 2.2.1
4
+ - 2.0.0
5
+ - rbx-2.5.2
5
6
  - jruby-19mode
data/README.md CHANGED
@@ -286,6 +286,29 @@ though it is shorter, more declarative, gives you a clear message and handles ed
286
286
  `attr_id_query :foo?, :bar?` defines query methods like `foo?`, which is true if (and only if) `foo_id` is truthy. Goes well with Active Record.
287
287
 
288
288
 
289
+ ## Explicit mode
290
+
291
+ By default, attr\_extras will add methods to every class and module.
292
+
293
+ This is not ideal if you're using attr\_extras in a library: those who depend on your library will get those methods as well.
294
+
295
+ It's also not obvious where the methods come from. You can be more explicit about it, and restrict where the methods are added, like this:
296
+
297
+ ```
298
+ require "attr_extras/explicit"
299
+
300
+ class MyLib
301
+ extend AttrExtras.mixin
302
+
303
+ pattr_initialize :now_this_class_can_use_attr_extras
304
+ end
305
+ ```
306
+
307
+ Crucially, you need to `require "attr_extras/explicit"` *instead of* `require "attr_extras"`. Some frameworks, like Ruby on Rails, may automatically require everything in your `Gemfile`. You can avoid that with `gem "attr_extras", require: "attr_extras/explicit"`.
308
+
309
+ In explicit mode, you need to call `extend AttrExtras.mixin` *in every class* that wants the attr\_extras methods.
310
+
311
+
289
312
  ## Philosophy
290
313
 
291
314
  Findability is a core value.
@@ -333,6 +356,8 @@ Or to see warnings (try not to have any):
333
356
 
334
357
  `RUBYOPT=-w rake`
335
358
 
359
+ The tests are intentionally split into two test suites for reasons described in `Rakefile`.
360
+
336
361
 
337
362
  ## Contributors
338
363
 
data/Rakefile CHANGED
@@ -2,8 +2,22 @@
2
2
  require "bundler/gem_tasks"
3
3
  require "rake/testtask"
4
4
 
5
- Rake::TestTask.new do |t|
6
- t.pattern = "spec/*_spec.rb"
5
+ # "Explicit mode" cannot be truly tested if that process has already `require`d attr_extras.
6
+ # Thus, we need separate test suites.
7
+
8
+ explicit_tests = [ "spec/attr_extras/explicit_spec.rb" ]
9
+
10
+ Rake::TestTask.new(:test_implicit) do |t|
11
+ implicit_tests = FileList["spec/**/*_spec.rb"] - explicit_tests
12
+
13
+ t.libs << "spec"
14
+ t.test_files = implicit_tests
15
+ end
16
+
17
+ Rake::TestTask.new(:test_explicit) do |t|
18
+ t.libs << "spec"
19
+ t.test_files = explicit_tests
7
20
  end
8
21
 
22
+ task :test => [ :test_implicit, :test_explicit ]
9
23
  task :default => :test
data/lib/attr_extras.rb CHANGED
@@ -1,97 +1,5 @@
1
- require "attr_extras/version"
2
- require "attr_extras/attr_initialize"
3
- require "attr_extras/attr_value"
4
- require "attr_extras/attr_query"
5
- require "attr_extras/utils"
6
-
7
- module AttrExtras
8
- # To avoid masking coding errors, we don't inherit from StandardError (which would be implicitly rescued). Forgetting to define a requisite method isn't just some runtime error.
9
- class MethodNotImplementedError < Exception; end
10
-
11
- module ModuleMethods
12
- def attr_initialize(*names, &block)
13
- AttrInitialize.new(self, names, block).apply
14
- end
15
-
16
- def attr_private(*names)
17
- # Need this to avoid "private attribute?" warnings when running
18
- # the full test suite; not sure why exactly.
19
- public
20
-
21
- attr_reader(*names)
22
- private(*names)
23
- end
24
-
25
- def attr_value(*names)
26
- AttrValue.new(self, *names).apply
27
- end
28
-
29
- def pattr_initialize(*names, &block)
30
- attr_initialize(*names, &block)
31
- attr_private(*Utils.flat_names(names))
32
- end
33
-
34
- alias_method :attr_private_initialize, :pattr_initialize
35
-
36
- def vattr_initialize(*names, &block)
37
- attr_initialize(*names, &block)
38
- attr_value(*Utils.flat_names(names))
39
- end
40
-
41
- alias_method :attr_value_initialize, :vattr_initialize
42
-
43
- def rattr_initialize(*names, &block)
44
- attr_initialize(*names, &block)
45
- attr_reader(*Utils.flat_names(names))
46
- end
47
-
48
- alias_method :attr_reader_initialize, :rattr_initialize
49
-
50
- def static_facade(method_name, *names)
51
- define_singleton_method(method_name) do |*values|
52
- new(*values).public_send(method_name)
53
- end
54
-
55
- pattr_initialize(*names)
56
- end
57
-
58
- def method_object(*names)
59
- static_facade :call, *names
60
- end
61
-
62
- def attr_query(*names)
63
- AttrQuery.define_with_suffix(self, "", *names)
64
- end
65
-
66
- def attr_id_query(*names)
67
- AttrQuery.define_with_suffix(self, "_id", *names)
68
- end
69
-
70
- def attr_implement(*names)
71
- arg_names = names.last.is_a?(Array) ? names.pop : []
72
- arity = arg_names.length
73
-
74
- mod = Module.new do
75
- define_method :method_missing do |name, *args|
76
- if names.include?(name)
77
- provided_arity = args.length
78
-
79
- if provided_arity != arity
80
- raise ArgumentError, "wrong number of arguments (#{provided_arity} for #{arity})"
81
- end
82
-
83
- raise MethodNotImplementedError, "Implement a '#{name}(#{arg_names.join(", ")})' method"
84
- else
85
- super(name, *args)
86
- end
87
- end
88
- end
89
-
90
- include mod
91
- end
92
- end
93
- end
1
+ require "attr_extras/explicit"
94
2
 
95
3
  class Module
96
- include AttrExtras::ModuleMethods
4
+ include AttrExtras.mixin
97
5
  end
@@ -0,0 +1,99 @@
1
+ require "attr_extras/version"
2
+ require "attr_extras/attr_initialize"
3
+ require "attr_extras/attr_value"
4
+ require "attr_extras/attr_query"
5
+ require "attr_extras/utils"
6
+
7
+ module AttrExtras
8
+ # To avoid masking coding errors, we don't inherit from StandardError (which would be implicitly rescued). Forgetting to define a requisite method isn't just some runtime error.
9
+ class MethodNotImplementedError < Exception; end
10
+
11
+ def self.mixin
12
+ self::ModuleMethods
13
+ end
14
+
15
+ # Separate module for `include`ing so that mixing in the methods doesn't also mix in constants:
16
+ # http://thepugautomatic.com/2014/02/private-api/
17
+ module ModuleMethods
18
+ def attr_initialize(*names, &block)
19
+ AttrInitialize.new(self, names, block).apply
20
+ end
21
+
22
+ def attr_private(*names)
23
+ # Need this to avoid "private attribute?" warnings when running
24
+ # the full test suite; not sure why exactly.
25
+ public
26
+
27
+ attr_reader(*names)
28
+ private(*names)
29
+ end
30
+
31
+ def attr_value(*names)
32
+ AttrValue.new(self, *names).apply
33
+ end
34
+
35
+ def pattr_initialize(*names, &block)
36
+ attr_initialize(*names, &block)
37
+ attr_private(*Utils.flat_names(names))
38
+ end
39
+
40
+ alias_method :attr_private_initialize, :pattr_initialize
41
+
42
+ def vattr_initialize(*names, &block)
43
+ attr_initialize(*names, &block)
44
+ attr_value(*Utils.flat_names(names))
45
+ end
46
+
47
+ alias_method :attr_value_initialize, :vattr_initialize
48
+
49
+ def rattr_initialize(*names, &block)
50
+ attr_initialize(*names, &block)
51
+ attr_reader(*Utils.flat_names(names))
52
+ end
53
+
54
+ alias_method :attr_reader_initialize, :rattr_initialize
55
+
56
+ def static_facade(method_name, *names)
57
+ define_singleton_method(method_name) do |*values|
58
+ new(*values).public_send(method_name)
59
+ end
60
+
61
+ pattr_initialize(*names)
62
+ end
63
+
64
+ def method_object(*names)
65
+ static_facade :call, *names
66
+ end
67
+
68
+ def attr_query(*names)
69
+ AttrQuery.define_with_suffix(self, "", *names)
70
+ end
71
+
72
+ def attr_id_query(*names)
73
+ AttrQuery.define_with_suffix(self, "_id", *names)
74
+ end
75
+
76
+ def attr_implement(*names)
77
+ arg_names = names.last.is_a?(Array) ? names.pop : []
78
+ arity = arg_names.length
79
+
80
+ mod = Module.new do
81
+ define_method :method_missing do |name, *args|
82
+ if names.include?(name)
83
+ provided_arity = args.length
84
+
85
+ if provided_arity != arity
86
+ raise ArgumentError, "wrong number of arguments (#{provided_arity} for #{arity})"
87
+ end
88
+
89
+ raise MethodNotImplementedError, "Implement a '#{name}(#{arg_names.join(", ")})' method"
90
+ else
91
+ super(name, *args)
92
+ end
93
+ end
94
+ end
95
+
96
+ include mod
97
+ end
98
+ end
99
+ end
@@ -1,3 +1,3 @@
1
1
  module AttrExtras
2
- VERSION = "4.3.0"
2
+ VERSION = "4.4.0"
3
3
  end
@@ -1,4 +1,4 @@
1
- require_relative "spec_helper"
1
+ require "spec_helper"
2
2
 
3
3
  describe Object, ".attr_id_query" do
4
4
  it "creates id query methods" do
@@ -1,4 +1,4 @@
1
- require_relative "spec_helper"
1
+ require "spec_helper"
2
2
 
3
3
  describe Object, ".attr_implement" do
4
4
  it "creates 0-argument methods that raise" do
@@ -1,4 +1,4 @@
1
- require_relative "spec_helper"
1
+ require "spec_helper"
2
2
 
3
3
  describe Object, ".attr_initialize" do
4
4
  let(:klass) do
@@ -1,4 +1,4 @@
1
- require_relative "spec_helper"
1
+ require "spec_helper"
2
2
 
3
3
  describe Object, ".attr_private" do
4
4
  let(:klass) do
@@ -1,4 +1,4 @@
1
- require_relative "spec_helper"
1
+ require "spec_helper"
2
2
 
3
3
  describe Object, ".attr_query" do
4
4
  it "creates attribute query methods" do
@@ -1,4 +1,4 @@
1
- require_relative "spec_helper"
1
+ require "spec_helper"
2
2
  require "set"
3
3
 
4
4
  describe Object, ".attr_value" do
@@ -0,0 +1,23 @@
1
+ require "spec_helper_without_loading_attr_extras"
2
+ require "attr_extras/explicit"
3
+
4
+ # Sanity check.
5
+ if String.respond_to?(:pattr_initialize)
6
+ raise "Expected this test suite not to have AttrExtras mixed in!"
7
+ end
8
+
9
+ describe AttrExtras, "explicit mode" do
10
+ it "must have methods mixed in explicitly" do
11
+ has_methods_before_mixin = nil
12
+ has_methods_after_mixin = nil
13
+
14
+ Class.new do
15
+ has_methods_before_mixin = respond_to?(:pattr_initialize)
16
+ extend AttrExtras.mixin
17
+ has_methods_after_mixin = respond_to?(:pattr_initialize)
18
+ end
19
+
20
+ refute has_methods_before_mixin
21
+ assert has_methods_after_mixin
22
+ end
23
+ end
@@ -1,4 +1,4 @@
1
- require_relative "spec_helper"
1
+ require "spec_helper"
2
2
 
3
3
  describe Object, ".method_object" do
4
4
  it "creates a .call class method that instantiates and runs the #call instance method" do
@@ -1,4 +1,4 @@
1
- require_relative "spec_helper"
1
+ require "spec_helper"
2
2
 
3
3
  describe Object, ".pattr_initialize" do
4
4
  it "creates both initializer and private readers" do
@@ -1,4 +1,4 @@
1
- require_relative "spec_helper"
1
+ require "spec_helper"
2
2
 
3
3
  describe Object, ".rattr_initialize" do
4
4
  it "creates both initializer and public readers" do
@@ -1,4 +1,4 @@
1
- require_relative "spec_helper"
1
+ require "spec_helper"
2
2
 
3
3
  describe Object, ".static_facade" do
4
4
  it "creates a class method that instantiates and runs that instance method" do
@@ -1,4 +1,4 @@
1
- require_relative "spec_helper"
1
+ require "spec_helper"
2
2
 
3
3
  describe Object, ".vattr_initialize" do
4
4
  it "creates initializer, value readers and value object identity" do
@@ -1,7 +1,7 @@
1
- require_relative "spec_helper"
1
+ require "spec_helper"
2
2
 
3
- describe AttrExtras, "in modules" do
4
- it "is supported" do
3
+ describe AttrExtras do
4
+ it "mixes helpers into all Modules (and thus all Classes)" do
5
5
  mod = Module.new do
6
6
  pattr_initialize :name
7
7
  end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,2 @@
1
- require "minitest/autorun"
2
- require "minitest/pride"
3
-
4
- $: << File.dirname(__FILE__) + "/../lib"
1
+ require "spec_helper_without_loading_attr_extras"
5
2
  require "attr_extras"
@@ -0,0 +1,4 @@
1
+ require "minitest/autorun"
2
+ require "minitest/pride"
3
+
4
+ $: << File.dirname(__FILE__) + "/../lib"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attr_extras
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.3.0
4
+ version: 4.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henrik Nyh
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-02-25 00:00:00.000000000 Z
13
+ date: 2015-03-08 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: minitest
@@ -48,7 +48,6 @@ extensions: []
48
48
  extra_rdoc_files: []
49
49
  files:
50
50
  - ".gitignore"
51
- - ".rvmrc"
52
51
  - ".travis.yml"
53
52
  - Gemfile
54
53
  - LICENSE.txt
@@ -59,22 +58,25 @@ files:
59
58
  - lib/attr_extras/attr_initialize.rb
60
59
  - lib/attr_extras/attr_query.rb
61
60
  - lib/attr_extras/attr_value.rb
61
+ - lib/attr_extras/explicit.rb
62
62
  - lib/attr_extras/utils.rb
63
63
  - lib/attr_extras/version.rb
64
64
  - script/test
65
+ - spec/attr_extras/attr_id_query_spec.rb
66
+ - spec/attr_extras/attr_implement_spec.rb
67
+ - spec/attr_extras/attr_initialize_spec.rb
68
+ - spec/attr_extras/attr_private_spec.rb
69
+ - spec/attr_extras/attr_query_spec.rb
70
+ - spec/attr_extras/attr_value_spec.rb
71
+ - spec/attr_extras/explicit_spec.rb
72
+ - spec/attr_extras/method_object_spec.rb
73
+ - spec/attr_extras/pattr_initialize_spec.rb
74
+ - spec/attr_extras/rattr_initialize_spec.rb
75
+ - spec/attr_extras/static_facade_spec.rb
76
+ - spec/attr_extras/vattr_initialize_spec.rb
65
77
  - spec/attr_extras_spec.rb
66
- - spec/attr_id_query_spec.rb
67
- - spec/attr_implement_spec.rb
68
- - spec/attr_initialize_spec.rb
69
- - spec/attr_private_spec.rb
70
- - spec/attr_query_spec.rb
71
- - spec/attr_value_spec.rb
72
- - spec/method_object_spec.rb
73
- - spec/pattr_initialize_spec.rb
74
- - spec/rattr_initialize_spec.rb
75
78
  - spec/spec_helper.rb
76
- - spec/static_facade_spec.rb
77
- - spec/vattr_initialize_spec.rb
79
+ - spec/spec_helper_without_loading_attr_extras.rb
78
80
  homepage: https://github.com/barsoom/attr_extras
79
81
  licenses:
80
82
  - MIT
@@ -95,21 +97,23 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
97
  version: '0'
96
98
  requirements: []
97
99
  rubyforge_project:
98
- rubygems_version: 2.4.5
100
+ rubygems_version: 2.2.2
99
101
  signing_key:
100
102
  specification_version: 4
101
103
  summary: Takes some boilerplate out of Ruby with methods like attr_initialize.
102
104
  test_files:
105
+ - spec/attr_extras/attr_id_query_spec.rb
106
+ - spec/attr_extras/attr_implement_spec.rb
107
+ - spec/attr_extras/attr_initialize_spec.rb
108
+ - spec/attr_extras/attr_private_spec.rb
109
+ - spec/attr_extras/attr_query_spec.rb
110
+ - spec/attr_extras/attr_value_spec.rb
111
+ - spec/attr_extras/explicit_spec.rb
112
+ - spec/attr_extras/method_object_spec.rb
113
+ - spec/attr_extras/pattr_initialize_spec.rb
114
+ - spec/attr_extras/rattr_initialize_spec.rb
115
+ - spec/attr_extras/static_facade_spec.rb
116
+ - spec/attr_extras/vattr_initialize_spec.rb
103
117
  - spec/attr_extras_spec.rb
104
- - spec/attr_id_query_spec.rb
105
- - spec/attr_implement_spec.rb
106
- - spec/attr_initialize_spec.rb
107
- - spec/attr_private_spec.rb
108
- - spec/attr_query_spec.rb
109
- - spec/attr_value_spec.rb
110
- - spec/method_object_spec.rb
111
- - spec/pattr_initialize_spec.rb
112
- - spec/rattr_initialize_spec.rb
113
118
  - spec/spec_helper.rb
114
- - spec/static_facade_spec.rb
115
- - spec/vattr_initialize_spec.rb
119
+ - spec/spec_helper_without_loading_attr_extras.rb
data/.rvmrc DELETED
@@ -1 +0,0 @@
1
- rvm ruby-1.9.3-p0-patched@attr_extras --create