madderlib 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 (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
+