magic_options 0.0.1 → 1.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.
data/README.md CHANGED
@@ -1,36 +1,55 @@
1
1
  magic_options
2
2
  -------------
3
3
 
4
- MagicOptions is a ruby module that provides an initialize method that takes an
5
- optional hash of options. Each key is taken as the name of an instance
6
- variable, to which the associated value is assigned.
4
+ MagicOptions is a ruby module that provides mechanisms for splatting
5
+ an options hash into an object's instance variables. Each key is taken
6
+ as the name of an instance variable, to which the associated value is
7
+ assigned.
7
8
 
8
- Example
9
- -------
9
+ This is version 1.0.0. It is not backward compatible with previous
10
+ versions at all. This version will be uploaded to rubygems.org within
11
+ the next few days.
12
+
13
+ Examples
14
+ --------
10
15
 
11
16
  ```ruby
12
17
  require 'rubygems'
13
18
  require 'magic_options'
14
19
 
15
- Cow.new :color => "brown", :gender => "female"
16
- => #<Cow:0x7f77e409a6d8 @gender="female", @color="brown">
17
- Cow.new :color => "brown", :gender => "female", :wheels => 4
18
- => ArgumentError: Unknown option wheels for new Cow
19
-
20
20
  class Gullible
21
21
 
22
22
  include MagicOptions
23
23
 
24
+ magic_initialize
25
+
24
26
  end
25
27
 
26
28
  Gullible.new :accepts => "anything"
27
29
  => #<Gullible:0x7f77e407fdb0 @accepts="anything">
28
30
 
31
+ class Cow
32
+
33
+ include MagicOptions
34
+
35
+ magic_initialize :only => :respond_to?
36
+
37
+ attr_accessor :color, :gender
38
+
39
+ end
40
+
41
+ Cow.new :color => "brown", :gender => "female"
42
+ => #<Cow:0x7f77e409a6d8 @gender="female", @color="brown">
43
+ Cow.new :color => "brown", :gender => "female", :wheels => 4
44
+ => ArgumentError: Unknown option wheels for new Cow
45
+
29
46
  class Professor
30
47
 
31
48
  include MagicOptions
32
49
 
33
- magic_options :iq, :hair_style
50
+ def initialize(name, options = {})
51
+ magic_options options, :only => [:iq, :hairstyle]
52
+ end
34
53
 
35
54
  end
36
55
 
@@ -40,6 +59,51 @@ Professor.new :does_not_take => :anything
40
59
  => ArgumentError: Unknown option does_not_take for new Professor
41
60
  ```
42
61
 
62
+ Documentation
63
+ -------------
64
+
65
+ Working code first. For now, here are the specs for the magic_options
66
+ method:
67
+
68
+ ```
69
+ MagicOptions#magic_options(options, config = {})
70
+ Given class Cow mixes in MagicOptions
71
+ When Cow#initialize(options) calls magic_options(options)
72
+ Then Cow.new(:name => 'Daisy', :color => :brown)
73
+ sets @name to 'Daisy'
74
+ sets @color to :brown
75
+ When Cow#initialize(options) calls magic_options(options, :only => [:name, :color])
76
+ Then Cow.new(:name => 'Daisy', :color => :brown)
77
+ sets @name to 'Daisy'
78
+ sets @color to :brown
79
+ Then Cow.new(:name => 'Daisy', :gender => :female)
80
+ raises an ArgumentError
81
+ reports the offending class and the unknown option
82
+ When Cow#initialize(options) calls magic_options(options, :require => :name)
83
+ Then Cow.new(:name => 'Daisy', :color => :brown)
84
+ sets @name to 'Daisy'
85
+ sets @color to :brown
86
+ Then Cow.new(:color => :brown)
87
+ raises an ArgumentError
88
+ reports the offending class and the missing option
89
+ When Cow#initialize(options) calls magic_options(options, :only => :color, :require => :name)
90
+ Then Cow.new(:name => 'Daisy', :color => :brown)
91
+ sets @name to 'Daisy'
92
+ sets @color to :brown
93
+ Then Cow.new(:color => :brown)
94
+ raises an ArgumentError
95
+ reports the offending class and the missing option
96
+ ```
97
+
98
+ MagicOptions::ClassMethods#magic_initialize(config = {}) creates an
99
+ initialize method that works like this:
100
+
101
+ ```ruby
102
+ def initialize(options = {})
103
+ magic_options(options, config)
104
+ end
105
+ ```
106
+
43
107
  Obtaining
