doodle 0.0.10 → 0.1.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.
Files changed (67) hide show
  1. data/CREDITS +22 -0
  2. data/{ChangeLog → History.txt} +22 -3
  3. data/License.txt +20 -0
  4. data/Manifest.txt +61 -0
  5. data/README.txt +166 -0
  6. data/Rakefile +4 -0
  7. data/config/hoe.rb +77 -0
  8. data/config/requirements.rb +15 -0
  9. data/examples/doodle-errors.rb +25 -0
  10. data/examples/event-location.rb +3 -7
  11. data/examples/example-01.rb +1 -1
  12. data/examples/example-01.rdoc +3 -3
  13. data/examples/example-02.rb +15 -4
  14. data/examples/example-02.rdoc +17 -5
  15. data/examples/mail-datatypes.rb +104 -0
  16. data/examples/mail.rb +85 -0
  17. data/examples/parent.rb +40 -0
  18. data/examples/profile-options.rb +67 -0
  19. data/examples/smtp_tls.rb +65 -0
  20. data/examples/test-datatypes.rb +55 -0
  21. data/examples/yaml-example.rb +40 -0
  22. data/examples/yaml-example2.rb +42 -0
  23. data/lib/doodle.rb +364 -301
  24. data/lib/doodle/datatypes.rb +148 -0
  25. data/lib/doodle/rfc822.rb +31 -0
  26. data/lib/doodle/utils.rb +13 -0
  27. data/lib/doodle/version.rb +9 -0
  28. data/log/debug.log +0 -0
  29. data/script/console +10 -0
  30. data/script/destroy +14 -0
  31. data/script/generate +14 -0
  32. data/script/txt2html +82 -0
  33. data/setup.rb +1585 -0
  34. data/spec/arg_order_spec.rb +5 -5
  35. data/spec/attributes_spec.rb +66 -24
  36. data/spec/bugs_spec.rb +109 -6
  37. data/spec/class_spec.rb +7 -4
  38. data/spec/class_validation_spec.rb +46 -0
  39. data/spec/class_var_spec.rb +76 -0
  40. data/spec/collector_spec.rb +16 -30
  41. data/spec/conversion_spec.rb +8 -3
  42. data/spec/defaults_spec.rb +4 -4
  43. data/spec/doodle_context_spec.rb +3 -4
  44. data/spec/doodle_spec.rb +25 -15
  45. data/spec/extra_args_spec.rb +1 -1
  46. data/spec/factory_spec.rb +3 -3
  47. data/spec/init_spec.rb +11 -11
  48. data/spec/new_doodle_spec.rb +19 -0
  49. data/spec/required_spec.rb +1 -1
  50. data/spec/serialization_spec.rb +3 -6
  51. data/spec/singleton_spec.rb +5 -5
  52. data/spec/spec.opts +1 -0
  53. data/spec/spec_helper.rb +44 -0
  54. data/spec/superclass_spec.rb +6 -5
  55. data/spec/validation2_spec.rb +248 -0
  56. data/spec/validation_spec.rb +26 -37
  57. data/tasks/deployment.rake +34 -0
  58. data/tasks/environment.rake +7 -0
  59. data/tasks/rspec.rake +21 -0
  60. data/tasks/website.rake +17 -0
  61. metadata +76 -20
  62. data/COPYING +0 -18
  63. data/README +0 -57
  64. data/examples/event.rb +0 -39
  65. data/examples/example-03.rb +0 -45
  66. data/examples/example-03.rdoc +0 -55
  67. data/lib/semantic.cache +0 -8
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/spec_helper.rb'
3
3
  describe Doodle, 'defaults which have not been set' do
4
4
  temporary_constant :Foo do
5
5
  before :each do
6
- class Foo < Doodle::Base
6
+ class Foo < Doodle
7
7
  has :baz
8
8
  has :start, :default => 1
9
9
  end
@@ -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::Base
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
- if RUBY_PLATFORM == 'java'
19
- @foo.to_yaml.should == "--- !ruby/object:Foo\nvar: 42\n"
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
@@ -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::Base
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::Helper
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::Base
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 == OrderedHash.new
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::Helper
48
+ include Doodle::Core
49
49
  end
50
50
  foo = Foo.new
51
51
  class << foo
@@ -0,0 +1 @@
1
+ --colour
@@ -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
@@ -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::Base
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::Base; self; end
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 class parents == class, doodle root' do
16
- @sc.parents.should == [@sclass_foo, @sclass_doodle_root]
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
- @scc.parents.should == []
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
@@ -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 :Base, :DateRange, :ClassMethods do
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 Base < Doodle::Base
38
- extend ClassMethods
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
- date :end_date do
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