doodle 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -57,6 +57,24 @@ class Doodle
57
57
  end
58
58
  end
59
59
 
60
+ def boolean(name, params = { }, &block)
61
+ define name, params, block, { } do
62
+ must "be true or false" do |v|
63
+ [true, false].include?(v)
64
+ end
65
+ from String, Symbol do |v|
66
+ case v.to_s
67
+ when /^(yes|true|on)$/
68
+ true
69
+ when /^(no|false|off)$/
70
+ false
71
+ else
72
+ v
73
+ end
74
+ end
75
+ end
76
+ end
77
+
60
78
  def symbol(name, params = { }, &block)
61
79
  define name, params, block, { :kind => Symbol } do
62
80
  from String do |s|
@@ -112,12 +130,7 @@ class Doodle
112
130
  # 384 = 128+1+255
113
131
  string(name, { :max => 384 }.merge(params), &block).instance_eval do
114
132
  must "be valid email address" do |s|
115
- if RUBY_VERSION >= '1.9.0'
116
- # the regex fails in 1.9 with illegal utf byte sequence error
117
- s =~ /\A.*@.*\z/
118
- else
119
- s =~ RFC822::EmailAddress
120
- end
133
+ s =~ RFC822::EmailAddress
121
134
  end
122
135
  end
123
136
  end
@@ -12,20 +12,27 @@
12
12
  # http://creativecommons.org/licenses/by-sa/2.5/
13
13
  #
14
14
  module RFC822
15
- EmailAddress = begin
16
- qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]'
17
- dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]'
18
- atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-' +
19
- '\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+'
20
- quoted_pair = '\\x5c[\\x00-\\x7f]'
21
- domain_literal = "\\x5b(?:#{dtext}|#{quoted_pair})*\\x5d"
22
- quoted_string = "\\x22(?:#{qtext}|#{quoted_pair})*\\x22"
23
- domain_ref = atom
24
- sub_domain = "(?:#{domain_ref}|#{domain_literal})"
25
- word = "(?:#{atom}|#{quoted_string})"
26
- domain = "#{sub_domain}(?:\\x2e#{sub_domain})*"
27
- local_part = "#{word}(?:\\x2e#{word})*"
28
- addr_spec = "#{local_part}\\x40#{domain}"
29
- pattern = /\A#{addr_spec}\z/
15
+ # TODO: fix the illegal multibyte sequence in 1.9
16
+ # the regex fails in 1.9 with illegal utf byte sequence error
17
+ if RUBY_VERSION < '1.9.0'
18
+ EmailAddress = begin
19
+ qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]'
20
+ dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]'
21
+ atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-' +
22
+ '\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+'
23
+ quoted_pair = '\\x5c[\\x00-\\x7f]'
24
+ domain_literal = "\\x5b(?:#{dtext}|#{quoted_pair})*\\x5d"
25
+ quoted_string = "\\x22(?:#{qtext}|#{quoted_pair})*\\x22"
26
+ domain_ref = atom
27
+ sub_domain = "(?:#{domain_ref}|#{domain_literal})"
28
+ word = "(?:#{atom}|#{quoted_string})"
29
+ domain = "#{sub_domain}(?:\\x2e#{sub_domain})*"
30
+ local_part = "#{word}(?:\\x2e#{word})*"
31
+ addr_spec = "#{local_part}\\x40#{domain}"
32
+ pattern = /\A#{addr_spec}\z/
33
+ end
34
+ else
35
+ # minimal regex until I sort out the problem above
36
+ EmailAddress = /\A.*@.*\z/
30
37
  end
31
38
  end
@@ -2,7 +2,7 @@ class Doodle #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 1
5
- TINY = 3
5
+ TINY = 4
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -12,9 +12,9 @@ describe 'arg_order' do
12
12
  end
13
13
  it 'should specify order of positional arguments' do
14
14
  foo = Foo.new 1, 2, 3
15
- foo.value.should == 1
16
- foo.name.should == 2
17
- foo.extra.should == 3
15
+ foo.value.should_be 1
16
+ foo.name.should_be 2
17
+ foo.extra.should_be 3
18
18
  end
19
19
 
20
20
  it 'should allow only symbols as arguments to arg_order' do
@@ -42,8 +42,8 @@ describe 'arg_order' do
42
42
  end