44
108
  ---------
45
109
 
@@ -1,3 +1,3 @@
1
1
  module MagicOptions
2
- VERSION = "0.0.1"
2
+ VERSION = "1.0.0"
3
3
  end
data/lib/magic_options.rb CHANGED
@@ -2,10 +2,10 @@ require "magic_options/version"
2
2
 
3
3
  module MagicOptions
4
4
 
5
- def initialize(options = {})
5
+ def magic_options(options, config = {})
6
+ magic_options_validate(options, config)
6
7
  options.each do |option, value|
7
- magic_options_validate(option)
8
- instance_variable_set "@#{option}".to_sym, value
8
+ instance_variable_set "@#{option}", value
9
9
  end
10
10
  end
11
11
 
@@ -15,24 +15,37 @@ module MagicOptions
15
15
 
16
16
  module ClassMethods
17
17
 
18
- attr_accessor :magic_options_allowed
18
+ attr_accessor :magic_options_config
19
19
 
20
- def magic_options(*allowed)
21
- self.magic_options_allowed = allowed
20
+ def magic_initialize(config = {})
21
+ self.magic_options_config = config
22
+ class_eval %{
23
+ def initialize(options = {})
24
+ magic_options(options, self.class.magic_options_config)
25
+ end
26
+ }
22
27
  end
23
28
 
24
29
  end
25
30
 
26
31
  private
27
32
 
28
- def magic_options_validate(option)
29
- return unless allowed = self.class.magic_options_allowed
30
- if allowed[0] == :accessors
31
- return if respond_to?(option)
32
- else
33
- return if allowed.include?(option)
33
+ def magic_options_validate(options, config)
34
+ if config[:only] == :respond_to?
35
+ if unknown = options.keys.detect { |option| !respond_to?(option) }
36
+ raise ArgumentError, "Unknown option #{unknown} in new #{self.class}"
37
+ end
38
+ elsif config[:only]
39
+ only = [config[:only], config[:require]].flatten.compact
40
+ if unknown = options.keys.detect { |option| !only.include?(option) }
41
+ raise ArgumentError, "Unknown option #{unknown} in new #{self.class}"
42
+ end
43
+ end
44
+ if (required = [config[:require]].flatten.compact).size > 0
45
+ if missing = required.detect { |requirement| !options.keys.include?(requirement) }
46
+ raise ArgumentError, "Missing option #{missing} in new #{self.class}"
47
+ end
34
48
  end
35
- raise ArgumentError, "Unknown option #{option} in new #{self.class}"
36
49
  end
37
50
 
38
51
  end
