qed 1.2 → 1.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -44,11 +44,11 @@ In this example, because 4 != 5, this expression will raise an Assertion
44
44
  exception. QED's Runner class is thus just a means of running and capturing
45
45
  code block containing these assertions.
46
46
 
47
- You can learn more about AE at http://proutils.rubyforge/ae.
47
+ You can learn more about AE at http://proutils.github.com/ae.
48
48
 
49
49
  === Document Structure
50
50
 
51
- QED documents are simply text files --thus a practice of literal programming.
51
+ QED documents are simply text files --thus a practice of literate programming.
52
52
  For example:
53
53
 
54
54
  = Example
data/Syckfile ADDED
@@ -0,0 +1,70 @@
1
+ ---
2
+ stats:
3
+ service : Stats
4
+ title : ~
5
+ loadpath : ~
6
+ exclude : ~
7
+ output : ~
8
+ active : true
9
+
10
+ box:
11
+ service: Box
12
+ active : true
13
+ types : [ gem, tar ]
14
+ spec : true
15
+ include: [ bin, demo, doc, lib, meta, test, "[A-Z]*" ]
16
+ exclude: [ doc/rdoc, doc/ri ]
17
+
18
+ dnote:
19
+ service : DNote
20
+ loadpath : ~
21
+ labels : ~
22
+ output : ~
23
+ format : ~
24
+ active : true
25
+
26
+ email:
27
+ service : Email
28
+ file : ~
29
+ subject : ~
30
+ mailto :
31
+ - ruby-talk@ruby-lang.org
32
+ - proutils@googlegroups.com
33
+ from : <%= ENV['EMAIL_ACCOUNT'] %>
34
+ server : <%= ENV['EMAIL_SERVER'] %>
35
+ port : <%= ENV['EMAIL_PORT'] %>
36
+ account : <%= ENV['EMAIL_ACCOUNT'] %>
37
+ domain : <%= ENV['EMAIL_DOMAIN'] %>
38
+ login : <%= ENV['EMAIL_LOGIN'] %>
39
+ secure : <%= ENV['EMAIL_SECURE'] %>
40
+ active : true
41
+
42
+ ridoc:
43
+ service: RIDoc
44
+ include: ~
45
+ exclude: ~
46
+ active : true
47
+
48
+ syntax:
49
+ service : Syntax
50
+ loadpath : ~
51
+ exclude : ~
52
+ active : false
53
+
54
+ testrb:
55
+ service : TestUnit
56
+ tests : ~
57
+ exclude : ~
58
+ loadpath : ~
59
+ requires : ~
60
+ live : false
61
+ active : false
62
+
63
+ vclog:
64
+ service : VClog
65
+ format : html # xml, txt
66
+ layout : rel # gnu
67
+ typed : false
68
+ output : ~
69
+ active : false
70
+
data/demo/01_spec.qed CHANGED
@@ -1,7 +1,7 @@
1
1
  = Standard Sections
2
2
 
3
- QED demos are light-weight specification documents, suitable
4
- for Interface-driven Development. The documents are divided up into
3
+ QED demos are light-weight specification documents, highly suitable
4
+ to interface-driven design. The documents are divided up into
5
5
  clauses separated by blank lines. Clauses that are flush to the
6
6
  left margin are always explanation or comment clauses. Indented
7
7
  clauses are always executable code.
@@ -121,7 +121,7 @@ a separate file. The +Data+ method makes is easy to load such files.
121
121
 
122
122
  Data('data.txt').assert =~ /dolor/
123
123
 
124
- All files are looked for relative to the location of current document.
124
+ All files are found relative to the location of current document.
125
125
 
126
126
  = Tabular Steps
127
127
 
@@ -129,9 +129,9 @@ The +Table+ method is similar to the +Data+ method except that it
129
129
  expects a YAML file, and it can take a block to iterate the data over.
130
130
  This makes it easy to test tables of examples.
131
131
 
132
- The arity of the table block determines the number of columns each row
133
- in the table should have. Each row is assigned in turn and run
134
- through the coded step. Consider the following example:
132
+ The arity of the table block corresponds to the number of columns in
133
+ each row of the table. Each row is assigned in turn and run through
134
+ the coded step. Consider the following example:
135
135
 
136
136
  Every row in the {table.yml table}[table.yml] will be assigned to
137
137
  the block parameters and run through the subsequent assertion.
@@ -171,5 +171,5 @@ This concludes the basic overview of QED's specification system, which
171
171
  is itself a QED document. Yes, we eat our own dog food.
172
172
 
173
173
  ---
174
- require 'helper'
174
+ 1[helper.rb] Helper
175
175
 