43
43
  it 'should specify order of positional arguments' do
44
44
  f = Bar.new 1, 2
45
- f.name.should == 1
46
- f.value.should == 2
45
+ f.name.should_be 1
46
+ f.value.should_be 2
47
47
  end
48
48
  end
49
49
  end
@@ -61,8 +61,8 @@ describe 'arg_order' do
61
61
  end
62
62
  it 'should specify order of positional arguments' do
63
63
  f = Bar.new 1, 2
64
- f.value.should == 1
65
- f.name.should == 2
64
+ f.value.should_be 1
65
+ f.name.should_be 2
66
66
  end
67
67
  end
68
68
  end
@@ -81,8 +81,8 @@ describe 'arg_order' do
81
81
 
82
82
  it 'should specify order of positional arguments' do
83
83
  f = Bar.new 1
84
- f.value.should == 1
85
- f.name.should == "bar"
84
+ f.value.should_be 1
85
+ f.name.should_be "bar"
86
86
  end
87
87
  end
88
88
  end
@@ -101,8 +101,8 @@ describe 'arg_order' do
101
101
 
102
102
  it 'should specify order of positional arguments' do
103
103
  f = Bar.new 1, "bar"
104
- f.value.should == 1
105
- f.name.should == "bar"
104
+ f.value.should_be 1
105
+ f.name.should_be "bar"
106
106
  end
107
107
  end
108
108
  end
@@ -64,10 +64,10 @@ describe Doodle::Attribute, 'basics' do
64
64
  @bar.attributes[:ivar2].optional?.should == false
65
65
  end
66
66
 
67
- it "should have parents in correct order" do
68
- expected_parents = RUBY_VERSION <= "1.8.6" ? [Foo, Object] : [Foo, Object, BasicObject]
69
- Bar.parents.should == expected_parents
70
- end
67
+ # it "should have parents in correct order" do
68
+ # expected_parents = RUBY_VERSION <= "1.8.6" ? [Foo, Object] : [Foo, Object, BasicObject]
69
+ # Bar.parents.should == expected_parents
70
+ # end
71
71
 
72
72
  it "should have Bar's singleton parents in reverse order of definition" do
73
73
  @bar.singleton_class.parents.should == []
@@ -128,10 +128,10 @@ describe Doodle::Attribute, 'attribute order' do
128
128
  end
129
129
  end
130
130
 
131
- it 'should keep order of inherited attributes' do
132
- expected_parents = RUBY_VERSION <= "1.8.6" ? [B, A, Doodle, Object] : [B, A, Doodle, Object, BasicObject]
133
- C.parents.should == expected_parents
134
- end
131
+ # it 'should keep order of inherited attributes' do
132
+ # expected_parents = RUBY_VERSION <= "1.8.6" ? [B, A, Doodle, Object] : [B, A, Doodle, Object, BasicObject]
133
+ # C.parents.should == expected_parents
134
+ # end
135
135
 
136
136
  it 'should keep order of inherited attributes' do
137
137
  C.attributes.keys.should == [:a, :b, :c]
@@ -15,8 +15,8 @@ describe 'Doodle', 'parents' do
15
15
 
16
16
  it 'should not duplicate validations when accessing them!' do
17
17
  foo = Foo 2
18
- foo.validations.size.should == 1
19
- foo.validations.size.should == 1
18
+ foo.validations.size.should_be 1
19
+ foo.validations.size.should_be 1
20
20
  end
21
21
  end
22
22
  end
@@ -48,8 +48,8 @@ describe 'Doodle', ' loading good data from yaml' do
48
48
 
49
49
  it 'should apply conversions' do
50
50
  foo = YAML::load(@str).validate!
51
- foo.date.should == Date.new(2000, 7, 1)
52
- foo.date.class.should == Date
51
+ foo.date.should_be Date.new(2000, 7, 1)
52
+ foo.date.class.should_be Date
53
53
  end
54
54
  end
55
55
  end
@@ -124,7 +124,7 @@ describe Doodle, 'initializing from hashes and yaml' do
124
124
  yaml = person.to_yaml
125
125
  # be careful here - Ruby yaml is finicky (spaces after class names)
126
126
  yaml = yaml.gsub(/\s*\n/m, "\n")