@@ -0,0 +1,205 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+
3
+ describe "MagicOptions::ClassMethods#magic_initialize" do
4
+
5
+ context "Given class Cow mixes in MagicOptions" do
6
+
7
+ before(:each) do
8
+ require 'magic_options'
9
+ class Cow
10
+ include MagicOptions
11
+ end
12
+ end
13
+
14
+ context "When it calls magic_initialize" do
15
+
16
+ before(:each) do
17
+ class Cow
18
+ magic_initialize
19
+ end
20
+ end
21
+
22
+ context "Then Cow.new(:name => 'Daisy', :color => :brown)" do
23
+
24
+ before(:each) do
25
+ @cow = Cow.new(:name => 'Daisy', :color => :brown)
26
+ end
27
+
28
+ it "sets @name to 'Daisy'" do
29
+ @cow.instance_variable_get('@name').should == 'Daisy'
30
+ end
31
+
32
+ it "sets @color to :brown" do
33
+ @cow.instance_variable_get('@color').should == :brown
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+
40
+ context "When it calls magic_initialize(:only => [:name, :color])" do
41
+
42
+ before(:each) do
43
+ class Cow
44
+ magic_initialize :only => [:name, :color]
45
+ end
46
+ end
47
+
48
+ context "Then Cow.new(:name => 'Daisy', :color => :brown)" do
49
+
50
+ before(:each) do
51
+ @cow = Cow.new(:name => 'Daisy', :color => :brown)
52
+ end
53
+
54
+ it "sets @name to 'Daisy'" do
55
+ @cow.instance_variable_get('@name').should == 'Daisy'
56
+ end
57
+
58
+ it "sets @color to :brown" do
59
+ @cow.instance_variable_get('@color').should == :brown
60
+ end
61
+
62
+ end
63
+
64
+ context "Then Cow.new(:name => 'Daisy', :gender => :female)" do
65
+
66
+ it "raises an ArgumentError" do
67
+ lambda {
68
+ Cow.new(:name => 'Daisy', :gender => :female)
69
+ }.should raise_error(ArgumentError)
70
+ end
71
+
72
+ it "reports the offending class and the unknown option" do
73
+ lambda {
74
+ Cow.new(:name => 'Daisy', :gender => :female)
75
+ }.should raise_error("Unknown option gender in new Cow")
76
+ end
77
+
78
+ end
79
+
80
+ end
81
+
82
+ context "When it calls magic_initialize(:require => :name)" do
83
+
84
+ before(:each) do
85
+ class Cow
86
+ magic_initialize :require => :name
87
+ end
88
+ end
89
+
90
+ context "Then Cow.new(:name => 'Daisy', :color => :brown)" do
91
+
92
+ before(:each) do
93
+ @cow = Cow.new(:name => 'Daisy', :color => :brown)
94
+ end
95
+
96
+ it "sets @name to 'Daisy'" do
97
+ @cow.instance_variable_get('@name').should == 'Daisy'
98
+ end
99
+
100
+ it "sets @color to :brown" do
101
+ @cow.instance_variable_get('@color').should == :brown
102
+ end
103
+
104
+ end
105
+
106
+ context "Then Cow.new(:color => :brown)" do
107
+
108
+ it "raises an ArgumentError" do
109
+ lambda { @cow = Cow.new(:color => :brown) }.should raise_error(ArgumentError)
110
+ end
111
+
112
+ it "reports the offending class and the missing option" do
113
+ lambda { @cow = Cow.new(:color => 'Daisy') }.should raise_error("Missing option name in new Cow")
114
+ end
115
+ end
116
+
117
+ end
118
+
119
+ context "When it calls magic_initialize(:only => :color, :require => :name)" do
120
+
121
+ before(:each) do
122
+ class Cow
123
+ magic_initialize :only => :color, :require => :name
124
+ end
125
+ end
126
+
127
+ context "Then Cow.new(:name => 'Daisy', :color => :brown)" do
128
+
129
+ before(:each) do
130
+ @cow = Cow.new(:name => 'Daisy', :color => :brown)
131
+ end
132
+
133
+ it "sets @name to 'Daisy'" do
134
+ @cow.instance_variable_get('@name').should == 'Daisy'
135
+ end
136
+
137
+ it "sets @color to :brown" do
138
+ @cow.instance_variable_get('@color').should == :brown
139
+ end
140
+
141
+ end
142
+
143
+ context "Then Cow.new(:color => :brown)" do
144
+
145
+ it "raises an ArgumentError" do
146
+ lambda { @cow = Cow.new(:color => :brown) }.should raise_error(ArgumentError)
147
+ end
148
+
149
+ it "reports the offending class and the missing option" do
150
+ lambda { @cow = Cow.new(:color => 'Daisy') }.should raise_error("Missing option name in new Cow")
151
+ end
152
+
153
+ end
154
+
155
+ end
156
+
157
+ context "When Cow calls attr_accessor(:name)" do
158
+
159
+ before(:each) do
160
+ class Cow
161
+ attr_accessor :name
162
+ end
163
+ end
164
+
165
+ context "When it calls magic_initialize(:only => :respond_to?)" do
166
+
167
+ before(:each) do
168
+ class Cow
169
+ magic_initialize :only => :respond_to?
170
+ end
171
+ end
172
+
173
+ context "Then Cow.new(:name => 'Daisy')" do
174
+
175
+ it "sets @name to 'Daisy'" do
176
+ @cow = Cow.new(:name => 'Daisy')
177
+ @cow.instance_variable_get('@name').should == 'Daisy'
178
+ end
179
+
180
+ end
181
+
182
+ context "Then Cow.new(:name => 'Daisy', :gender => :female)" do
183
+
184
+ it "raises an ArgumentError" do
185
+ lambda {
186
+ Cow.new(:name => 'Daisy', :gender => :female)
187
+ }.should raise_error(ArgumentError)
188
+ end
189
+
190
+ it "reports the offending class and the unknown option" do
191
+ lambda {
192
+ Cow.new(:name => 'Daisy', :gender => :female)
193
+ }.should raise_error("Unknown option gender in new Cow")
194
+ end
195
+
196
+ end
197
+
198
+ end
199
+
200
+ end
201
+
202
+ end
203
+
204
+ end
205
+
@@ -0,0 +1,168 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+
3
+ describe "MagicOptions#magic_options" do
4
+
5
+ context "Given class Cow mixes in MagicOptions" do
6
+
7
+ before(:each) do
8
+ require 'magic_options'
9
+ class Cow
10
+ include MagicOptions
11
+ end
12
+ end
13
+
14
+ context "When Cow#initialize(options) calls magic_options(options)" do
15
+
16
+ before(:each) do
17
+ class Cow
18
+ def initialize(options = {})
19
+ magic_options options
20
+ end
21
+ end
22
+ end
23
+
24
+ context "Then Cow.new(:name => 'Daisy', :color => :brown)" do
25
+
26
+ before(:each) do
27
+ @cow = Cow.new(:name => 'Daisy', :color => :brown)
28
+ end
29
+
30
+ it "sets @name to 'Daisy'" do
31
+ @cow.instance_variable_get('@name').should == 'Daisy'
32
+ end
33
+
34
+ it "sets @color to :brown" do
35
+ @cow.instance_variable_get('@color').should == :brown
36
+ end
37
+
38
+ end
39
+
40
+ end
41
+
42
+ context "When Cow#initialize(options) calls magic_options(options, :only => [:name, :color])" do
43
+
44
+ before(:each) do
45
+ class Cow
46
+ def initialize(options)
47
+ magic_options(options, :only => [:name, :color])
48
+ end
49
+ end
50
+ end
51
+
52
+ context "Then Cow.new(:name => 'Daisy', :color => :brown)" do
53
+
54
+ before(:each) do
55
+ @cow = Cow.new(:name => 'Daisy', :color => :brown)
56
+ end
57
+
58
+ it "sets @name to 'Daisy'" do
59
+ @cow.instance_variable_get('@name').should == 'Daisy'
60
+ end
61
+
62
+ it "sets @color to :brown" do
63
+ @cow.instance_variable_get('@color').should == :brown
64
+ end
65
+
66
+ end
67
+
68
+ context "Then Cow.new(:name => 'Daisy', :gender => :female)" do
69
+
70
+ it "raises an ArgumentError" do
71
+ lambda {
72
+ Cow.new(:name => 'Daisy', :gender => :female)
73
+ }.should raise_error(ArgumentError)
74
+ end
75
+
76
+ it "reports the offending class and the unknown option" do
77
+ lambda {
78
+ Cow.new(:name => 'Daisy', :gender => :female)
79
+ }.should raise_error("Unknown option gender in new Cow")
80
+ end
81
+
82
+ end
83
+
84
+ end
85
+
86
+ context "When Cow#initialize(options) calls magic_options(options, :require => :name)" do
87
+
88
+ before(:each) do
89
+ class Cow
90
+ def initialize(options)
91
+ magic_options(options, :require => :name)
92
+ end
93
+ end
94
+ end
95
+
96
+ context "Then Cow.new(:name => 'Daisy', :color => :brown)" do
97
+
98
+ before(:each) do
99
+ @cow = Cow.new(:name => 'Daisy', :color => :brown)
100
+ end
101
+
102
+ it "sets @name to 'Daisy'" do
103
+ @cow.instance_variable_get('@name').should == 'Daisy'
104
+ end
105
+
106
+ it "sets @color to :brown" do
107
+ @cow.instance_variable_get('@color').should == :brown
108
+ end
109
+
110
+ end
111
+
112
+ context "Then Cow.new(:color => :brown)" do
113
+
114
+ it "raises an ArgumentError" do
115
+ lambda { @cow = Cow.new(:color => :brown) }.should raise_error(ArgumentError)
116
+ end
117
+
118
+ it "reports the offending class and the missing option" do
119
+ lambda { @cow = Cow.new(:color => 'Daisy') }.should raise_error("Missing option name in new Cow")
120
+ end
121
+ end
122
+
123
+ end
124
+
125
+ context "When Cow#initialize(options) calls magic_options(options, :only => :color, :require => :name)" do
126
+
127
+ before(:each) do
128
+ class Cow
129
+ def initialize(options)
130
+ magic_options(options, :only => :color, :require => :name)
131
+ end
132
+ end
133
+ end
134
+
135
+ context "Then Cow.new(:name => 'Daisy', :color => :brown)" do
136
+
137
+ before(:each) do
138
+ @cow = Cow.new(:name => 'Daisy', :color => :brown)
139
+ end
140
+
141
+ it "sets @name to 'Daisy'" do
142
+ @cow.instance_variable_get('@name').should == 'Daisy'
143
+ end
144
+
145
+ it "sets @color to :brown" do
146
+ @cow.instance_variable_get('@color').should == :brown
147
+ end
148
+
149
+ end
150
+
151
+ context "Then Cow.new(:color => :brown)" do
152
+
153
+ it "raises an ArgumentError" do
154
+ lambda { @cow = Cow.new(:color => :brown) }.should raise_error(ArgumentError)
155
+ end
156
+
157
+ it "reports the offending class and the missing option" do
158
+ lambda { @cow = Cow.new(:color => 'Daisy') }.should raise_error("Missing option name in new Cow")
159
+ end
160
+
161
+ end
162
+
163
+ end
164
+
165
+ end
166
+
167
+ end
168
+
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: magic_options
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
+ - 1
7
8
  - 0
