qed 2.6.0 → 2.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. data/.ruby +34 -33
  2. data/.yardopts +6 -0
  3. data/HISTORY.rdoc +14 -0
  4. data/QED.rdoc +454 -0
  5. data/lib/qed.yml +34 -33
  6. data/lib/qed/session.rb +12 -7
  7. metadata +6 -4
data/.ruby CHANGED
@@ -1,47 +1,48 @@
1
1
  ---
2
- spec_version: 1.0.0
3
- replaces: []
4
-
5
- loadpath:
6
- - lib
7
2
  name: qed
8
- repositories:
9
- public: git://github.com/proutils/qed.git
10
- conflicts: []
11
-
12
- engine_check: []
13
-
3
+ version: 2.6.1
14
4
  title: QED
15
- resources:
16
- home: http://proutils.github.com/qed
17
- work: http://github.com/proutils/qed
18
- maintainers: []
19
-
5
+ summary: Quod Erat Demonstrandum
6
+ description: QED (Quality Ensured Demonstrations) is a TDD/BDD framework utilizing Literate Programming techniques.
7
+ loadpath:
8
+ - lib
9
+ manifest: MANIFEST
20
10
  requires:
21
- - group: []
22
-
23
- name: ansi
11
+ - name: ansi
24
12
  version: 0+
25
- - group: []
13
+ group: []
26
14
 
27
- name: facets
15
+ - name: facets
28
16
  version: 2.8+
29
- - group: []
17
+ group: []
30
18
 
31
- name: ae
19
+ - name: ae
20
+ version: 1.7+
21
+ group: []
22
+
23
+ - name: detroit
32
24
  version: 0+
33
- - group:
25
+ group:
34
26
  - build
35
- name: syckle
36
- version: 0+
37
- manifest: Manifest
38
- version: 2.5.1
39
- licenses: []
27
+ conflicts: []
28
+
29
+ replaces: []
30
+
31
+ engine_check: []
40
32
 
33
+ organization: RubyWorks
34
+ contact: trans <transfire@gmail.com>
35
+ created: 2006-12-16
41
36
  copyright: Copyright (c) 2006 Thomas Sawyer
37
+ licenses: []
38
+
42
39
  authors:
43
40
  - Thomas Sawyer <transfire@gmail.com>
44
- organization: RubyWorks
45
- description: QED (Quality Ensured Demonstrations) is a TDD/BDD framework utilizing Literate Programming techniques.
46
- summary: Quod Erat Demonstrandum
47
- created: 2006-12-16
41
+ maintainers: []
42
+
43
+ resources:
44
+ home: http://rubyworks.github.com/qed
45
+ work: http://github.com/rubyworks/qed
46
+ repositories:
47
+ public: git://github.com/rubyworks/qed.git
48
+ spec_version: 1.0.0
data/.yardopts ADDED
@@ -0,0 +1,6 @@
1
+ --output-dir doc
2
+ --readme README.rdoc
3
+ --title "Q.E.D."
4
+ lib
5
+ -
6
+ [A-Z]*.*
data/HISTORY.rdoc CHANGED
@@ -1,5 +1,19 @@
1
1
  = RELEASE HISTORY
2
2
 
3
+ == 2.6.1 / 2011-07-02
4
+
5
+ A friend insisted QED default the loadpath tolib and
6
+ automatically look for QED demos in default locations
7
+ (sepc, demo, qed) if not files are passed to it on the
8
+ command line. So it is.
9
+
10
+ Changes:
11
+
12
+ * Default loadpath option to lib/.
13
+ * Default files to markup files in spec/, demo/ and qed/.
14
+ * Fix website links (you might acutally find things now).
15
+
16
+
3
17
  == 2.6.0 / 2011-07-01
4
18
 
5
19
  Thie release fixes some issues with reporters, further refines