127
- yaml.should == %[--- !ruby/object:Person
127
+ yaml.should_be %[--- !ruby/object:Person
128
128
  address:
129
129
  - !ruby/object:AddressLine
130
130
  text: Henry Wood House
@@ -134,7 +134,7 @@ name: Sean
134
134
  ]
135
135
  person = YAML.load(yaml)
136
136
  proc { person.validate! }.should_not raise_error
137
- person.address.all?{ |x| x.kind_of? AddressLine }.should == true
137
+ person.address.all?{ |x| x.kind_of? AddressLine }.should_be true
138
138
 
139
139
  end
140
140
  end
@@ -167,7 +167,7 @@ describe 'Doodle', 'hiding @__doodle__' do
167
167
  end
168
168
  it 'should not include @__doodle__ in instance_variables' do
169
169
  foo = Foo 2
170
- foo.instance_variables.size.should == 1
170
+ foo.instance_variables.size.should_be 1
171
171
  foo.instance_variables.first.should =~ /^@var1$/
172
172
  end
173
173
  it 'should not reveal @__doodle__ in inspect string' do
@@ -176,7 +176,7 @@ describe 'Doodle', 'hiding @__doodle__' do
176
176
  end
177
177
  it 'should not include @__doodle__ in instance_variables' do
178
178
  foo = Bar 2
179
- foo.instance_variables.size.should == 1
179
+ foo.instance_variables.size.should_be 1
180
180
  foo.instance_variables.first.should =~ /^@var2$/
181
181
  end
182
182
  it 'should correctly inspect when using included module' do
@@ -185,17 +185,17 @@ describe 'Doodle', 'hiding @__doodle__' do
185
185
  end
186
186
  it 'should correctly inspect string' do
187
187
  foo = DString("Hello")
188
- foo.inspect.should == '"Hello"'
188
+ foo.inspect.should_be '"Hello"'
189
189
  end
190
190
  it 'should correctly inspect hash' do
191
191
  foo = DHash.new(2)
192
192
  foo[:a] = 1
193
- foo.inspect.should == '{:a=>1}'
194
- foo[:b].should == 2
193
+ foo.inspect.should_be '{:a=>1}'
194
+ foo[:b].should_be 2
195
195
  end
196
196
  it 'should correctly inspect array' do
197
197
  foo = DArray(3, 2)
198
- foo.inspect.should == '[2, 2, 2]'
198
+ foo.inspect.should_be '[2, 2, 2]'
199
199
  end
200
200
  end
201
201
  end
@@ -22,65 +22,65 @@ describe Doodle, 'class attributes' do
22
22
 
23
23
  it 'should create class attribute' do
24
24
  Foo.metadata = 'Foo metadata'
25
- Foo.metadata.should == 'Foo metadata'
25
+ Foo.metadata.should_be 'Foo metadata'
26
26
  end
27
27
 
28
28
  it 'should access @foo class attribute via self.class' do
29
29
  @foo.class.metadata = '@foo metadata'
30
- @foo.class.metadata.should == '@foo metadata'
31
- Foo.metadata.should == '@foo metadata'
30
+ @foo.class.metadata.should_be '@foo metadata'
31
+ Foo.metadata.should_be '@foo metadata'
32
32
 
33
33
  Foo.metadata = 'Foo metadata'
34
- Foo.metadata.should == 'Foo metadata'
35
- @foo.class.metadata.should == 'Foo metadata'
34
+ Foo.metadata.should_be 'Foo metadata'
35
+ @foo.class.metadata.should_be 'Foo metadata'
36
36
  end
37
37
 
38
38
  it "should list all class's own attributes" do
39
- Foo.singleton_class.attributes(false).keys.should == [:metadata]
39
+ Foo.singleton_class.attributes(false).keys.should_be [:metadata]
40
40
  end
41
41
 
42
42
  it "should list all class's own attributes" do
43
- Foo.singleton_class.attributes.keys.should == [:metadata]
43
+ Foo.singleton_class.attributes.keys.should_be [:metadata]
44
44
  end
45
45
 
46
46
  it 'should create Bar class attribute' do
47
47
  Bar.metadata = 'Bar metadata'
48
- Bar.metadata.should == 'Bar metadata'
48
+ Bar.metadata.should_be 'Bar metadata'
49
49
  end
50
50
 
51
51
  it 'should access @bar class attribute via self.class' do
52
52
  @bar.class.metadata = '@bar metadata'
53
- @bar.class.metadata.should == '@bar metadata'
54
- Bar.metadata.should == '@bar metadata'
53
+ @bar.class.metadata.should_be '@bar metadata'
54
+ Bar.metadata.should_be '@bar metadata'
55
55
 
56
56
  Bar.metadata = 'Bar metadata'
57
- Bar.metadata.should == 'Bar metadata'
58
- @bar.class.metadata.should == 'Bar metadata'
57
+ Bar.metadata.should_be 'Bar metadata'
58
+ @bar.class.metadata.should_be 'Bar metadata'
59
59
  end
60
60
 
61
61
  it 'should not allow inherited class attributes to interfere with each other' do
62
62
  Foo.metadata = 'Foo metadata'
63
63
  @bar.class.metadata = '@bar metadata'
64
- @bar.class.metadata.should == '@bar metadata'
65
- Bar.metadata.should == '@bar metadata'
64
+ @bar.class.metadata.should_be '@bar metadata'
65
+ Bar.metadata.should_be '@bar metadata'
66
66
 
67
67
  Bar.metadata = 'Bar metadata'
68
- Bar.metadata.should == 'Bar metadata'
69
- @bar.class.metadata.should == 'Bar metadata'
68
+ Bar.metadata.should_be 'Bar metadata'
69
+ @bar.class.metadata.should_be 'Bar metadata'
70
70
 
71
- Foo.metadata.should == 'Foo metadata'
72
- @foo.class.metadata.should == 'Foo metadata'
71
+ Foo.metadata.should_be 'Foo metadata'
72
+ @foo.class.metadata.should_be 'Foo metadata'
73
73
  end
74
74
 
75
75
  it "should list all class's own attributes" do
76
- Bar.singleton_class.attributes(false).keys.should == [:doc]
76
+ Bar.singleton_class.attributes(false).keys.should_be [:doc]
77
77
  end
78
78
 
79
79
  it "should list all class's singleton attributes" do
80
- Bar.singleton_class.attributes.keys.should == [:doc]
80
+ Bar.singleton_class.attributes.keys.should_be [:doc]
81
81
  end
82
82
  it "should list all class's class_attributes" do
83
- Bar.class_attributes.keys.should == [:metadata, :doc]
83
+ Bar.class_attributes.keys.should_be [:metadata, :doc]
84
84
  end
85
85
  end
86
86
  end
@@ -16,11 +16,11 @@ describe Doodle, "Simple collector" do
16
16
  end
17
17
 
18
18
  it "should define a collector method :item" do
19
- @foo.methods.map{ |x| x.to_sym }.include?(:item).should == true
19
+ @foo.methods.map{ |x| x.to_sym }.include?(:item).should_be true
20
20
  end
21
21
 
22
22
  it "should collect items into attribute :list" do
23
- @foo.list.should == ["Hello", "World"]
23
+ @foo.list.should_be ["Hello", "World"]
24
24
  end
25
25
 
26
26
  end
@@ -37,7 +37,11 @@ describe Doodle, "Typed collector with default collector name" do
37
37
  end
38
38
  @event = Event do
39
39
  location "Stage 1"
40
- location "Stage 2"
40
+ # todo: move this into spec
41
+ # should handle collected arguments with block only
42
+ location do
43
+ name "Stage 2"
44
+ end
41
45
  end
42
46
  end
43
47
  after :each do
@@ -45,11 +49,11 @@ describe Doodle, "Typed collector with default collector name" do
45
49
  end
46
50
 
47
51
  it "should define a collector method :location" do
48
- @event.methods.map{ |x| x.to_sym }.include?(:location).should == true
52
+ @event.methods.map{ |x| x.to_sym }.include?(:location).should_be true
49
53
  end
50
54
 
51
55
  it "should collect items into attribute :list" do
52
- @event.locations.map{|loc| loc.name}.should == ["Stage 1", "Stage 2"]
56
+ @event.locations.map{|loc| loc.name}.should_be ["Stage 1", "Stage 2"]
53
57
  end
54
58
 
55
59
  end
@@ -66,7 +70,7 @@ describe Doodle, "Typed collector with specified collector name" do
66
70
  end
67
71
  end
68
72
  it "should define a collector method :place" do
69
- Event.instance_methods.map{ |x| x.to_sym}.include?(:place).should == true
73
+ Event.instance_methods.map{ |x| x.to_sym}.include?(:place).should_be true
70
74
  end
71
75
  end
72
76
  end
@@ -89,8 +93,8 @@ describe Doodle, "typed collector with specified collector name" do
89
93
  place "Stage 2"
90
94
  end
91
95
  }.should_not raise_error