data/demo/02_err.qed ADDED
@@ -0,0 +1,18 @@
1
+ = Examples of Failure
2
+
3
+ This document is here simply to demonstrate what
4
+ a failed step looks like.
5
+
6
+ 1.assert == 2
7
+
8
+ And this step demonstrates an error.
9
+
10
+ raise "just because"
11
+
12
+ When run with the -v (verbatim) option, +qed+ will
13
+ highlight these in red and give a brief error
14
+ message.
15
+
16
+ ---
17
+ 1[sample.rb] Sample Helper
18
+
data/demo/03_site.qed ADDED
@@ -0,0 +1,12 @@
1
+ = Addition
2
+
3
+ require 'calculator'
4
+ calculator = Caclulater.new
5
+
6
+ A Calculator can add two numbers.
7
+
8
+ calculator.push 2
9
+ calculator.push 2
10
+ calculator.add
11
+ calculator.output.assert == 4
12
+
@@ -0,0 +1,4 @@
1
+ #require 'ae/should'
2
+ puts "This is just here to demonstrate that helpers are loaded."
3
+ puts
4
+
data/doc/qedoc/index.html CHANGED
@@ -1,6 +1,6 @@
1
1
  <html>
2
2
  <head>
3
- <title>Demonstration</title>
3
+ <title>QED Demonstrandum</title>
4
4
 
5
5
  <style>
6
6
  #container{ margin: 0 auto; width: 800px; }
@@ -19,7 +19,7 @@
19
19
  h1 { border-bottom: 2px solid silver; }
20
20
  h2 { border-bottom: 2px solid silver; padding-top: 0.5em; }
21
21
 
