madderlib 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/CHANGELOG +3 -0
  2. data/LICENSE +22 -0
  3. data/README.rdoc +173 -0
  4. data/Rakefile +134 -0
  5. data/lib/madderlib.rb +27 -0
  6. data/lib/madderlib/builder.rb +659 -0
  7. data/lib/madderlib/conditional/allowed.rb +144 -0
  8. data/lib/madderlib/conditional/helper.rb +135 -0
  9. data/lib/madderlib/conditional/likely.rb +162 -0
  10. data/lib/madderlib/conditional/recur.rb +103 -0
  11. data/lib/madderlib/conditional/registry.rb +56 -0
  12. data/lib/madderlib/conditional/repeat.rb +130 -0
  13. data/lib/madderlib/context.rb +140 -0
  14. data/lib/madderlib/core.rb +217 -0
  15. data/lib/madderlib/extensions.rb +40 -0
  16. data/lib/madderlib/instruction.rb +171 -0
  17. data/lib/madderlib/phrase.rb +284 -0
  18. data/lib/madderlib/sequencer.rb +337 -0
  19. data/madderlib.gemspec +72 -0
  20. data/spec/benchmark_spec.rb +69 -0
  21. data/spec/builder_spec.rb +321 -0
  22. data/spec/builder_to_other_spec.rb +47 -0
  23. data/spec/builder_to_sequencer_spec.rb +388 -0
  24. data/spec/conditional_allowed_spec.rb +130 -0
  25. data/spec/conditional_helper_spec.rb +131 -0
  26. data/spec/conditional_likely_spec.rb +138 -0
  27. data/spec/conditional_recur_spec.rb +102 -0
  28. data/spec/conditional_registry_spec.rb +94 -0
  29. data/spec/conditional_repeat_spec.rb +88 -0
  30. data/spec/doc_spec.rb +550 -0
  31. data/spec/error_spec.rb +33 -0
  32. data/spec/examples_spec.rb +151 -0
  33. data/spec/extensions_spec.rb +47 -0
  34. data/spec/grammar_spec.rb +101 -0
  35. data/spec/instruction_spec.rb +133 -0
  36. data/spec/kernel_spec.rb +58 -0
  37. data/spec/phrase_spec.rb +7 -0
  38. data/spec/sequencer_spec.rb +317 -0
  39. data/spec/spec_helper.rb +54 -0
  40. metadata +98 -0