92
- event.locations.map{|loc| loc.name}.should == ["Stage 1", "Stage 2"]
93
- event.locations.map{|loc| loc.class}.should == [Location, Location]
96
+ event.locations.map{|loc| loc.name}.should_be ["Stage 1", "Stage 2"]
97
+ event.locations.map{|loc| loc.class}.should_be [Location, Location]
94
98
  end
95
99
  end
96
100
  end
@@ -122,10 +126,82 @@ describe Doodle, "typed collector with specified collector name initialized from
122
126
  proc {
123
127
  event = Event(data)
124
128
  }.should_not raise_error
125
- event.locations.map{|loc| loc.name}.should == ["Stage 1", "Stage 2"]
126
- event.locations.map{|loc| loc.class}.should == [Location, Location]
127
- event.locations[0].events[0].kind_of?(Event).should == true
129
+ event.locations.map{|loc| loc.name}.should_be ["Stage 1", "Stage 2"]
130
+ event.locations.map{|loc| loc.class}.should_be [Location, Location]
131
+ event.locations[0].events[0].kind_of?(Event).should_be true
128
132
  end
129
133
  end
130
134
  end
131
135
 
136
+ describe Doodle, "Simple keyed collector" do
137
+ temporary_constant :Foo do
138
+ before :each do
139
+ class Foo < Doodle
140
+ has :list, :collect => :item, :key => :size
141
+ end
142
+ @foo = Foo do
143
+ item "Hello"
144
+ item "World"
145
+ end
146
+ end
147
+ after :each do
148
+ remove_ivars :foo
149
+ end
150
+
151
+ it "should define a collector method :item" do
152
+ @foo.methods.map{ |x| x.to_sym }.include?(:item).should_be true
153
+ end
154
+
155
+ it "should collect items into attribute :list" do
156
+ @foo.list.should_be( { 5 => "World" } )
157
+ end
158
+
159
+ end
160
+ end
161
+
162
+ describe Doodle, "Simple keyed collector #2" do
163
+ temporary_constant :Foo, :Item do
164
+ before :each do
165
+ class Item < Doodle
166
+ has :name
167
+ end
168
+ class Foo < Doodle
169
+ has :list, :collect => Item, :key => :name
170
+ end
171
+ end
172
+
173
+ it "should define a collector method :item" do
174
+ foo = Foo.new
175
+ foo.methods.map{ |x| x.to_sym }.include?(:item).should_be true
176
+ foo.respond_to?(:item).should_be true
177
+ end
178
+
179
+ it "should collect items into attribute :list #1" do
180
+ foo = Foo do
181
+ item "Hello"
182
+ item "World"
183
+ end
184
+ foo.list.to_a.map{ |k, v| [k, v.class, v.name] }.should_be( [["Hello", Item, "Hello"], ["World", Item, "World"]] )
185
+ end
186
+
187
+ it "should collect keyword argument enumerable into attribute :list" do
188
+ foo = Foo(:list =>
189
+ [
190
+ { :name => "Hello" },
191
+ { :name => "World" }
192
+ ]
193
+ )
194
+ foo.list.to_a.map{ |k, v| [k, v.class, v.name] }.should_be( [["Hello", Item, "Hello"], ["World", Item, "World"]] )
195
+ end
196
+
197
+ it "should collect positional argument enumerable into attribute :list" do
198
+ foo = Foo([
199
+ { :name => "Hello" },
200
+ { :name => "World" }
201
+ ]
202
+ )
203
+ foo.list.to_a.map{ |k, v| [k, v.class, v.name] }.should_be( [["Hello", Item, "Hello"], ["World", Item, "World"]] )
204
+ end
205
+
206
+ end
207
+ end