22
- hr { border: 1px solid silver; }
22
+ hr { color: #ccc; margin-top: 1.6em; }
23
23
 
24
24
  p { color: #222; text-align: justify; margin-top: 0.5em; margin-bottom: 0.5em; line-height: 1.4em; }
25
25
 
@@ -89,7 +89,7 @@
89
89
  <div id="header">
90
90
  <img src="img/icon/book.jpg" align="left" style="padding-right: 10px;" alt=""/>
91
91
 
92
- <h1 class="title">Demonstration</h1>
92
+ <h1 class="title">QED Demonstrandum</h1>
93
93
 
94
94
  <h1>Table of Contents</h1>
95
95
 
@@ -100,8 +100,8 @@
100
100
  <div id="content">
101
101
  <h1>Standard Sections</h1>
102
102
  <p>
103
- QED demos are light-weight specification documents, suitable for
104
- Interface-driven Development. The documents are divided up into clauses
103
+ QED demos are light-weight specification documents, highly suitable to
104
+ interface-driven design. The documents are divided up into clauses
105
105
  separated by blank lines. Clauses that are flush to the left margin are
106
106
  always explanation or comment clauses. Indented clauses are always
107
107
  executable code.
@@ -249,7 +249,7 @@ The <tt>Data</tt> method makes is easy to load such files.
249
249
  Data('data.txt').assert =~ /dolor/
250
250
  </pre>
251
251
  <p>
252
- All files are looked for relative to the location of current document.
252
+ All files are found relative to the location of current document.
253
253
  </p>
254
254
  <h1>Tabular Steps</h1>
255
255
  <p>
@@ -258,9 +258,9 @@ that it expects a YAML file, and it can take a block to iterate the data
258
258
  over. This makes it easy to test tables of examples.
259
259
  </p>
260
260
  <p>
261
- The arity of the table block determines the number of columns each row in
262
- the table should have. Each row is assigned in turn and run through the
263
- coded step. Consider the following example:
261
+ The arity of the table block corresponds to the number of columns in each
262
+ row of the table. Each row is assigned in turn and run through the coded
263
+ step. Consider the following example:
264
264
  </p>
265
265
  <p>
266
266
  Every row in the <a href="http://table.yml">table.yml table</a> will be
@@ -310,7 +310,28 @@ This concludes the basic overview of QED&#8217;s specification system,
310
310
  which is itself a QED document. Yes, we eat our own dog food.
311
311
  </p>
312
312
  <hr size="1"></hr><p>
313
- require &#8216;helper&#8217;
313
+ <a href="http://helper.rb">1</a> Helper
314
+ </p>
315
+
316
+ <h1>Examples of Failure</h1>
317
+ <p>
318
+ This document is here simply to demonstrate what a failed step looks like.
319
+ </p>
320
+ <pre>
321
+ 1.assert == 2
322
+ </pre>
323
+ <p>
324
+ And this step demonstrates an error.
325
+ </p>
326
+ <pre>
327
+ raise &quot;just because&quot;
328
+ </pre>
329
+ <p>
330
+ When run with the -v (verbatim) option, <tt>qed</tt> will highlight these
331
+ in red and give a brief error message.
332
+ </p>
333
+ <hr size="1"></hr><p>
334
+ <a href="http://helper.rb">1</a> Helper
314
335
  </p>
315
336
 
316
337
 
data/lib/qed/command.rb CHANGED
@@ -2,58 +2,127 @@
2
2
 
3
3
  require 'qed'
4
4
  require 'optparse'
5
+ require 'shellwords'
5
6
 
6
7
  module QED
7
8
 
8
9
  # = QED Commandline Tool
9
10
  #
10
11
  class Command
12
+
13
+ # Configuration directory.
14
+ CONFDIR = "{.,}config/qed"
15
+
16
+ # Initialize and execute.
11
17
  def self.execute
12
18
  new.execute
13
19
  end
14
20
 
15
- #
21
+ # Ouput format.
16
22
  attr :format
17
23
 
24
+ # Make sure format is a symbol.
25
+ def format=(type)
26
+ @format = type.to_sym
27
+ end
28
+
29
+ # Trace execution?
30
+ attr :trace
31
+
32
+ # Options defined by selected profile.
33
+ attr :profile
34
+
35
+ # Command-line options.
36
+ attr :options
37
+
38
+ # Files to be run.
39
+ attr :files
40
+
18
41
  #
42
+ def files=(globs)
43
+ @files = [globs].flatten
44
+ end
45
+
46
+ #
47
+ attr_accessor :loadpath
48
+
49
+ #
50
+ attr_accessor :requires
51
+
52
+ #
53
+ attr_accessor :env
54
+
55
+ #
56
+
19
57
  def initialize
20
- @format = nil
58
+ @format = nil
59
+ @env = nil
60
+ @profile = nil
61
+ @requires = []
62
+ @loadpath = []
63
+ @files = []
64
+ @options = {}
21
65
  end
22
66
 
23
67
  # Instance of OptionParser
68
+
24
69
  def opts
25
70
  @opts ||= OptionParser.new do |opt|
26
71
 
72
+ opt.separator("Custom Profiles:") unless profiles.empty?
73
+
74
+ profiles.each do |name, value|
75
+ o = "--#{name}"
76
+ opt.on(o, "#{name} custom profile") do
77
+ @profile = name
78
+ end
79
+ end
80
+
81
+ opt.separator("Report Options (pick one):")
82
+
27
83
  opt.on('--dotprogress', '-d', "use dot-progress reporter [default]") do
28
- @format = :summary
84
+ @options[:format] = :summary
29
85
  end
30
86
 
31
87
  opt.on('--verbatim', '-v', "use verbatim reporter") do
32
- @format = :verbatim
88
+ @options[:format] = :verbatim
33
89
  end
34
90
 
35
91
  opt.on('--summary', '-s', "use summary reporter") do
36
- @format = :summary
92
+ @options[:format] = :summary
37
93
  end
38
94
 
39
95
  opt.on('--script', "psuedo-reporter") do
40
- @format = :script # psuedo-reporter
96
+ @options[:script] # psuedo-reporter
97
+ end
98
+
99
+ opt.separator("Control Options:")
100
+
101
+ opt.on('--env', '-e [NAME]', "runtime environment [default]") do |name|
102
+ @options[:env] = name
103
+ end
104
+
105
+ opt.on('--loadpath', "-I PATH", "add paths to $LOAD_PATH") do |arg|
106
+ @options[:loadpath] ||= []
107
+ @options[:loadpath].concat(arg.split(/[:;]/).map{ |dir| File.expand_path(dir) })
41
108
  end
42
109
 
43
- opt.on('--loadpath', "-I", "add paths to $LOAD_PATH") do |arg|
44
- libs = arg.split(/[:;]/).map{ |dir| File.expand_path(dir) }
45
- libs.each{|dir| $LOAD_PATH.unshift(dir)}
110
+ opt.on('--require', "-r", "require library") do |arg|
111
+ @options[:requires] ||= []
112
+ @options[:requires].concat(arg.split(/[:;]/)) #.map{ |dir| File.expand_path(dir) })
46
113
  end
47
114
 
48
- opt.on('--verbose', '-V', "extra verbose output") do
49
- @verbose = true
50
- $VERBOSE = true
115
+ opt.on('--trace', '-t', "show full backtraces for exceptions") do
116
+ @options[:trace] = true
51
117
  end
52
118
 
53
- opt.on('--debug', "demos will exit on error") do
119
+ opt.on('--debug', "exit immediately upon raised exception") do
120
+ $VERBOSE = true # wish this were called $WARN
54
121
  $DEBUG = true
55
122
  end
56
123
 
124
+ opt.separator("Optional Commands:")
125
+
57
126
  opt.on_tail('--version', "display version") do
58
127
  puts "QED #{VERSION}"
59
128
  exit
@@ -73,35 +142,24 @@ module QED
73
142
  end
74
143
 
75
144
  #
76
- #def load_rc
77
- # if rcfile = Dir['.config/qed{,rc}{,.rb}'].first
78
- # load(rcfile)
79
- # end
80
- #end
81
-
82
- # TODO: Better way to load helpers?
83
- #
84
- #def load_helpers
85
- # dirs = spec_files.map{ |file| File.join(Dir.pwd, File.dirname(file)) }
86
- # dirs = dirs.select{ |dir| File.directory?(dir) }
87
- # dirs.each do |dir|
88
- # while dir != '/' do
89
- # helper = File.join(dir, 'qed_helper.rb')
90
- # load(helper) if File.exist?(helper)
91
- # break if Dir.pwd == dir
92
- # dir = File.dirname(dir)
93
- # end
94
- # end
95
- #end
96
145
 
97
- #
98
146
  def demos
99
147
  demo_files
100
148
  end
101
149
 
102
150
  #
151
+
103
152
  def demo_files
104
- files = ARGV.map do |pattern|
153
+ files = self.files
154
+
155
+ #if files.empty?
156
+ # if File.directory?('test')
157
+ # files << 'test/doc{,s}'
158
+ # files << 'test/demo{,s}'
159
+ # end
160
+ #end
161
+
162
+ files = files.map do |pattern|
105
163
  Dir[pattern]
106
164
  end.flatten.uniq
107
165
 
@@ -113,7 +171,7 @@ module QED
113
171
  end
114
172
  end
115
173
 
116
- file = files.flatten.uniq
174
+ files = files.flatten.uniq
117
175
 
118
176
  #files = files.select do |file|
119
177
  # %w{.yml .yaml .rb}.include?(File.extname(file))
@@ -122,38 +180,48 @@ module QED
122
180
  files
123
181
  end
124
182
 
125
- #
126
- def reporter
127
- case format
128
- when :dotprogress
129
- Reporter::DotProgress.new(reporter_options)
130
- when :verbatim
131
- Reporter::Verbatim.new(reporter_options)
132
- when :summary
133
- Reporter::Summary.new(reporter_options)
134
- else
135
- nil
136
- end
137
- end
183
+ # Instance of Runner class.
138
184
 
139
- #
140
- def reporter_options
141
- { :verbose => @verbose }
185
+ def runner
186
+ Runner.new(demos, :format=>format, :trace=>trace)
142
187
  end
143
188
 
144
- #
145
- def runner
146
- Runner.new(demos, reporter)
189
+ # Parse command-line options along with profile options.
190
+
191
+ def parse
192
+ @files = []
193
+ argv = ARGV.dup
194
+ opts.parse!(argv)
195
+ @files.concat(argv)
196
+
197
+ if profile
198
+ args = profiles[profile]
199
+ argv = Shellwords.shellwords(args)
200
+ opts.parse!(argv)
201
+ @files.concat(argv)
202
+ end
203
+
204
+ options.each do |k,v|
205
+ __send__("#{k}=", v)
206
+ end
147
207
  end
148
208
 
149
- #
209
+ # Run demonstrations.
210
+
150
211
  def execute
151
- opts.parse!
152
- #load_rc
153
- #load_helpers
154
- case reporter
212
+ parse
213
+
214
+ abort "No documents." if demos.empty?
215
+
216
+ prepare_loadpath
217
+
218
+ require_libraries
219
+ require_environment
220
+
221
+ # TODO: Remove case, can :script be done with Reporter or do we ne need selectable Runner?
222
+ case format
155
223
  when :script
156
- specs.each do |spec|
224
+ demos.each do |spec|
157
225
  puts spec.to_script
158
226
  end
159
227
  else
@@ -161,6 +229,44 @@ module QED
161
229
  end
162
230
  end
163
231
 
232
+ # Profile configurations.
233
+
234
+ def profiles
235
+ @profiles ||= (
236
+ file = Dir["#{CONFDIR}/profile{,s}.{yml,yaml}"].first
237
+ file ? YAML.load(File.new(file)) : {}
238
+ )
239
+ end
240
+
241
+ # Add to load path (from -I option).
242
+
243
+ def prepare_loadpath
244
+ loadpath.each{ |dir| $LOAD_PATH.unshift(dir) }
245
+ end
246
+
247
+ # Require libraries (from -r option).
248
+
249
+ def require_libraries
250
+ requires.each{ |file| require(file) }
251
+ end
252
+
253
+ # Require requirement file (from -e option.
254
+
255
+ def require_environment
256
+ if env
257
+ if file = Dir["#{CONFDIR}/{env,environments}/#{env}.rb"].first
258
+ require(file)
259
+ end
260
+ else
261
+ if file = Dir["#{CONFDIR}/env.rb"].first
262
+ require(file)
263
+ elsif file = Dir["#{CONFDIR}/{env,environments}/default.rb"].first
264
+ require(file)
265
+ end
266
+ end
267
+ end
268
+
164
269
  end
270
+
165
271
  end
166
272