attr_extras 4.3.0 → 4.4.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
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