@@ -0,0 +1,58 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+
4
+
5
+ describe MadderLib::KernelMethods do
6
+ after(:each) do
7
+ # complete the current grammar
8
+ # so that the next test isn't so limited
9
+ madderlib_grammar.complete
10
+
11
+
12
+
13
+ it "madderlib requires a block" do
14
+ end
15
+
16
+ it "provides access to a Builder" do
17
+ # empty
18
+ builder = madderlib { }
19
+
20
+ builder.should_not be_nil
21
+ builder.id.should be_nil
22
+ builder.should be_a(MadderLib::Builder)
23
+ builder.phrases.should have(0).phrases
24
+
25
+ # id only
26
+ builder = madderlib(:id) { }
27
+
28
+ builder.should_not be_nil
29
+ builder.id.should equal(:id)
30
+ builder.should be_a(MadderLib::Builder)
31
+ builder.phrases.should have(0).phrases
32
+ end
33
+
34
+ it "provides a new Builder each time" do
35
+ builder = madderlib { }
36
+ madderlib { }.should_not equal(builder)
37
+
38
+
39
+ it "provides access to a Grammar" do
40
+ grammar = madderlib_grammar
41
+
42
+ # empty
43
+ grammar.should_not be_nil
44
+ grammar.should be_a(MadderLib::Grammar)
45
+ grammar.should have(0).builders
46
+ grammar.builder_map.should have(0).builders
47
+ end
48
+
49
+ it "provides the same Grammar, until completed" do
50
+ # same
51
+ grammar = madderlib_grammar
52
+ madderlib_grammar.should equal(grammar)
53
+
54
+ # different
55
+ grammar.complete
56
+ madderlib_grammar.should_not equal(grammar)
57
+ end
58
+ end
@@ -0,0 +1,7 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+
4
+
5
+ describe MadderLib::Phrase do
6
+
7
+ end
@@ -0,0 +1,317 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+
4
+
5
+ describe MadderLib::Sequencer do
6
+
7
+ it "handles a single say" do
8
+ sequencer = (madderlib :single_say do
9
+ say :hello
10
+ end).to_sequencer
11
+
12
+ sequencer.words.should eql(%w{ hello })
13
+ end
14
+
15
+ it "handles multiple says" do
16
+ sequencer = (madderlib :multiple_say do
17
+ # all in sequence
18
+ # multiple words per phrase
19
+ # a few syntactical varieties
20
+ say :cover, :contents
21
+ and_then.say :beginning
22
+ says :middle
23
+ also.says :end
24
+ end).to_sequencer
25
+
26
+ sequencer.words.should eql(%w{
27
+ cover contents beginning middle end
28
+ })
29
+ end
30
+
31
+
32
+
33
+ it "handles flat before sequencing" do
34
+ # one instance, single word
35
+ sequencer = (madderlib :flat_single_before do
36
+ a(:ref).says :ref
37
+ before(:ref).say :before
38
+ end).to_sequencer
39
+
40
+ sequencer.words.should eql(%w{ before ref })
41
+
42
+ # multiple instances, multiple words
43
+ sequencer = (madderlib :flat_multiple_before do
44
+ before(:ref).say :b, :c
45
+ a(:ref).says(:ref)
46
+ before(:ref).say :a
47
+ end).to_sequencer
48
+
49
+ sequencer.words.should eql(%w{ a b c ref })
50
+ end
51
+
52
+ it "handles flat after sequencing" do
53
+ # one instance, single word
54
+ sequencer = (madderlib :flat_single_after do
55
+ a(:ref).says :ref
56
+ after(:ref).say :after
57
+ end).to_sequencer
58
+
59
+ sequencer.words.should eql(%w{ ref after })
60
+
61
+ # multiple instances, multiple words
62
+ sequencer = (madderlib :flat_multiple_after do
63
+ after(:ref).say :x, :y
64
+ a(:ref).says(:ref)
65
+ after(:ref).say :z
66
+ end).to_sequencer
67
+
68
+ sequencer.words.should eql(%w{ ref x y z })
69
+ end
70
+
71
+
72
+
73
+ it "handles nested before sequencing" do
74
+ # one instance, single word
75
+ sequencer = (madderlib :nested_single_before do
76
+ a(:ref).says :ref
77
+ before(:ref, :inner).say :inner
78
+ before(:inner).say :outer
79
+ end).to_sequencer
80
+
81
+ sequencer.words.should eql(%w{ outer inner ref })
82
+
83
+ # multiple instances, multiple words
84
+ sequencer = (madderlib :nested_multiple_before do
85
+ # visually:
86
+ # [ :a [ :b [:c :d ] :e ] :f :ref ]
87
+ before(:ref).say :f
88
+ before(:ref, :inner_e).say :e1, :e2
89
+ before(:inner_e, :outer_d).say :d
90
+ a(:ref).says(:ref)
91
+ before(:outer_d).say :c
92
+ before(:inner_e).say :b1, :b2
93
+ before(:ref).say :a
94
+ end).to_sequencer
95
+
96
+ sequencer.words.should eql(%w{ a b1 b2 c d e1 e2 f ref })
97
+ end
98
+
99
+ it "handles nested after sequencing" do
100
+ # one instance, single word
101
+ sequencer = (madderlib :nested_single_before do
102
+ a(:ref).says :ref
103
+ after(:inner).say :outer
104
+ after(:ref, :inner).say :inner
105
+ end).to_sequencer
106
+
107
+ sequencer.words.should eql(%w{ ref inner outer })
108
+
109
+ # multiple instances, multiple words
110
+ sequencer = (madderlib :nested_multiple_before do
111
+ # visually:
112
+ # [ :ref :u [ :v [ :w :x ] :y ] :z ]
113
+ after(:ref).say :u
114
+ after(:ref, :inner_v).say :v1, :v2
115
+ after(:inner_v, :outer_w).say :w
116
+ a(:ref).says(:ref)
117
+ after(:outer_w).say :x
118
+ after(:inner_v).say :y1, :y2
119
+ after(:ref).say :z
120
+ end).to_sequencer
121
+
122
+ sequencer.words.should eql(%w{ ref u v1 v2 w x y1 y2 z })
123
+ end
124
+
125
+
126
+
127
+ it "handles complex nested sequencing" do
128
+ sequencer = (madderlib :nested_complex do
129
+ # visually:
130
+ # [ :a [ [ :b :c [ :d :e ] ] :f [ :g :h ] :i ] :ref [ :r [ :s :t ] :u [ [ :v :w ] :x :y ] ] :z ]
131
+ # as if that helps
132
+ # yes, it's palindromic around :ref
133
+ before(:c).say :b
134
+ before(:f, :c).say :c
135
+ after(:c, :d).say :d
136
+ after(:d).say :e
137
+ before(:ref, :f).say :f
138
+ before(:h).say :g
139
+ after(:f, :h).say :h
140
+ # dupl after
141
+ after(:f).say :i
142
+ # dupl before
143
+ before(:ref).say :a
144
+
145
+ a(:ref).says(:ref)
146
+
147
+ after(:x).say :y
148
+ after(:u, :x).say :x
149
+ before(:x, :w).say :w
150
+ before(:w).say :v
151
+ after(:ref, :u).say :u
152
+ before(:u, :t).say :t
153
+ before(:t).say :s
154
+ # dupl before
155
+ before(:u).say :r
156
+ # dupl after
157
+ after(:ref).say :z
158
+ end).to_sequencer
159
+
160
+ sequencer.words.should eql(%w{
161
+ a b c d e f g h i
162
+ ref
163
+ r s t u v w x y z
164
+ })
165
+ end
166
+
167
+
168
+
169
+ it "handles anytimes, without anything else" do
170
+ sequencer = (madderlib :empty_anytimes do
171
+ anytime.say :anything
172
+ end).to_sequencer
173
+
174
+ sequencer.words.should eql(%w{ anything })
175
+ end
176
+
177
+ it "handles simple anytimes" do
178
+ # will always occur at the end (no other option)
179
+ sequencer = (madderlib :single_anytimes do
180
+ say :something
181
+ anytime.say :anything
182
+ end).to_sequencer
183
+
184
+ sequencer.words.should eql(%w{ something anything })
185
+
186
+ # only one place to go
187
+ # because it won't start or end the sequence
188
+ builder = madderlib :multiple_anytimes do
189
+ say :one
190
+ say :two
191
+ anytime.say :gotcha
192
+ end
193
+
194
+ pound_on do
195
+ items = builder.words
196
+ items.should eql(%w{ one gotcha two })
197
+ end
198
+ end
199
+
200
+ it "handles after-positional anytimes" do
201
+ # nowhere to go
202
+ # but will NOT end the sequence
203
+ builder = madderlib :blocked_after_anytimes do
204
+ say :one
205
+ a(:lower).says :two
206
+ anytime.after(:lower).say :gotcha
207
+ end
208
+
209
+ pound_on do
210
+ items = builder.words
211
+ items.should eql(%w{ one two })
212
+ end
213
+
214
+ # only one place
215
+ builder = madderlib :simple_after_anytimes do
216
+ say :one
217
+ a(:lower).says :two
218
+ say :three
219
+ anytime.after(:lower).say :gotcha
220
+ end
221
+
222
+ pound_on do
223
+ items = builder.words
224
+ items.should eql(%w{ one two gotcha three })
225
+ end
226
+ end
227
+
228
+ it "handles before-positional anytimes" do
229
+ # nowhere to go
230
+ # because it will NOT start the sequence
231
+ builder = madderlib :blocked_before_anytimes do
232
+ an(:upper).says :one
233
+ say :two
234
+ anytime.before(:upper).say :gotcha
235
+ end
236
+
237
+ pound_on do
238
+ items = builder.words
239
+ items.should eql(%w{ one two })
240
+ end
241
+
242
+ # only one place
243
+ builder = madderlib :simple_before_anytimes do
244
+ say :one
245
+ an(:upper).says :two
246
+ say :three
247
+ anytime.before(:upper).say :gotcha
248
+ end
249
+
250
+ pound_on do
251
+ items = builder.words
252
+ items.should eql(%w{ one gotcha two three })
253
+ end
254
+ end
255
+
256
+ it "doesn't tolerate invalid bounding conditions" do
257
+ (lambda do
258
+ (builder = madderlib :between_exception_anytimes do
259
+ # before > after ... never works
260
+ # assume that before and after aren't first or last, respectively
261
+ # those are tolerated no-op conditions
262
+ say :one
263
+ a(:first).says :two
264
+ a(:second).says :three
265
+ say :four
266
+ anytime.between(:second, :first).say :never
267
+ end).to_sequencer.words
268
+ end).should raise_error MadderLib::Error
269
+ end
270
+
271
+ it "handles bounded anytimes" do
272
+ # nowhere to go
273
+ # this IS a valid (though stupid) bounding condition
274
+ builder = madderlib :bounded_nowhere_anytimes do
275
+ a(:phrase).says :one
276
+ anytime.after(:phrase).before(:phrase).say :never
277
+ end
278
+
279
+ pound_on do
280
+ items = builder.words
281
+ items.should eql(%w{ one })
282
+ end
283
+
284
+ # one place only
285
+ builder = madderlib :bounded_anytimes do
286
+ say :one
287
+ a(:lower).says :two
288
+ an(:upper).says :three
289
+ say :four
290
+ anytime.between(:lower, :upper).say :gotcha
291
+ end
292
+
293
+ pound_on do
294
+ items = builder.words
295
+ items.should eql(%w{ one two gotcha three four })
296
+ end
297
+
298
+ # a small range
299
+ builder = madderlib :between_anytimes do
300
+ a(:lower).says :one
301
+ say :two
302
+ an(:upper).says :three
303
+ anytime.after(:lower).before(:upper).say :gotcha
304
+ end
305
+
306
+ pound_on do
307
+ items = builder.words
308
+
309
+ items.shift.should eql('one')
310
+ items.pop.should eql('three')
311
+
312
+ items.index('gotcha').should_not be_nil
313
+ items.delete 'gotcha'
314
+ items.should eql(%w{ two })
315
+ end
316
+ end
317
+ end
@@ -0,0 +1,54 @@
1
+ # external
2
+ %w{ rubygems spec }.each {|lib| require lib }
3
+
4
+ # optional
5
+ require 'ruby-debug' rescue nil
6
+
7
+ # our dependencies
8
+ # loaded after debug is ready
9
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'madderlib')
10
+
11
+
12
+
13
+ module Spec::DSL::Main
14
+ def pound_on(count=100)
15
+ # that'll be enough
16
+ count.times { yield }
17
+ end
18
+ end
19
+
20
+
21
+
22
+ module MadderLib
23
+ class Builder
24
+ # normally private
25
+ # oops! reserved names!
26
+ ###attr_reader :ordered, :depends
27
+ def orderings; @ordered; end
28
+ def dependencies; @depends; end
29
+ end
30
+
31
+ class Sequencer
32
+ # normally private
33
+ attr_reader :steps
34
+
35
+ # oops! reserved names!
36
+ ###attr_reader :anytime, :before, :after
37
+ def anytimes; @anytime; end
38
+ def befores; @before; end
39
+ def afters; @after; end
40
+
41
+ send :public, :sequence
42
+ send :public, :traverse
43
+ end
44
+
45
+ class Instruction
46
+ class << self
47
+ send :public, :wordify
48
+ end
49
+ end
50
+
51
+ class AnytimePhrase
52
+ attr_reader :repeat_logic
53
+ end
54
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: madderlib
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Dan Foley
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-14 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: "MadderLib : a Sentence-Building DSL for the easily amused"
17
+ email: admin@cantremember.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ - CHANGELOG
25
+ - LICENSE
26
+ files:
27
+ - CHANGELOG
28
+ - LICENSE
29
+ - README.rdoc
30
+ - Rakefile
31
+ - lib/madderlib.rb
32
+ - lib/madderlib/builder.rb
33
+ - lib/madderlib/conditional/allowed.rb
34
+ - lib/madderlib/conditional/helper.rb
35
+ - lib/madderlib/conditional/likely.rb
36
+ - lib/madderlib/conditional/recur.rb
37
+ - lib/madderlib/conditional/registry.rb
38
+ - lib/madderlib/conditional/repeat.rb
39
+ - lib/madderlib/context.rb
40
+ - lib/madderlib/core.rb
41
+ - lib/madderlib/extensions.rb
42
+ - lib/madderlib/instruction.rb
43
+ - lib/madderlib/phrase.rb
44
+ - lib/madderlib/sequencer.rb
45
+ - madderlib.gemspec
46
+ - spec/benchmark_spec.rb
47
+ - spec/builder_spec.rb
48
+ - spec/builder_to_other_spec.rb
49
+ - spec/builder_to_sequencer_spec.rb
50
+ - spec/conditional_allowed_spec.rb
51
+ - spec/conditional_helper_spec.rb
52
+ - spec/conditional_likely_spec.rb
53
+ - spec/conditional_recur_spec.rb
54
+ - spec/conditional_registry_spec.rb
55
+ - spec/conditional_repeat_spec.rb
56
+ - spec/doc_spec.rb
57
+ - spec/error_spec.rb
58
+ - spec/examples_spec.rb
59
+ - spec/extensions_spec.rb
60
+ - spec/grammar_spec.rb
61
+ - spec/instruction_spec.rb
62
+ - spec/kernel_spec.rb
63
+ - spec/phrase_spec.rb
64
+ - spec/sequencer_spec.rb
65
+ - spec/spec_helper.rb
66
+ has_rdoc: true
67
+ homepage: http://wiki.cantremember.com/MadderLib
68
+ post_install_message:
69
+ rdoc_options:
70
+ - --line-numbers
71
+ - --inline-source
72
+ - --title
73
+ - MadderLib
74
+ - --main
75
+ - README.rdoc
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: "1.8"
83
+ version:
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: "0"
89
+ version:
90
+ requirements: []
91
+
92
+ rubyforge_project: madderlib
93
+ rubygems_version: 1.3.1
94
+ signing_key:
95
+ specification_version: 2
96
+ summary: madderlib 0.1.0
97
+ test_files: []
98
+