magic_options 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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