8
9
  - 0
9
- - 1
10
- version: 0.0.1
10
+ version: 1.0.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Sheldon Hearn
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-09-23 00:00:00 Z
19
+ date: 2011-09-25 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: rspec
@@ -50,7 +50,8 @@ files:
50
50
  - lib/magic_options.rb
51
51
  - lib/magic_options/version.rb
52
52
  - magic_options.gemspec
53
- - spec/magic_options/magic_options_spec.rb
53
+ - spec/magic_options/class_method_spec.rb
54
+ - spec/magic_options/instance_method_spec.rb
54
55
  - spec/spec_helper.rb
55
56
  homepage: http://github.com/sheldonh/magic_options
56
57
  licenses: []
@@ -1,87 +0,0 @@
1
- require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
-
3
- describe "MagicOptions" do
4
-
5
- require 'magic_options'
6
- class Klazz
7
- include MagicOptions
8
- attr_accessor :accessible
9
- end
10
-
11
- context "without specifying magic_options" do
12
-
13
- it "sets instance variables for all options" do
14
- object = Klazz.new(:color => "green")
15
- object.instance_variables.should include("@color")
16
- object.instance_variable_get(:@color).should == "green"
17
- end
18
-
19
- end
20
-
21
- context "with magic_options :accessors" do
22
-
23
- before(:each) do
24
- Klazz.send :magic_options, :accessors
25
- end
26
-
27
- it "allows options named after accessors" do
28
- lambda {
29
- object = Klazz.new(:accessible => "is an accessor")
30
- }.should_not raise_error
31
- end
32
-
33
- it "disallows any other option" do
34
- lambda {
35
- object = Klazz.new(:color => "is not an accessor")
36
- }.should raise_error(ArgumentError)
37
- end
38
-
39
- end
40
-
41
- context "with magic_options :color, :shape" do
42
-
43
- before(:each) do
44
- Klazz.send :magic_options, :color, :shape
45
- end
46
-
47
- it "allows an option called :color" do
48
- lambda {
49
- object = Klazz.new(:color => "green")
50
- }.should_not raise_error
51
- end
52
-
53
- it "allows options an option called :shape" do
54
- lambda {
55
- object = Klazz.new(:shape => "round")
56
- }.should_not raise_error
57
- end
58
-
59
- it "disallows any other option" do
60
- lambda {
61
- object = Klazz.new(:size => "is not a magic option")
62
- }.should raise_error
63
- end
64
-
65
- end
66
-
67
- context "with a disallowed option" do
68
-
69
- before(:each) do
70
- Klazz.send :magic_options, :allowed
71
- end
72
-
73
- it "raises an ArgumentError" do
74
- lambda {
75
- object = Klazz.new(:size => "is not a magic option")
76
- }.should raise_error(ArgumentError)
77
- end
78
-
79
- it "says which class disallowed which option" do
80
- lambda {
81
- object = Klazz.new(:size => "is not a magic option")
82
- }.should raise_error("Unknown option size in new Klazz")
83
- end
84
-
85
- end
86
-
87
- end