data/QED.rdoc ADDED
@@ -0,0 +1,454 @@
1
+ = Demonstrations
2
+
3
+ == Steps
4
+
5
+ QED demos are light-weight specification documents, highly suitable
6
+ to interface-driven design. The documents are divided up into
7
+ steps separated by blank lines. Steps that are flush to the
8
+ left margin are always explanatory comments. Indented steps are
9
+ either executable code or plain text samples.
10
+
11
+ Each step is executed in order of appearance within a rescue wrapper
12
+ that captures any failures or errors. If neither a failure or error
13
+ occur then the step gets a "pass".
14
+
15
+ For example, the following passes.
16
+
17
+ (2 + 2).assert == 4
18
+
19
+ While the following would "fail", as indicated by the raising of
20
+ an Assertion error.
21
+
22
+ expect Assertion do
23
+ (2 + 2).assert == 5
24
+ end
25
+
26
+ And this would have raised a NameError.
27
+
28
+ expect NameError do
29
+ nobody_knows_method
30
+ end
31
+
32
+ == Defining Custom Assertions
33
+
34
+ The context in which the QED code is run is a self-extended module, thus
35
+ reusable macros can be created simply by defining a method.
36
+
37
+ def assert_integer(x)
38
+ x.assert.is_a? Integer
39
+ end
40
+
41
+ Now lets try out our new macro definition.
42
+
43
+ assert_integer(4)
44
+
45
+ Let's prove that it can also fail.
46
+
47
+ expect Assertion do
48
+ assert_integer("IV")
49
+ end
50
+
51
+
52
+ = Advice
53
+
54
+ Advice are event-based procedures that augment demonstrations.
55
+ They are used to keep demonstrations clean of extraneous,
56
+ repetitive and merely adminstrative code that the reader does
57
+ not need to see over and over.
58
+
59
+ Typically you will want to put advice definitions is applique
60
+ files, rather then place them directly in the demonstration
61
+ document, but you can do so, as you will see in this document.
62
+
63
+ == Before and After
64
+
65
+ QED supports *before* and *after* clauses in a specification
66
+ through the use of Before and After code blocks. These blocks
67
+ are executed at the beginning and at the end of each indicated
68
+ step.
69
+
70
+ We use a *before* clause if we want to setup some code at the
71
+ start of each code step.
72
+
73
+ a, z = nil, nil
74
+
75
+ Before do
76
+ a = "BEFORE"
77
+ end
78
+
79
+ And an *after* clause to teardown objects after a code step.
80
+
81
+ After do
82
+ z = "AFTER"
83
+ end
84
+
85
+ Notice we assigned +a+ and +z+ before the block. This was to ensure
86
+ their visibility in the scope later. Now, lets verify that the *before*
87
+ and *after* clauses work.
88
+
89
+ a.assert == "BEFORE"
90
+
91
+ a = "A"
92
+ z = "Z"
93
+
94
+ And now.
95
+
96
+ z.assert == "AFTER"
97
+
98
+ There can be more than one before and after clause at a time. If we
99
+ define a new *before* or *after* clause later in the document,
100
+ it will be appended to the current list of clauses in use.
101
+
102
+ As a demonstration of this,
103
+
104
+ b = nil
105
+
106
+ Before do
107
+ b = "BEFORE AGAIN"
108
+ end
109
+
110
+ We will see it is the case.
111
+
112
+ b.assert == "BEFORE AGAIN"
113
+
114
+ Only use *before* and *after* clauses when necessary --specifications
115
+ are generally more readable without them. Indeed, some developers
116
+ make a policy of avoiding them altogether. YMMV.
117
+
118
+ == Caveats of Before and After
119
+
120
+ Instead of using Before and After clauses, it is wiser to
121
+ define a reusable setup method. For example, in the helper
122
+ if we define a method such as #prepare_example.
123
+
124
+ def prepare_example
125
+ "Hello, World!"
126
+ end
127
+
128
+ Then we can reuse it in later code blocks.
129
+
130
+ example = prepare_example
131
+ example.assert == "Hello, World!"
132
+
133
+ The advantage to this is that it gives the reader an indication
134
+ of what is going on behind the scenes, rather the having
135
+ an object just magically appear.
136
+
137
+ == Event Targets
138
+
139
+ There is a small set of advice targets that do not come before or after,
140
+ rather they occur *upon* a particular event. These include +:load+
141
+ and +:unload+ for when a new helper is loaded; +:pass+, +:fail+ and +:error+
142
+ for when a code block passes, fails or raises an error; and +:head+, +:desc:+,
143
+ +:code+ and +:data:+ which targets the immediate processing of a text block
144
+ and code excecution.
145
+
146
+ These event targets can be advised by calling the +When+ method
147
+ with the target type as an argument along with the code block
148
+ to be run when the event is triggered.
149
+
150
+ x = []
151
+
152
+ When(:text) do |section|
153
+ section.text.scan(/^\*(.*?)$/) do |m|
154
+ x << $1.strip
155
+ end
156
+ end
157
+
158
+ Not let see if it worked.
159
+
160
+ * SampleA
161
+ * SampleB
162
+ * SampleC
163
+
164
+ So +x+ should now contain these three list samples.
165
+
166
+ x.assert == [ 'SampleA', 'SampleB', 'SampleC' ]
167
+
168
+ == Pattern Matchers
169
+
170
+ QED also supports comment match triggers. With the +When+ method one can
171
+ define procedures to run when a given pattern matches comment text.
172
+
173
+ When 'given a setting @a equal to (((\d+)))' do |n|
174
+ @a = n.to_i
175
+ end
176
+
177
+ Now, @a will be set to 1 whenever a comment like this one contains,
178
+ "given a setting @a equal to 1".
179
+
180
+ @a.assert == 1
181
+
182
+ A string pattern is translated into a regular expression. In fact, you can
183
+ use a regular expression if you need more control over the match. When
184
+ using a string all spaces are converted to <tt>\s+</tt> and anything within
185
+ double-parenthesis is treated as raw regular expression. Since the above
186
+ example has (((\d+))), the actual regular expression contains <tt>(\d+)</tt>,
187
+ so any number can be used. For example, "given a setting @a equal to 2".
188
+
189
+ @a.assert == 2
190
+
191
+ When clauses can also use consecutive pattern matching. For instance
192
+ we could write,
193
+
194
+ When 'first match #(((\d+)))', 'then match #(((\d+)))' do |i1, i2|
195
+ @a = [i1.to_i, i2.to_i]
196
+ end
197
+
198
+ So that 'first match #1' will be looked for first, and only after
199
+ that if 'then match #2' is found, will it be condiered a complete match.
200
+ All regular expression slots are collected from all matches and passed to
201
+ the block. We can see that the rule matched this very paragraph.
202
+
203
+ @a.assert == [1,2]
204
+
205
+ This concludes the basic overview of QED's specification system, which
206
+ is itself a QED document. Yes, we eat our own dog food.
207
+
208
+
209
+ = Helpers
210
+
211
+ There are two ways to load advice scripts. Either per
212
+ demonstration or globally. Per demonstration helpers
213
+ apply only to the current demonstration. Global helpers
214
+ apply to all demonstrations.
215
+
216
+ == Global Helpers
217
+
218
+ Global helpers are loaded at the start of a session and
219
+ apply equally to all demonstrations in a suite. Global
220
+ helpers are simply Ruby scripts and are placed in an
221
+ +environment+ subdirectory. For instance this document
222
+ is used <a href="environment/env.rb">environment/env.rb</a>.
223
+
224
+ == Local Helpers
225
+
226
+ Helper scripts can be written just like demonstration scripts,
227
+ or they can be defined as pure Ruby scripts. Either way
228
+ they are loaded per-demonstration by using specially
229
+ marked links.
230
+
231
+ For example, because this link, Advice[qed://helpers/advice.rb],
232
+ begins with +qed:+, it will be used to load a global
233
+ helper. We can see this with the following assertion.
234
+
235
+ pudding.assert.include?('load advice.rb')
236
+
237
+ No where in the demonstration have we defined +pudding+, but
238
+ it has been defined for us in the advice.rb helper script.
239
+
240
+ We can also see that the generic When clause in our advice
241
+ helper is keeping count of decriptive paragraphs. Since the
242
+ helper script was loaded two paragraphs back, the next count
243
+ will be 3.
244
+
245
+ count.assert == 3
246
+
247
+ Helpers are vital to building test-demonstration suites for
248
+ applications. But here again, only use them as necessary.
249
+ The more helpers you use the more difficult your demos will
250
+ be to follow.
251
+
252
+
253
+ = Test Samples
254
+
255
+ == Flat-file Data
256
+
257
+ When creating testable demonstrations, there are times when sizable
258
+ chunks of data are needed. It is convenient to store such data in
259
+ separate files. The +Data+ method makes is easy to utilize them.
260
+
261
+ Data('qed/samples/data.txt').assert =~ /dolor/
262
+
263
+ The +Data+ method can also take a block which passes the data
264
+ as the block's only argument.
265
+
266
+ Data('qed/samples/data.txt') do |data|
267
+ data.assert =~ /dolor/
268
+ end
269
+
270
+ Files are looked-up relative to the location of the current document.
271
+ If not found then they will be looked-up relative to the current
272
+ working directory.
273
+
274
+ == Tabular Data
275
+
276
+ The +Table+ method is similar to the +Data+ method except that it
277
+ expects a YAML file, and it can take a block to iterate the data over.
278
+ This makes it easy to test tables of examples.
279
+
280
+ The arity of the table block corresponds to the number of columns in
281
+ each row of the table. Each row is assigned in turn and run through
282
+ the coded step. Consider the following example.
283
+
284
+ Every row in the {table.yml table}[table.yml] will be assigned to
285
+ the block parameters and run through the subsequent assertion.
286
+
287
+ Table 'qed/samples/table.yml' do |x, y|
288
+ x.upcase.assert == y
289
+ end
290
+
291
+ Without the block, the +Table+ methods simply returns the sample data.
292
+
293
+ == Considerations
294
+
295
+ Both Data and Table are some what "old fashion" approches to sample
296
+ data. New techinques using plain text blocks are more convenient
297
+ in that the data can be stored directly in the demonstration itself.
298
+ However, for especially large data sets and external file is still
299
+ the better option, and +Data+ and +Table+ make them quite easy to
300
+ access.
301
+
302
+
303
+ = Quotes
304
+
305
+ We do not always want verbatim clauses to be interpreted as code.
306
+ Sometimes it would more useful to treat them a plain text to
307
+ which the preceeding paragraph can make use in a processing rule.
308
+
309
+ For example let say we want to make an example out of the following
310
+ text...
311
+
312
+ The file will contain
313
+
314
+ this text
315
+
316
+ The use of the ellipsis ('...') tells the processor that the next
317
+ segment is a plain text continuation of the current segment, rather
318
+ than example code. If the next segment is varbatim it will be added to
319
+ the end of the arguments list of any applicable processing rule.
320
+
321
+ Behind the scenes we created a rule to set the text to an instance
322
+ variable called @quote_text, and we can verify it is so.
323
+
324
+ @quote_text.assert == "The file will contain\n\nthis text"
325
+
326
+ Alternately we can use a colon (':') instead of ellipsis. We can repeat
327
+ the same statment as above.
328
+
329
+ For example let say we want to make an example out of the following
330
+ text:
331
+
332
+ The file will contain
333
+
334
+ different text
335
+
336
+ And again we can verify that it did in fact set the @quote_text variable.
337
+
338
+ @quote_text.assert == "The file will contain\n\ndifferent text"
339
+
340
+
341
+ = Toplevel Simulation
342
+
343
+ QED simulates Ruby's TOPLEVEL environment in both the Demonstrandum
344
+ and the Applique contexts. This serves two important purposes.
345
+ First, it provides the tester the environment that is most intutive.
346
+ And second, and more importantly, it stays out of the actual
347
+ TOPLEVEL space to prevent any potential interferece with any of
348
+ the code it is intended to test.
349
+
350
+ Let's look at some examples. For starters, we have access to a class
351
+ defined at the "toplevel" in the applique.
352
+
353
+ ToplevelClass
354
+
355
+ We can also call a method defined in the toplevel.
356
+
357
+ toplevel_method.assert == true
358
+
359
+ At the demonstrandum level we can define reusable methods.
360
+
361
+ def demo_method
362
+ true
363
+ end
364
+
365
+ demo_method.assert == true
366
+
367
+ And at the demonstrandum level even singleton methods are accessible.
368
+
369
+ def self.singleton_method; true; end
370
+
371
+ singleton_method.assert == true
372
+
373
+ QED uses a self-extend modules to achieve this simulation, so the
374
+ contexts are in fact a bit more capable then even Ruby's TOPLEVEL.
375
+ For instance, #define_method can be used.
376
+
377
+ define_method(:named_method){ true }
378
+
379
+ named_method.assert == true
380
+
381
+
382
+ = Cross-Scripting Setup
383
+
384
+ We define some variables here to make sure it is
385
+ not visible in the next script.
386
+
387
+ Let's set two local variables.
388
+
389
+ a = 100
390
+ b = 200
391
+
392
+ And two instance varaibles.
393
+
394
+ @a = 1000
395
+ @b = 2000
396
+
397
+ Also let check how it effect constants.
398
+
399
+ CROSS_SCRIPT_CONSTANT = "cross?"
400
+
401
+ And a method.
402
+
403
+ def cross_script_method
404
+ "common"
405
+ end
406
+
407
+
408
+ = Cross-Scripting Check
409
+
410
+ Make sure local and instance variables from previous
411
+ QED scripts are not visible in this document.
412
+
413
+ expect NameError do
414
+ a.assert = 100
415
+ b.assert = 200
416
+ end
417
+
418
+ And two instance_varaibles
419
+
420
+ @a.assert! == 1000
421
+ @b.assert! == 2000
422
+
423
+
424
+ Method definitions also do not cross QED scripts.
425
+
426
+ expect NameError do
427
+ cross_script_method
428
+ end
429
+
430
+ Since each demo is encapsulated in a separated class scope, constants also
431
+ do not make their way across.
432
+
433
+ expect NameError do
434
+ CROSS_SCRIPT_CONSTANT
435
+ end
436
+
437
+
438
+ = Missing Constant
439
+
440
+ If a constant is missing it is because it was not found
441
+ in either the demos scope, the applique or the toplevel.
442
+
443
+ begin
444
+ UnknownConstant
445
+ rescue => err
446
+ # no colon means toplevel
447
+ /[^:]UnknownConstant/ =~ err.message
448
+ end
449
+
450
+ A constant defined in the applique is visible.
451
+
452
+ APPLIQUE_CONSTANT.assert = true
453
+
454
+
data/lib/qed.yml CHANGED
@@ -1,47 +1,48 @@
1
1
  ---
2
- spec_version: 1.0.0
3
- replaces: []
4
-
5
- loadpath:
6
- - lib
7
2
  name: qed
8
- repositories:
9
- public: git://github.com/proutils/qed.git
10
- conflicts: []
11
-
12
- engine_check: []
13
-
3
+ version: 2.6.1
14
4
  title: QED
15
- resources:
16
- home: http://proutils.github.com/qed
17
- work: http://github.com/proutils/qed
18
- maintainers: []
19
-
5
+ summary: Quod Erat Demonstrandum
6
+ description: QED (Quality Ensured Demonstrations) is a TDD/BDD framework utilizing Literate Programming techniques.
7
+ loadpath:
8
+ - lib
9
+ manifest: MANIFEST
20
10
  requires:
21
- - group: []
22
-
23
- name: ansi
11
+ - name: ansi
24
12
  version: 0+
25
- - group: []
13
+ group: []
26
14
 
27
- name: facets
15
+ - name: facets
28
16
  version: 2.8+
29
- - group: []
17
+ group: []
30
18
 
31
- name: ae
19
+ - name: ae
20
+ version: 1.7+
21
+ group: []
22
+
23
+ - name: detroit
32
24
  version: 0+
33
- - group:
25
+ group:
34
26
  - build
35
- name: syckle
36
- version: 0+
37
- manifest: Manifest
38
- version: 2.5.1
39
- licenses: []
27
+ conflicts: []
28
+
29
+ replaces: []
30
+
31
+ engine_check: []
40
32
 
33
+ organization: RubyWorks
34
+ contact: trans <transfire@gmail.com>
35
+ created: 2006-12-16
41
36
  copyright: Copyright (c) 2006 Thomas Sawyer
37
+ licenses: []
38
+
42
39
  authors:
43
40
  - Thomas Sawyer <transfire@gmail.com>
44
- organization: RubyWorks
45
- description: QED (Quality Ensured Demonstrations) is a TDD/BDD framework utilizing Literate Programming techniques.
46
- summary: Quod Erat Demonstrandum
47
- created: 2006-12-16
41
+ maintainers: []
42
+
43
+ resources:
44
+ home: http://rubyworks.github.com/qed
45
+ work: http://github.com/rubyworks/qed
46
+ repositories:
47
+ public: git://github.com/rubyworks/qed.git
48
+ spec_version: 1.0.0
data/lib/qed/session.rb CHANGED
@@ -9,6 +9,10 @@ module QED
9
9
  #
10
10
  class Session
11
11
 
12
+ # If files are not specifies than these directories
13
+ # will be searched.
14
+ DEFAULT_FILES = ['spec', 'demo', 'qed']
15
+
12
16
  # Default recognized demos file types.
13
17
  DEMO_TYPES = %w{qed rdoc md markdown}
14
18
 
@@ -52,13 +56,14 @@ module QED
52
56
  def initialize(files, options={})
53
57
  require_reporters
54
58
 
55
- @files = [files].flatten
59
+ @files = [files].flatten
60
+ @files = DEFAULT_FILES if @files.empty?
56
61
 
57
62
  @format = options[:format] || :dotprogress
58
63
  @trace = options[:trace] || false
59
64
  @mode = options[:mode] || nil
60
65
  @profile = options[:profile] || :default
61
- @loadpath = options[:loadpath] || []
66
+ @loadpath = options[:loadpath] || ['lib']
62
67
  @requires = options[:requires] || []
63
68
 
64
69
  @omit = OMIT_PATHS # TODO: eventually make configurable
@@ -93,7 +98,7 @@ module QED
93
98
 
94
99
  # Returns an Array of Demo instances.
95
100
  #--
96
- # TODO: Pass settings to demo, so we can get temporary_dirctory.
101
+ # TODO: Pass settings to demo, so we can get temporary_directory.
97
102
  #++
98
103
  def demos
99
104
  @demos ||= demo_files.map{ |file| Demo.new(file, :mode=>mode, :at=>directory) }
@@ -224,10 +229,10 @@ module QED
224
229
 
225
230
  files, options = cli_parse(argv)
226
231
 
227
- if files.empty?
228
- puts "No files."
229
- exit -1
230
- end
232
+ #if files.empty?
233
+ # puts "No files."
234
+ # exit -1
235
+ #end
231
236
 
232
237
  session = new(files, options)
233
238
  session.run
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: qed
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 2.6.0
5
+ version: 2.6.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Thomas Sawyer <transfire@gmail.com>
@@ -42,11 +42,11 @@ dependencies:
42
42
  requirements:
43
43
  - - ">="
44
44
  - !ruby/object:Gem::Version
45
- version: "0"
45
+ version: "1.7"
46
46
  type: :runtime
47
47
  version_requirements: *id003
48
48
  - !ruby/object:Gem::Dependency
49
- name: syckle
49
+ name: detroit
50
50
  prerelease: false
51
51
  requirement: &id004 !ruby/object:Gem::Requirement
52
52
  none: false
@@ -67,6 +67,7 @@ extra_rdoc_files:
67
67
  - README.rdoc
68
68
  files:
69
69
  - .ruby
70
+ - .yardopts
70
71
  - bin/qed
71
72
  - bin/qedoc
72
73
  - lib/qed/advice.rb
@@ -118,8 +119,9 @@ files:
118
119
  - test/integration/topcode.rdoc
119
120
  - HISTORY.rdoc
120
121
  - README.rdoc
122
+ - QED.rdoc
121
123
  - LICENSE.rdoc
122
- homepage: http://proutils.github.com/qed
124
+ homepage: http://rubyworks.github.com/qed
123
125
  licenses: []
124
126
 
125
127
  post_install_message: