doodle 0.0.10 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CREDITS +22 -0
- data/{ChangeLog → History.txt} +22 -3
- data/License.txt +20 -0
- data/Manifest.txt +61 -0
- data/README.txt +166 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +77 -0
- data/config/requirements.rb +15 -0
- data/examples/doodle-errors.rb +25 -0
- data/examples/event-location.rb +3 -7
- data/examples/example-01.rb +1 -1
- data/examples/example-01.rdoc +3 -3
- data/examples/example-02.rb +15 -4
- data/examples/example-02.rdoc +17 -5
- data/examples/mail-datatypes.rb +104 -0
- data/examples/mail.rb +85 -0
- data/examples/parent.rb +40 -0
- data/examples/profile-options.rb +67 -0
- data/examples/smtp_tls.rb +65 -0
- data/examples/test-datatypes.rb +55 -0
- data/examples/yaml-example.rb +40 -0
- data/examples/yaml-example2.rb +42 -0
- data/lib/doodle.rb +364 -301
- data/lib/doodle/datatypes.rb +148 -0
- data/lib/doodle/rfc822.rb +31 -0
- data/lib/doodle/utils.rb +13 -0
- data/lib/doodle/version.rb +9 -0
- data/log/debug.log +0 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +82 -0
- data/setup.rb +1585 -0
- data/spec/arg_order_spec.rb +5 -5
- data/spec/attributes_spec.rb +66 -24
- data/spec/bugs_spec.rb +109 -6
- data/spec/class_spec.rb +7 -4
- data/spec/class_validation_spec.rb +46 -0
- data/spec/class_var_spec.rb +76 -0
- data/spec/collector_spec.rb +16 -30
- data/spec/conversion_spec.rb +8 -3
- data/spec/defaults_spec.rb +4 -4
- data/spec/doodle_context_spec.rb +3 -4
- data/spec/doodle_spec.rb +25 -15
- data/spec/extra_args_spec.rb +1 -1
- data/spec/factory_spec.rb +3 -3
- data/spec/init_spec.rb +11 -11
- data/spec/new_doodle_spec.rb +19 -0
- data/spec/required_spec.rb +1 -1
- data/spec/serialization_spec.rb +3 -6
- data/spec/singleton_spec.rb +5 -5
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +44 -0
- data/spec/superclass_spec.rb +6 -5
- data/spec/validation2_spec.rb +248 -0
- data/spec/validation_spec.rb +26 -37
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/rspec.rake +21 -0
- data/tasks/website.rake +17 -0
- metadata +76 -20
- data/COPYING +0 -18
- data/README +0 -57
- data/examples/event.rb +0 -39
- data/examples/example-03.rb +0 -45
- data/examples/example-03.rdoc +0 -55
- data/lib/semantic.cache +0 -8
data/spec/required_spec.rb
CHANGED
data/spec/serialization_spec.rb
CHANGED
@@ -4,7 +4,7 @@ require 'yaml'
|
|
4
4
|
describe Doodle, "Serialization" do
|
5
5
|
temporary_constant :Foo do
|
6
6
|
before :each do
|
7
|
-
class Foo < Doodle
|
7
|
+
class Foo < Doodle
|
8
8
|
has :var, :kind => Integer
|
9
9
|
end
|
10
10
|
@foo = Foo 42
|
@@ -15,11 +15,8 @@ describe Doodle, "Serialization" do
|
|
15
15
|
|
16
16
|
it "should be serializable to yaml" do
|
17
17
|
# is this a bug in the MRI yaml implementation? why the space after Foo?
|
18
|
-
|
19
|
-
|
20
|
-
else
|
21
|
-
@foo.to_yaml.should == "--- !ruby/object:Foo \nvar: 42\n"
|
22
|
-
end
|
18
|
+
# (note: all on one line to pass coverage)
|
19
|
+
RUBY_PLATFORM == 'java' ? @foo.to_yaml.should == "--- !ruby/object:Foo\nvar: 42\n" : @foo.to_yaml.should == "--- !ruby/object:Foo \nvar: 42\n"
|
23
20
|
end
|
24
21
|
|
25
22
|
it "should be loadable from yaml" do
|
data/spec/singleton_spec.rb
CHANGED
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + "/spec_helper.rb"
|
|
3
3
|
describe Doodle, "singletons" do
|
4
4
|
temporary_constant :Foo do
|
5
5
|
it "should allow creating attributes on classes via inheritance" do
|
6
|
-
class Foo < Doodle
|
6
|
+
class Foo < Doodle
|
7
7
|
class << self
|
8
8
|
has :c1
|
9
9
|
end
|
@@ -17,7 +17,7 @@ describe Doodle, "singletons" do
|
|
17
17
|
|
18
18
|
it "should allow creating attributes on classes via module inclusion" do
|
19
19
|
class Foo
|
20
|
-
include Doodle::
|
20
|
+
include Doodle::Core
|
21
21
|
class << self
|
22
22
|
has :c2
|
23
23
|
end
|
@@ -30,13 +30,13 @@ describe Doodle, "singletons" do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should allow creating attributes on singletons via inheritance" do
|
33
|
-
class Foo < Doodle
|
33
|
+
class Foo < Doodle
|
34
34
|
end
|
35
35
|
foo = Foo.new
|
36
36
|
class << foo
|
37
37
|
has :i1
|
38
38
|
end
|
39
|
-
foo.attributes.should ==
|
39
|
+
foo.attributes.keys.should == [:i1]
|
40
40
|
foo.singleton_class.attributes.should_not == OrderedHash.new
|
41
41
|
foo.singleton_class.attributes.map{ |name, attr| name }.should == [:i1]
|
42
42
|
foo.i1 = 1
|
@@ -45,7 +45,7 @@ describe Doodle, "singletons" do
|
|
45
45
|
|
46
46
|
it "should allow creating attributes on a singleton's singleton via module inclusion" do
|
47
47
|
class Foo
|
48
|
-
include Doodle::
|
48
|
+
include Doodle::Core
|
49
49
|
end
|
50
50
|
foo = Foo.new
|
51
51
|
class << foo
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
begin
|
2
|
+
require 'spec'
|
3
|
+
rescue LoadError
|
4
|
+
require 'rubygems'
|
5
|
+
gem 'rspec'
|
6
|
+
require 'spec'
|
7
|
+
end
|
8
|
+
|
9
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
10
|
+
require 'doodle'
|
11
|
+
require 'date'
|
12
|
+
|
13
|
+
# functions to help clean up namespace after defining classes
|
14
|
+
def undefine_const(*consts)
|
15
|
+
consts.each do |const|
|
16
|
+
if Object.const_defined?(const)
|
17
|
+
Object.send(:remove_const, const)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def raise_if_defined(*args)
|
23
|
+
defined, undefined = args.partition{ |x| Object.const_defined?(x)}
|
24
|
+
raise "Namespace pollution: #{defined.join(', ')}" if defined.size > 0
|
25
|
+
end
|
26
|
+
|
27
|
+
def temporary_constants(*args, &block)
|
28
|
+
before :each do
|
29
|
+
raise_if_defined(*args)
|
30
|
+
end
|
31
|
+
after :each do
|
32
|
+
undefine_const(*args)
|
33
|
+
end
|
34
|
+
raise_if_defined(*args)
|
35
|
+
yield
|
36
|
+
raise_if_defined(*args)
|
37
|
+
end
|
38
|
+
alias :temporary_constant :temporary_constants
|
39
|
+
|
40
|
+
def remove_ivars(*args)
|
41
|
+
args.each do |ivar|
|
42
|
+
remove_instance_variable "@#{ivar}"
|
43
|
+
end
|
44
|
+
end
|
data/spec/superclass_spec.rb
CHANGED
@@ -3,21 +3,22 @@ require File.dirname(__FILE__) + '/spec_helper.rb'
|
|
3
3
|
describe 'Doodle', 'parents' do
|
4
4
|
temporary_constant :Foo do
|
5
5
|
before :each do
|
6
|
-
class Foo < Doodle
|
6
|
+
class Foo < Doodle
|
7
7
|
end
|
8
8
|
@foo = Foo.new
|
9
9
|
@sc = class << @foo; self; end
|
10
10
|
@scc = class << @sc; self; end
|
11
|
-
@sclass_doodle_root = class << Doodle
|
11
|
+
@sclass_doodle_root = class << Doodle; self; end
|
12
12
|
@sclass_foo = class << @foo; class << self; self; end; end
|
13
13
|
end
|
14
14
|
|
15
|
-
it 'should have singleton
|
16
|
-
@sc.parents.should == [
|
15
|
+
it 'should have no singleton parents ' do
|
16
|
+
@sc.parents.should == []
|
17
17
|
end
|
18
18
|
|
19
19
|
it "should have singleton class's singleton class parents == []" do
|
20
|
-
|
20
|
+
expected_parents = RUBY_VERSION <= "1.8.6" ? [] : [Module, Object, BasicObject]
|
21
|
+
@scc.parents.should == expected_parents
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
@@ -0,0 +1,248 @@
|
|
1
|
+
# this file is frankly a bit of a mess - trying to do too many things
|
2
|
+
# at once
|
3
|
+
|
4
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
5
|
+
|
6
|
+
shared_code = proc do
|
7
|
+
class DateRange < Doodle
|
8
|
+
has :start_date, :kind => Date do
|
9
|
+
from String do |s|
|
10
|
+
Date.parse(s)
|
11
|
+
end
|
12
|
+
from Array do |y,m,d|
|
13
|
+
#p [:from, Array, y, m, d]
|
14
|
+
Date.new(y, m, d)
|
15
|
+
end
|
16
|
+
from Integer do |jd|
|
17
|
+
#Doodle::Debug.d { [:converting_from, Integer, jd] }
|
18
|
+
Date.new(*Date.send(:jd_to_civil, jd))
|
19
|
+
end
|
20
|
+
#Doodle::Debug.d { [:start_date, self, self.class] }
|
21
|
+
default { Date.today }
|
22
|
+
end
|
23
|
+
has :end_date, :kind => Date do
|
24
|
+
from String do |s|
|
25
|
+
Date.parse(s)
|
26
|
+
end
|
27
|
+
from Array do |y,m,d|
|
28
|
+
#p [:from, Array, y, m, d]
|
29
|
+
Date.new(y, m, d)
|
30
|
+
end
|
31
|
+
from Integer do |jd|
|
32
|
+
#Doodle::Debug.d { [:converting_from, Integer, jd] }
|
33
|
+
Date.new(*Date.send(:jd_to_civil, jd))
|
34
|
+
end
|
35
|
+
default { start_date }
|
36
|
+
end
|
37
|
+
must "have end_date >= start_date" do
|
38
|
+
end_date >= start_date
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe :DateRange, ' validation' do
|
44
|
+
temporary_constants :DateRange do
|
45
|
+
|
46
|
+
before :each, &shared_code
|
47
|
+
|
48
|
+
it 'should not raise an exception if end_date >= start_date' do
|
49
|
+
proc { DateRange.new('2007-01-01', '2007-01-02') }.should_not raise_error
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should raise an exception if end_date < start_date' do
|
53
|
+
proc { DateRange.new('2007-11-01', '2007-01-02') }.should raise_error
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
[:DateRange, :DerivedDateRange, :SecondLevelDerivedDateRange].each do |klass|
|
59
|
+
|
60
|
+
describe klass, ' validation' do
|
61
|
+
temporary_constants :DateRange, :DerivedDateRange, :SecondLevelDerivedDateRange do
|
62
|
+
|
63
|
+
before :each, &shared_code
|
64
|
+
before :each do
|
65
|
+
|
66
|
+
class DerivedDateRange < DateRange
|
67
|
+
end
|
68
|
+
|
69
|
+
class SecondLevelDerivedDateRange < DateRange
|
70
|
+
end
|
71
|
+
|
72
|
+
@klass = self.class.const_get(klass)
|
73
|
+
@meth = @klass.method(:new)
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should not raise an exception if end_date > start_date' do
|
78
|
+
proc { @meth.call('2007-01-01', '2007-01-02') }.should_not raise_error
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should not raise an exception if end_date == start_date' do
|
82
|
+
proc { @klass.new('2007-01-02', '2007-01-02') }.should_not raise_error
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should raise an exception if end_date is < start_date' do
|
86
|
+
proc { @klass.new('2007-01-03', '2007-01-02') }.should raise_error(Doodle::ValidationError)
|
87
|
+
end
|
88
|
+
|
89
|
+
# distinguish between objects which have invalid classes and objects which have classes
|
90
|
+
# which can be converted (i.e. in from clause) but which have unconvertible values
|
91
|
+
|
92
|
+
invalid_dates = [Object.new, Object, Hash.new, { :key => 42 }, 1.2, :today]
|
93
|
+
keys = [:start_date, :end_date]
|
94
|
+
|
95
|
+
keys.each do |key|
|
96
|
+
invalid_dates.each do |o|
|
97
|
+
it "should not validate #{o.inspect} for #{key}" do
|
98
|
+
proc { @klass.new(key => o) }.should raise_error(Doodle::ValidationError)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
unconvertible_dates = [
|
104
|
+
'Hello',
|
105
|
+
[],
|
106
|
+
'tomorrow',
|
107
|
+
'today',
|
108
|
+
'yesterday',
|
109
|
+
"-9999999999999991-12-31",
|
110
|
+
"9999999999999990-12-31",
|
111
|
+
9999999999999999999,
|
112
|
+
-9999999999999999999,
|
113
|
+
]
|
114
|
+
keys = [:start_date, :end_date]
|
115
|
+
|
116
|
+
keys.each do |key|
|
117
|
+
unconvertible_dates.each do |o|
|
118
|
+
it "should not convert #{o.inspect} to #{key}" do
|
119
|
+
proc { @klass.new(key => o) }.should raise_error(Doodle::ConversionError)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# could do with more bad_dates...
|
125
|
+
# note, these are splatted so need [] around args
|
126
|
+
bad_date_pairs = [
|
127
|
+
[[2007,1,2],[2007,1,1]],
|
128
|
+
[{ :end_date => '2007-01-01' }],
|
129
|
+
[{ :start_date => '2007-01-01', :end_date => '2006-01-01' }]
|
130
|
+
]
|
131
|
+
|
132
|
+
bad_date_pairs.each do |o|
|
133
|
+
it "should not allow #{o.inspect[1..-2]}" do
|
134
|
+
proc { @klass.new(*o) }.should raise_error(Doodle::ValidationError)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# note, these are splatted so need [] around args
|
139
|
+
good_dates = [
|
140
|
+
[[2007,1,1],[2007,1,2]],
|
141
|
+
[{ :start_date => '2007-01-01' }],
|
142
|
+
[{ :start_date => '2007-01-01', :end_date => '2007-01-01' }],
|
143
|
+
[{ :start_date => -1, :end_date => 0 }]
|
144
|
+
]
|
145
|
+
|
146
|
+
good_dates.each do |o|
|
147
|
+
it "should allow #{o.inspect[1..-2]}" do
|
148
|
+
proc { @klass.new(*o) }.should_not raise_error
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe klass, ' defaults' do
|
155
|
+
temporary_constants :AttributeDate, :Base, :DateRange, :DerivedDateRange, :SecondLevelDerivedDateRange do
|
156
|
+
before :each, &shared_code
|
157
|
+
before :each do
|
158
|
+
class DerivedDateRange < DateRange
|
159
|
+
end
|
160
|
+
|
161
|
+
class SecondLevelDerivedDateRange < DateRange
|
162
|
+
end
|
163
|
+
|
164
|
+
@klass = self.class.const_get(klass)
|
165
|
+
@dr = @klass.new
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'should have default start_date == Date.today' do
|
169
|
+
@dr.start_date == Date.today
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'should have default end_date == start_date' do
|
173
|
+
@dr.end_date.should == @dr.start_date
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe klass, ' setting attributes after initialization' do
|
179
|
+
temporary_constants :AttributeDate, :Base, :DateRange, :DerivedDateRange, :SecondLevelDerivedDateRange do
|
180
|
+
before :each, &shared_code
|
181
|
+
before :each do
|
182
|
+
class DerivedDateRange < DateRange
|
183
|
+
end
|
184
|
+
|
185
|
+
class SecondLevelDerivedDateRange < DateRange
|
186
|
+
end
|
187
|
+
|
188
|
+
@klass = self.class.const_get(klass)
|
189
|
+
@dr = @klass.new
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should not allow end_date < start_date" do
|
193
|
+
proc { @dr.end_date = @dr.start_date - 1 }.should raise_error(Doodle::ValidationError)
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should allow end_date >= start_date" do
|
197
|
+
proc { @dr.end_date = @dr.start_date + 1 }.should_not raise_error
|
198
|
+
end
|
199
|
+
|
200
|
+
it "should allow changing start_date (and have dependent end_date follow)" do
|
201
|
+
proc { @dr.start_date = @dr.start_date + 1 }.should_not raise_error
|
202
|
+
@dr.end_date.should == @dr.start_date
|
203
|
+
end
|
204
|
+
|
205
|
+
it "should not raise an error when changing start_date and changing end_date using defer_validation" do
|
206
|
+
proc {
|
207
|
+
@dr.defer_validation do
|
208
|
+
self.start_date = self.start_date + 1
|
209
|
+
self.end_date = self.start_date
|
210
|
+
end
|
211
|
+
}.should_not raise_error
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should allow changing start_date and changing end_date using defer_validation" do
|
215
|
+
@dr.defer_validation do
|
216
|
+
start_date start_date + 1
|
217
|
+
end_date start_date
|
218
|
+
end
|
219
|
+
@dr.start_date.should >= @dr.end_date
|
220
|
+
end
|
221
|
+
|
222
|
+
it "should not allow changing start_date to be > end_date" do
|
223
|
+
proc {
|
224
|
+
@dr.end_date = @dr.start_date
|
225
|
+
@dr.start_date = @dr.start_date + 1
|
226
|
+
}.should raise_error(Doodle::ValidationError)
|
227
|
+
end
|
228
|
+
|
229
|
+
it "should not allow changing start_date to be > end_date" do
|
230
|
+
proc {
|
231
|
+
@dr.instance_eval {
|
232
|
+
end_date start_date
|
233
|
+
start_date start_date + 1
|
234
|
+
}
|
235
|
+
}.should raise_error(Doodle::ValidationError)
|
236
|
+
end
|
237
|
+
|
238
|
+
it "should not allow changing end_date to be < start_date" do
|
239
|
+
proc {
|
240
|
+
@dr.instance_eval {
|
241
|
+
end_date start_date - 1
|
242
|
+
}
|
243
|
+
}.should raise_error(Doodle::ValidationError)
|
244
|
+
end
|
245
|
+
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
data/spec/validation_spec.rb
CHANGED
@@ -1,52 +1,41 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
2
|
|
3
3
|
describe :DateRange, 'validation & conversions' do
|
4
|
-
temporary_constants :
|
4
|
+
temporary_constants :DateRange do
|
5
5
|
|
6
6
|
before :each do
|
7
|
-
module ClassMethods
|
8
|
-
def date(*a, &b)
|
9
|
-
# if a.size > 0
|
10
|
-
name = a.shift
|
11
|
-
# else
|
12
|
-
# name = :date
|
13
|
-
# end
|
14
|
-
td = has(name, :kind => Date, *a) do
|
15
|
-
# it is a bit clumsy to define these conversions &
|
16
|
-
# conditions for every attribute/typedef - could define a
|
17
|
-
# subclass of Typedef which does this by default (so we
|
18
|
-
# instances can override or defer to class level conversions
|
19
|
-
# and conditions)
|
20
|
-
from String do |s|
|
21
|
-
Date.parse(s)
|
22
|
-
end
|
23
|
-
from Array do |y,m,d|
|
24
|
-
#p [:from, Array, y, m, d]
|
25
|
-
Date.new(y, m, d)
|
26
|
-
end
|
27
|
-
from Integer do |jd|
|
28
|
-
Doodle::Debug.d { [:converting_from, Integer, jd] }
|
29
|
-
Date.new(*Date.jd_to_civil(jd))
|
30
|
-
end
|
31
|
-
end
|
32
|
-
Doodle::Debug.d { [:date, td] }
|
33
|
-
td.instance_eval(&b) if block_given? # user's block should override default
|
34
|
-
end
|
35
|
-
end
|
36
7
|
|
37
|
-
class
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
class DateRange < Base
|
42
|
-
date :start_date do
|
8
|
+
class DateRange < Doodle
|
9
|
+
has :start_date, :kind => Date do
|
43
10
|
Doodle::Debug.d { [:start_date, self, self.class] }
|
11
|
+
from String do |s|
|
12
|
+
Date.parse(s)
|
13
|
+
end
|
14
|
+
from Array do |y,m,d|
|
15
|
+
#p [:from, Array, y, m, d]
|
16
|
+
Date.new(y, m, d)
|
17
|
+
end
|
18
|
+
from Integer do |jd|
|
19
|
+
Doodle::Debug.d { [:converting_from, Integer, jd] }
|
20
|
+
Date.new(*Date.send(:jd_to_civil, jd))
|
21
|
+
end
|
44
22
|
default { Date.today }
|
45
23
|
must "be >= 2007-01-01" do |d|
|
46
24
|
d >= Date.new(2007, 01, 01)
|
47
25
|
end
|
48
26
|
end
|
49
|
-
|
27
|
+
has :end_date, { :kind => Date } do
|
28
|
+
from String do |s|
|
29
|
+
Date.parse(s)
|
30
|
+
end
|
31
|
+
from Array do |y,m,d|
|
32
|
+
#p [:from, Array, y, m, d]
|
33
|
+
Date.new(y, m, d)
|
34
|
+
end
|
35
|
+
from Integer do |jd|
|
36
|
+
Doodle::Debug.d { [:converting_from, Integer, jd] }
|
37
|
+
Date.new(*Date.send(:jd_to_civil, jd))
|
38
|
+
end
|
50
39
|
default { start_date }
|
51
40
|
end
|
52
41
|
must "have end_date >= start_date" do
|