doodle 0.0.10 → 0.1.0

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