qed 2.5.0 → 2.5.1
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.
- data/.ruby +47 -0
- data/bin/qed +1 -1
- data/lib/qed/demo.rb +18 -7
- data/lib/qed/evaluator.rb +31 -8
- data/lib/qed/reporter/abstract.rb +4 -4
- data/lib/qed/reporter/verbatim.rb +5 -3
- data/lib/qed/scope.rb +22 -6
- data/lib/qed/session.rb +240 -18
- data/lib/qed/settings.rb +155 -0
- data/lib/qed.rb +18 -17
- data/lib/qed.yml +47 -0
- data/lib/yard-qed.rb +1 -0
- metadata +16 -24
- data/History.rdoc +0 -210
- data/eg/hello_world.rdoc +0 -15
- data/eg/view_error.rdoc +0 -21
- data/eg/website.rdoc +0 -12
- data/lib/qed/command.rb +0 -387
- data/lib/qed/meta/data.rb +0 -27
- data/lib/qed/meta/package +0 -10
- data/lib/qed/meta/profile +0 -16
- data/meta/data.rb +0 -27
- data/meta/package +0 -10
- data/meta/profile +0 -16
data/lib/qed/command.rb
DELETED
@@ -1,387 +0,0 @@
|
|
1
|
-
require 'optparse'
|
2
|
-
require 'shellwords'
|
3
|
-
require 'fileutils'
|
4
|
-
|
5
|
-
module QED
|
6
|
-
|
7
|
-
def self.main(*argv)
|
8
|
-
Command.main(*argv)
|
9
|
-
end
|
10
|
-
|
11
|
-
# QED Command-line tool.
|
12
|
-
#
|
13
|
-
# TODO: Merge Command with Session ?
|
14
|
-
class Command
|
15
|
-
|
16
|
-
# Configuration directory `.qed`, `.config/qed` or `config/qed`.
|
17
|
-
# In this directory special configuration files can be placed
|
18
|
-
# to autmatically effect qed execution. In particular you can
|
19
|
-
# add a `profiles.yml` file to setup convenient execution
|
20
|
-
# scenarios.
|
21
|
-
CONFIG_PATTERN = "{.,.config/,config/}qed"
|
22
|
-
|
23
|
-
## Default location of demonstrations if no specific files
|
24
|
-
## or locations given. This is use in Dir.glob. The default
|
25
|
-
## locations are qed/, demo/ or demos/, searched for in that
|
26
|
-
## order relative to the root directory.
|
27
|
-
##--
|
28
|
-
## TODO: deprecate this
|
29
|
-
##++
|
30
|
-
##DEMO_LOCATION = '{qed,demo,demos}'
|
31
|
-
|
32
|
-
# Glob pattern used to search for project's root directory.
|
33
|
-
ROOT_PATTERN = '{.ruby,.git/,.hg/,_darcs/,.qed/,.config/qed/,config/qed/}'
|
34
|
-
|
35
|
-
# Directory names to omit from automatic selection.
|
36
|
-
OMIT_PATHS = %w{applique helpers support sample samples fixture fixtures}
|
37
|
-
|
38
|
-
# Home directory.
|
39
|
-
HOME = File.expand_path('~')
|
40
|
-
|
41
|
-
# Default recognized demos file types.
|
42
|
-
DEMO_TYPES = %w{qed rdoc md markdown}
|
43
|
-
|
44
|
-
#
|
45
|
-
CODE_TYPES = %w{rb}
|
46
|
-
|
47
|
-
# Instantiate a new Command object and call #execute.
|
48
|
-
def self.main(*argv)
|
49
|
-
new.execute(argv)
|
50
|
-
end
|
51
|
-
|
52
|
-
# Ouput format.
|
53
|
-
attr :format
|
54
|
-
|
55
|
-
# Make sure format is a symbol.
|
56
|
-
def format=(type)
|
57
|
-
@format = type.to_sym
|
58
|
-
end
|
59
|
-
|
60
|
-
# Trace execution?
|
61
|
-
attr :trace
|
62
|
-
|
63
|
-
# Options defined by selected profile.
|
64
|
-
attr :profile
|
65
|
-
|
66
|
-
# Command-line options.
|
67
|
-
#attr :options
|
68
|
-
|
69
|
-
# Files to be run.
|
70
|
-
attr_reader :files
|
71
|
-
|
72
|
-
# Ensure files are in a flat list.
|
73
|
-
def files=(globs)
|
74
|
-
@files = [globs].flatten
|
75
|
-
end
|
76
|
-
|
77
|
-
# Paths to be added to $LOAD_PATH.
|
78
|
-
attr_accessor :loadpath
|
79
|
-
|
80
|
-
# Libraries to be required.
|
81
|
-
attr_accessor :requires
|
82
|
-
|
83
|
-
# Move to root directory?
|
84
|
-
attr_accessor :root
|
85
|
-
|
86
|
-
# Parse mode.
|
87
|
-
attr_accessor :mode
|
88
|
-
|
89
|
-
#
|
90
|
-
attr_accessor :omit
|
91
|
-
|
92
|
-
#
|
93
|
-
# TODO: Should extension and profile have a common reference?
|
94
|
-
def initialize
|
95
|
-
@format = :dotprogress
|
96
|
-
#@extension = :default
|
97
|
-
@profile = :default
|
98
|
-
@requires = []
|
99
|
-
@loadpath = []
|
100
|
-
@files = []
|
101
|
-
#@options = {}
|
102
|
-
|
103
|
-
@omit = OMIT_PATHS
|
104
|
-
end
|
105
|
-
|
106
|
-
# Instance of OptionParser
|
107
|
-
def opts
|
108
|
-
@opts ||= OptionParser.new do |opt|
|
109
|
-
opt.banner = "Usage: qed [options] <files...>"
|
110
|
-
|
111
|
-
opt.separator("Custom Profiles:") unless profiles.empty?
|
112
|
-
|
113
|
-
profiles.each do |name, value|
|
114
|
-
o = "--#{name}"
|
115
|
-
opt.on(o, "#{name} custom profile") do
|
116
|
-
self.profile = name
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
opt.separator("Report Formats (pick one):")
|
121
|
-
opt.on('--dotprogress', '-d', "use dot-progress reporter [default]") do
|
122
|
-
self.format = :dotprogress
|
123
|
-
end
|
124
|
-
opt.on('--verbatim', '-v', "use verbatim reporter") do
|
125
|
-
self.format = :verbatim
|
126
|
-
end
|
127
|
-
opt.on('--bullet', '-b', "use bullet-point reporter") do
|
128
|
-
self.format = :bullet
|
129
|
-
end
|
130
|
-
opt.on('--html', '-h', "use underlying HTML reporter") do
|
131
|
-
self.format = :html
|
132
|
-
end
|
133
|
-
#opt.on('--script', "psuedo-reporter") do
|
134
|
-
# self.format = :script # psuedo-reporter
|
135
|
-
#end
|
136
|
-
opt.on('--format', '-f FORMAT', "use custom reporter") do |format|
|
137
|
-
self.format = format
|
138
|
-
end
|
139
|
-
opt.separator("Control Options:")
|
140
|
-
opt.on('--root', '-R', "run from alternate directory") do |path|
|
141
|
-
self.root = path
|
142
|
-
end
|
143
|
-
opt.on('--comment', '-c', "Run comment code.") do
|
144
|
-
self.mode = :comment
|
145
|
-
end
|
146
|
-
opt.on('--profile', '-p NAME', "load runtime profile") do |name|
|
147
|
-
self.profile = name
|
148
|
-
end
|
149
|
-
opt.on('--loadpath', "-I PATH", "add paths to $LOAD_PATH") do |paths|
|
150
|
-
self.loadpath = paths.split(/[:;]/).map{|d| File.expand_path(d)}
|
151
|
-
end
|
152
|
-
opt.on('--require', "-r LIB", "require library") do |paths|
|
153
|
-
self.requires = paths.split(/[:;]/)
|
154
|
-
end
|
155
|
-
opt.on('--trace', '-t', "show full backtraces for exceptions") do
|
156
|
-
self.trace = true
|
157
|
-
end
|
158
|
-
opt.on('--debug', "exit immediately upon raised exception") do
|
159
|
-
$VERBOSE = true # wish this were called $WARN
|
160
|
-
$DEBUG = true
|
161
|
-
end
|
162
|
-
opt.separator("Optional Commands:")
|
163
|
-
opt.on_tail('--version', "display version") do
|
164
|
-
puts "QED #{VERSION}"
|
165
|
-
exit
|
166
|
-
end
|
167
|
-
opt.on_tail('--copyright', "display copyrights") do
|
168
|
-
puts "Copyright (c) 2008 Thomas Sawyer, Apache 2.0 License"
|
169
|
-
exit
|
170
|
-
end
|
171
|
-
opt.on_tail('--help', '-h', "display this help message") do
|
172
|
-
puts opt
|
173
|
-
exit
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
# Returns a list of demo files. The files returned depends on the
|
179
|
-
# +files+ attribute and if none given, then the current run mode.
|
180
|
-
def demos
|
181
|
-
@demos ||= (
|
182
|
-
if mode == :comment
|
183
|
-
demos_in_comment_mode
|
184
|
-
else
|
185
|
-
demos_in_normal_mode
|
186
|
-
end
|
187
|
-
)
|
188
|
-
end
|
189
|
-
|
190
|
-
# Collect default files to process in normal demo mode.
|
191
|
-
def demos_in_normal_mode
|
192
|
-
demos_gather(DEMO_TYPES)
|
193
|
-
end
|
194
|
-
|
195
|
-
# Collect default files to process in code comment mode.
|
196
|
-
#
|
197
|
-
# TODO: Sure removing applique files is the best approach here?
|
198
|
-
def demos_in_comment_mode
|
199
|
-
files = demos_gather(CODE_TYPES)
|
200
|
-
files = files.reject{ |f| f.index('applique/') } # don't include applique files ???
|
201
|
-
files
|
202
|
-
end
|
203
|
-
|
204
|
-
# Gather list of demo files. Uses +omit+ to remove certain files
|
205
|
-
# based on the name of their parent directory.
|
206
|
-
def demos_gather(extensions=DEMO_TYPES)
|
207
|
-
files = self.files
|
208
|
-
#files << default_location if files.empty?
|
209
|
-
files = files.map{|pattern| Dir[pattern]}.flatten.uniq
|
210
|
-
files = files.map do |file|
|
211
|
-
if File.directory?(file)
|
212
|
-
Dir[File.join(file,'**','*.{' + extensions.join(',') + '}')]
|
213
|
-
else
|
214
|
-
file
|
215
|
-
end
|
216
|
-
end
|
217
|
-
files = files.flatten.uniq
|
218
|
-
files = files.reject{ |f| f =~ Regexp.new('\/'+omit.join('|')+'\/') }
|
219
|
-
files.map{|f| File.expand_path(f) }.uniq.sort
|
220
|
-
end
|
221
|
-
|
222
|
-
# Parse command-line options along with profile options.
|
223
|
-
def parse(argv)
|
224
|
-
#@files = []
|
225
|
-
opts.parse!(argv ||= ARGV.dup)
|
226
|
-
#@files.concat(argv)
|
227
|
-
@files = argv
|
228
|
-
|
229
|
-
if @files.empty?
|
230
|
-
puts "No files."
|
231
|
-
puts opts
|
232
|
-
exit
|
233
|
-
end
|
234
|
-
|
235
|
-
#if profile
|
236
|
-
#if args = profiles[profile]
|
237
|
-
# argv = Shellwords.shellwords(args)
|
238
|
-
# opts.parse!(argv)
|
239
|
-
# @files.concat(argv)
|
240
|
-
#end
|
241
|
-
#end
|
242
|
-
|
243
|
-
#options.each do |k,v|
|
244
|
-
# __send__("#{k}=", v)
|
245
|
-
#end
|
246
|
-
end
|
247
|
-
|
248
|
-
# Run demonstrations.
|
249
|
-
def execute(argv)
|
250
|
-
parse(argv)
|
251
|
-
|
252
|
-
abort "No documents." if demos.empty?
|
253
|
-
|
254
|
-
prepare_loadpath
|
255
|
-
require_libraries
|
256
|
-
|
257
|
-
require_profile # TODO: here or in chdir?
|
258
|
-
|
259
|
-
jump = root || temporary_directory
|
260
|
-
|
261
|
-
Dir.chdir(jump) do
|
262
|
-
session.run
|
263
|
-
end
|
264
|
-
end
|
265
|
-
|
266
|
-
# Session instance.
|
267
|
-
def session
|
268
|
-
@session ||= Session.new(demos, :format=>format, :trace=>trace, :mode=>mode)
|
269
|
-
end
|
270
|
-
|
271
|
-
# Project's root directory.
|
272
|
-
def root_directory
|
273
|
-
@root_directory ||= find_root
|
274
|
-
end
|
275
|
-
|
276
|
-
# Project's QED configuation directory.
|
277
|
-
def config_directory
|
278
|
-
@config_directory ||= find_config #Dir[File.join(root_directory, CONFIG_PATTERN)].first
|
279
|
-
end
|
280
|
-
|
281
|
-
# Profile configurations.
|
282
|
-
def profiles
|
283
|
-
@profiles ||= (
|
284
|
-
files = Dir["#{config_directory}/*.rb"]
|
285
|
-
files.map do |file|
|
286
|
-
File.basename(file).chomp('.rb')
|
287
|
-
end
|
288
|
-
)
|
289
|
-
end
|
290
|
-
|
291
|
-
# Add to load path (from -I option).
|
292
|
-
def prepare_loadpath
|
293
|
-
loadpath.each{ |dir| $LOAD_PATH.unshift(dir) }
|
294
|
-
end
|
295
|
-
|
296
|
-
# Require libraries (from -r option).
|
297
|
-
def require_libraries
|
298
|
-
requires.each{ |file| require(file) }
|
299
|
-
end
|
300
|
-
|
301
|
-
# Require requirement file (from -e option).
|
302
|
-
def require_profile
|
303
|
-
return unless config_directory
|
304
|
-
if file = Dir["#{config_directory}/#{profile}.rb"].first
|
305
|
-
require(file)
|
306
|
-
end
|
307
|
-
end
|
308
|
-
|
309
|
-
#
|
310
|
-
def temporary_directory
|
311
|
-
@temporary_directory ||= (
|
312
|
-
dir = File.join(root_directory, 'tmp', 'qed')
|
313
|
-
FileUtils.mkdir_p(dir)
|
314
|
-
dir
|
315
|
-
)
|
316
|
-
end
|
317
|
-
|
318
|
-
# Locate project's root directory. This is done by searching upward
|
319
|
-
# in the file heirarchy for the existence of one of the following
|
320
|
-
# path names, each group being tried in turn.
|
321
|
-
#
|
322
|
-
# * .git/
|
323
|
-
# * .hg/
|
324
|
-
# * _darcs/
|
325
|
-
# * .config/qed/
|
326
|
-
# * config/qed/
|
327
|
-
# * .qed/
|
328
|
-
# * .ruby
|
329
|
-
#
|
330
|
-
# Failing to find any of these locations, resort to the fallback:
|
331
|
-
#
|
332
|
-
# * lib/
|
333
|
-
#
|
334
|
-
def find_root(path=nil)
|
335
|
-
path = File.expand_path(path || Dir.pwd)
|
336
|
-
path = File.dirname(path) unless File.directory?(path)
|
337
|
-
|
338
|
-
root = lookup(ROOT_PATTERN, path)
|
339
|
-
return root if root
|
340
|
-
|
341
|
-
#root = lookup(path, '{.qed,.config/qed,config/qed}/')
|
342
|
-
#return root if root
|
343
|
-
|
344
|
-
#root = lookup(path, '{qed,demo,demos}/')
|
345
|
-
#return root if root
|
346
|
-
|
347
|
-
root = lookup('lib/', path)
|
348
|
-
return root if root
|
349
|
-
|
350
|
-
abort "QED failed to resolve project's root location.\n" +
|
351
|
-
"QED looks for following entries to identify the root:\n" +
|
352
|
-
" .config/qed/\n" +
|
353
|
-
" config/qed/\n" +
|
354
|
-
" .qed/\n" +
|
355
|
-
" .ruby\n" +
|
356
|
-
" lib/\n" +
|
357
|
-
"Please add one of them to your project to proceed."
|
358
|
-
end
|
359
|
-
|
360
|
-
# Locate configuration directory by seaching up the
|
361
|
-
# file hierachy relative to the working directory
|
362
|
-
# for one of the following paths:
|
363
|
-
#
|
364
|
-
# * .config/qed/
|
365
|
-
# * config/qed/
|
366
|
-
# * .qed/
|
367
|
-
#
|
368
|
-
def find_config
|
369
|
-
Dir[File.join(root_directory,CONFIG_PATTERN)].first
|
370
|
-
end
|
371
|
-
|
372
|
-
# Lookup path +glob+, searching each higher directory
|
373
|
-
# in turn until just before the users home directory
|
374
|
-
# is reached or just before the system's root directory.
|
375
|
-
#
|
376
|
-
# TODO: include HOME directory in search?
|
377
|
-
def lookup(glob, path=Dir.pwd)
|
378
|
-
until path == HOME or path == '/' # until home or root
|
379
|
-
mark = Dir.glob(File.join(path,glob), File::FNM_CASEFOLD).first
|
380
|
-
return path if mark
|
381
|
-
path = File.dirname(path)
|
382
|
-
end
|
383
|
-
end
|
384
|
-
|
385
|
-
end
|
386
|
-
|
387
|
-
end
|
data/lib/qed/meta/data.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
module QED
|
2
|
-
|
3
|
-
DIRECTORY = File.dirname(__FILE__)
|
4
|
-
|
5
|
-
def self.package
|
6
|
-
@package ||= (
|
7
|
-
require 'yaml'
|
8
|
-
YAML.load(File.new(DIRECTORY + '/package'))
|
9
|
-
)
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.profile
|
13
|
-
@profile ||= (
|
14
|
-
require 'yaml'
|
15
|
-
YAML.load(File.new(DIRECTORY + '/profile'))
|
16
|
-
)
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.const_missing(name)
|
20
|
-
key = name.to_s.downcase
|
21
|
-
package[key] || profile[key] || super(name)
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
# becuase Ruby 1.8~ gets in the way
|
27
|
-
Object.__send__(:remove_const, :VERSION) if Object.const_defined?(:VERSION)
|
data/lib/qed/meta/package
DELETED
data/lib/qed/meta/profile
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
---
|
2
|
-
title: QED
|
3
|
-
suite: proutils
|
4
|
-
summary: Quod Erat Demonstrandum
|
5
|
-
authors: Thomas Sawyer <transfire@gmail.com>
|
6
|
-
created: 2006-12-16
|
7
|
-
|
8
|
-
description:
|
9
|
-
QED (Quality Ensured Demonstrations) is a TDD/BDD framework
|
10
|
-
utilizing Literate Programming techniques.
|
11
|
-
|
12
|
-
resources:
|
13
|
-
home: http://proutils.github.com/qed
|
14
|
-
work: http://github.com/proutils/qed
|
15
|
-
repo: git://github.com/proutils/qed.git
|
16
|
-
|
data/meta/data.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
module QED
|
2
|
-
|
3
|
-
DIRECTORY = File.dirname(__FILE__)
|
4
|
-
|
5
|
-
def self.package
|
6
|
-
@package ||= (
|
7
|
-
require 'yaml'
|
8
|
-
YAML.load(File.new(DIRECTORY + '/package'))
|
9
|
-
)
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.profile
|
13
|
-
@profile ||= (
|
14
|
-
require 'yaml'
|
15
|
-
YAML.load(File.new(DIRECTORY + '/profile'))
|
16
|
-
)
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.const_missing(name)
|
20
|
-
key = name.to_s.downcase
|
21
|
-
package[key] || profile[key] || super(name)
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
# becuase Ruby 1.8~ gets in the way
|
27
|
-
Object.__send__(:remove_const, :VERSION) if Object.const_defined?(:VERSION)
|
data/meta/package
DELETED
data/meta/profile
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
---
|
2
|
-
title: QED
|
3
|
-
suite: proutils
|
4
|
-
summary: Quod Erat Demonstrandum
|
5
|
-
authors: Thomas Sawyer <transfire@gmail.com>
|
6
|
-
created: 2006-12-16
|
7
|
-
|
8
|
-
description:
|
9
|
-
QED (Quality Ensured Demonstrations) is a TDD/BDD framework
|
10
|
-
utilizing Literate Programming techniques.
|
11
|
-
|
12
|
-
resources:
|
13
|
-
home: http://proutils.github.com/qed
|
14
|
-
work: http://github.com/proutils/qed
|
15
|
-
repo: git://github.com/proutils/qed.git
|
16
|
-
|