qed 1.3 → 2.0.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.
- data/CHANGELOG.txt +647 -0
- data/HISTORY +16 -0
- data/bin/qedoc +2 -51
- data/demo/error.rdoc +21 -0
- data/demo/{03_site.qed → website.rdoc} +0 -0
- data/doc/qedoc/index.html +160 -69
- data/lib/qed.rb +2 -2
- data/lib/qed/advice.rb +61 -0
- data/lib/qed/advice/events.rb +54 -0
- data/lib/qed/advice/patterns.rb +64 -0
- data/lib/qed/command.rb +76 -65
- data/lib/qed/config.rb +48 -13
- data/lib/qed/evaluator.rb +124 -0
- data/lib/qed/reporter/base.rb +93 -39
- data/lib/qed/reporter/bullet.rb +79 -0
- data/lib/qed/reporter/dotprogress.rb +9 -29
- data/lib/qed/reporter/html.rb +61 -0
- data/lib/qed/reporter/verbatim.rb +41 -47
- data/lib/qed/scope.rb +77 -0
- data/lib/qed/script.rb +66 -399
- data/lib/qed/session.rb +95 -0
- data/lib/qedoc/command.rb +76 -0
- data/lib/{qed → qedoc}/document.rb +31 -22
- data/lib/{qed → qedoc}/document/jquery.js +0 -0
- data/lib/{qed → qedoc}/document/markup.rb +0 -0
- data/lib/{qed → qedoc}/document/template.rhtml +0 -0
- data/meta/requires +2 -0
- data/meta/version +1 -1
- metadata +71 -34
- data/Syckfile +0 -70
- data/demo/01_spec.qed +0 -175
- data/demo/02_err.qed +0 -18
- data/demo/data.txt +0 -1
- data/demo/helpers/sample.rb +0 -4
- data/demo/table.yml +0 -5
- data/lib/qed/extract.rb +0 -137
- data/lib/qed/reporter/ditto.rb +0 -72
- data/lib/qed/reporter/summary.rb +0 -68
- data/lib/qed/runner.rb +0 -198
- data/lib/qed/script1.rb +0 -495
data/lib/qed.rb
CHANGED
data/lib/qed/advice.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
module QED
|
2
|
+
|
3
|
+
require 'qed/advice/events'
|
4
|
+
require 'qed/advice/patterns'
|
5
|
+
|
6
|
+
# = Advice
|
7
|
+
#
|
8
|
+
# This class tracks advice defined by demo scripts
|
9
|
+
# and helpers. It is instantiated in Scope, so that
|
10
|
+
# the advice methods will have access to the same
|
11
|
+
# local binding and the demo scripts themselves.
|
12
|
+
#
|
13
|
+
class Advice
|
14
|
+
|
15
|
+
attr :patterns
|
16
|
+
|
17
|
+
attr :events
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@patterns = Patterns.new
|
21
|
+
@events = Events.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def call(type, *args)
|
25
|
+
case type
|
26
|
+
when :when
|
27
|
+
@patterns.call(*args)
|
28
|
+
else
|
29
|
+
@events.call(type, *args)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
module Advisable
|
36
|
+
|
37
|
+
def __advice__
|
38
|
+
@__advice__ ||= Advice.new
|
39
|
+
end
|
40
|
+
|
41
|
+
def When(pattern, &procedure)
|
42
|
+
case pattern
|
43
|
+
when Symbol
|
44
|
+
__advice__.events.add(:"#{pattern}", &procedure)
|
45
|
+
else
|
46
|
+
__advice__.patterns.add(pattern, &procedure)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def Before(type=:code, &procedure)
|
51
|
+
__advice__.events.add(:"before_#{type}", &procedure)
|
52
|
+
end
|
53
|
+
|
54
|
+
def After(type=:code, &procedure)
|
55
|
+
__advice__.events.add(:"after_#{type}", &procedure)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module QED
|
2
|
+
|
3
|
+
class Advice
|
4
|
+
|
5
|
+
# Event advice: Before, After and Upon.
|
6
|
+
#
|
7
|
+
class Events
|
8
|
+
|
9
|
+
#
|
10
|
+
attr :signals
|
11
|
+
|
12
|
+
#
|
13
|
+
def initialize
|
14
|
+
@signals = [{}]
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
def add(type, &procedure)
|
19
|
+
@signals.last[type.to_sym] = procedure
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
def call(type, *args)
|
24
|
+
@signals.each do |set|
|
25
|
+
proc = set[type.to_sym]
|
26
|
+
proc.call(*args) if proc
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Clear last set of advice.
|
31
|
+
def reset
|
32
|
+
@signals.pop
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
def setup
|
37
|
+
@signals.push {}
|
38
|
+
end
|
39
|
+
|
40
|
+
# Clear advice.
|
41
|
+
def clear(type=nil)
|
42
|
+
if type
|
43
|
+
@signals.each{ |set| set.delete(type.to_sym) }
|
44
|
+
else
|
45
|
+
@signals = [{}]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module QED
|
2
|
+
|
3
|
+
# = Patter Advice (When)
|
4
|
+
#
|
5
|
+
# This class tracks When advice defined by demo scripts
|
6
|
+
# and helpers. It is instantiated in Scope, so that
|
7
|
+
# the advice methods will have access to the same
|
8
|
+
# local binding and the demo scripts themselves.
|
9
|
+
#
|
10
|
+
class Patterns
|
11
|
+
|
12
|
+
attr :when
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@when = []
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
def add(pattern, &procedure)
|
20
|
+
@when << [pattern, procedure]
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
def call(match, *args)
|
25
|
+
@when.each do |(pattern, proc)|
|
26
|
+
case pattern
|
27
|
+
when Regexp
|
28
|
+
regex = pattern
|
29
|
+
else
|
30
|
+
regex = when_string_to_regexp(pattern)
|
31
|
+
end
|
32
|
+
if md = regex.match(match)
|
33
|
+
proc.call(*md[1..-1])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
#
|
41
|
+
def when_string_to_regexp(str)
|
42
|
+
str = str.split(/(\(\(.*?\)\))(?!\))/).map{ |x|
|
43
|
+
x =~ /\A\(\((.*)\)\)\z/ ? $1 : Regexp.escape(x)
|
44
|
+
}.join
|
45
|
+
str = str.gsub(/(\\\ )+/, '\s+')
|
46
|
+
Regexp.new(str, Regexp::IGNORECASE)
|
47
|
+
|
48
|
+
#rexps = []
|
49
|
+
#str = str.gsub(/\(\((.*?)\)\)/) do |m|
|
50
|
+
# rexps << '(' + $1 + ')'
|
51
|
+
# "\0"
|
52
|
+
#end
|
53
|
+
#str = Regexp.escape(str)
|
54
|
+
#rexps.each do |r|
|
55
|
+
# str = str.sub("\0", r)
|
56
|
+
#end
|
57
|
+
#str = str.gsub(/(\\\ )+/, '\s+')
|
58
|
+
#Regexp.new(str, Regexp::IGNORECASE)
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
data/lib/qed/command.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'qed'
|
4
4
|
require 'optparse'
|
5
5
|
require 'shellwords'
|
6
|
+
require 'tilt'
|
6
7
|
|
7
8
|
module QED
|
8
9
|
|
@@ -13,6 +14,11 @@ module QED
|
|
13
14
|
# Configuration directory.
|
14
15
|
CONFDIR = "{.,}config/qed"
|
15
16
|
|
17
|
+
# Default location of demonstrations if no
|
18
|
+
# specific files or locations given. This
|
19
|
+
# is use in Dir.glob.
|
20
|
+
DEFAULT_DEMOS_LOCATION = '{qed}'
|
21
|
+
|
16
22
|
# Initialize and execute.
|
17
23
|
def self.execute
|
18
24
|
new.execute
|
@@ -50,18 +56,18 @@ module QED
|
|
50
56
|
attr_accessor :requires
|
51
57
|
|
52
58
|
#
|
53
|
-
attr_accessor :
|
59
|
+
attr_accessor :extension
|
54
60
|
|
55
|
-
#
|
61
|
+
# TODO: Should extension and profile have a common reference?
|
56
62
|
|
57
63
|
def initialize
|
58
|
-
@format
|
59
|
-
@
|
60
|
-
@profile
|
61
|
-
@requires
|
62
|
-
@loadpath
|
63
|
-
@files
|
64
|
-
@options
|
64
|
+
@format = :dotprogress
|
65
|
+
@extension = :default
|
66
|
+
@profile = :default
|
67
|
+
@requires = []
|
68
|
+
@loadpath = []
|
69
|
+
@files = []
|
70
|
+
@options = {}
|
65
71
|
end
|
66
72
|
|
67
73
|
# Instance of OptionParser
|
@@ -75,31 +81,39 @@ module QED
|
|
75
81
|
o = "--#{name}"
|
76
82
|
opt.on(o, "#{name} custom profile") do
|
77
83
|
@profile = name
|
78
|
-
end
|
84
|
+
end
|
79
85
|
end
|
80
86
|
|
81
|
-
opt.separator("Report
|
87
|
+
opt.separator("Report Formats (pick one):")
|
82
88
|
|
83
89
|
opt.on('--dotprogress', '-d', "use dot-progress reporter [default]") do
|
84
|
-
@options[:format] = :
|
90
|
+
@options[:format] = :dotprogress
|
85
91
|
end
|
86
92
|
|
87
93
|
opt.on('--verbatim', '-v', "use verbatim reporter") do
|
88
94
|
@options[:format] = :verbatim
|
89
95
|
end
|
90
96
|
|
91
|
-
opt.on('--
|
92
|
-
@options[:format] = :
|
97
|
+
opt.on('--bullet', '-b', "use bullet-point reporter") do
|
98
|
+
@options[:format] = :bullet
|
99
|
+
end
|
100
|
+
|
101
|
+
opt.on('--html', '-h', "use underlying HTML reporter") do
|
102
|
+
@options[:format] = :html
|
93
103
|
end
|
94
104
|
|
95
|
-
opt.on('--
|
96
|
-
@options[:
|
105
|
+
opt.on('--format', '-f FORMAT', "use custom reporter") do |format|
|
106
|
+
@options[:format] = format
|
97
107
|
end
|
98
108
|
|
109
|
+
#opt.on('--script', "psuedo-reporter") do
|
110
|
+
# @options[:format] = :script # psuedo-reporter
|
111
|
+
#end
|
112
|
+
|
99
113
|
opt.separator("Control Options:")
|
100
114
|
|
101
|
-
opt.on('--
|
102
|
-
@options[:
|
115
|
+
opt.on('--ext', '-e [NAME]', "runtime extension [default]") do |name|
|
116
|
+
@options[:extension] = name
|
103
117
|
end
|
104
118
|
|
105
119
|
opt.on('--loadpath', "-I PATH", "add paths to $LOAD_PATH") do |arg|
|
@@ -144,46 +158,32 @@ module QED
|
|
144
158
|
#
|
145
159
|
|
146
160
|
def demos
|
147
|
-
demo_files
|
148
|
-
end
|
149
|
-
|
150
|
-
#
|
151
|
-
|
152
|
-
def demo_files
|
153
161
|
files = self.files
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
# files << 'test/demo{,s}'
|
159
|
-
# end
|
160
|
-
#end
|
161
|
-
|
162
|
+
types = Tilt.mappings.keys
|
163
|
+
if files.empty?
|
164
|
+
files << DEFAULT_DEMOS_LOCATION
|
165
|
+
end
|
162
166
|
files = files.map do |pattern|
|
163
167
|
Dir[pattern]
|
164
168
|
end.flatten.uniq
|
165
|
-
|
166
169
|
files = files.map do |file|
|
167
170
|
if File.directory?(file)
|
168
|
-
Dir[File.join(file,'**','
|
171
|
+
Dir[File.join(file,'**','*.{' + types.join(',') + '}')]
|
169
172
|
else
|
170
173
|
file
|
171
174
|
end
|
172
175
|
end
|
173
|
-
|
174
|
-
files = files.flatten.uniq
|
175
|
-
|
176
|
+
files = files.flatten.uniq.sort
|
176
177
|
#files = files.select do |file|
|
177
178
|
# %w{.yml .yaml .rb}.include?(File.extname(file))
|
178
179
|
#end
|
179
|
-
|
180
180
|
files
|
181
181
|
end
|
182
182
|
|
183
|
-
#
|
183
|
+
# Session instance.
|
184
184
|
|
185
|
-
def
|
186
|
-
|
185
|
+
def session
|
186
|
+
@session ||= Session.new(demos, :format=>format, :trace=>trace)
|
187
187
|
end
|
188
188
|
|
189
189
|
# Parse command-line options along with profile options.
|
@@ -194,12 +194,13 @@ module QED
|
|
194
194
|
opts.parse!(argv)
|
195
195
|
@files.concat(argv)
|
196
196
|
|
197
|
-
if profile
|
198
|
-
|
197
|
+
#if profile
|
198
|
+
if args = profiles[profile]
|
199
199
|
argv = Shellwords.shellwords(args)
|
200
200
|
opts.parse!(argv)
|
201
201
|
@files.concat(argv)
|
202
202
|
end
|
203
|
+
#end
|
203
204
|
|
204
205
|
options.each do |k,v|
|
205
206
|
__send__("#{k}=", v)
|
@@ -216,17 +217,9 @@ module QED
|
|
216
217
|
prepare_loadpath
|
217
218
|
|
218
219
|
require_libraries
|
219
|
-
|
220
|
+
require_profile
|
220
221
|
|
221
|
-
|
222
|
-
case format
|
223
|
-
when :script
|
224
|
-
demos.each do |spec|
|
225
|
-
puts spec.to_script
|
226
|
-
end
|
227
|
-
else
|
228
|
-
runner.check
|
229
|
-
end
|
222
|
+
session.run
|
230
223
|
end
|
231
224
|
|
232
225
|
# Profile configurations.
|
@@ -250,22 +243,40 @@ module QED
|
|
250
243
|
requires.each{ |file| require(file) }
|
251
244
|
end
|
252
245
|
|
253
|
-
# Require requirement file (from -e option.
|
246
|
+
# Require requirement file (from -e option).
|
254
247
|
|
255
|
-
def
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
248
|
+
def require_profile
|
249
|
+
return unless root
|
250
|
+
|
251
|
+
# common environment, always loaded if present.
|
252
|
+
#if file = Dir["#{root}/#{CONFDIR}/default.rb"].first
|
253
|
+
# require(file)
|
254
|
+
#end
|
255
|
+
|
256
|
+
#env = env() || 'default'
|
257
|
+
|
258
|
+
if file = Dir["#{root}/#{CONFDIR}/#{extension}.rb"].first
|
259
|
+
require(file)
|
266
260
|
end
|
267
261
|
end
|
268
262
|
|
263
|
+
#
|
264
|
+
def root
|
265
|
+
QED.root
|
266
|
+
end
|
267
|
+
|
268
|
+
end
|
269
|
+
|
270
|
+
# Is there no perfect way to find root directory of a project?
|
271
|
+
def self.root(path=nil)
|
272
|
+
path ||= Dir.pwd
|
273
|
+
path = File.dirname(path) unless File.directory?(path)
|
274
|
+
until path == File.dirname(path)
|
275
|
+
mark = Dir[File.join(path, 'README*')].first
|
276
|
+
return path if mark
|
277
|
+
path = File.dirname(path)
|
278
|
+
end
|
279
|
+
nil
|
269
280
|
end
|
270
281
|
|
271
282
|
end
|
data/lib/qed/config.rb
CHANGED
@@ -1,25 +1,60 @@
|
|
1
1
|
module QED
|
2
2
|
|
3
|
-
|
3
|
+
=begin
|
4
|
+
# Setup global configuration.
|
5
|
+
#
|
6
|
+
# QED.config do
|
7
|
+
#
|
8
|
+
# Before(:session) do
|
9
|
+
# # ...
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# After(:session) do
|
13
|
+
# # ...
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
def self.configure(&block)
|
19
|
+
@config ||= Profile.new #(nil)
|
20
|
+
@config.instance_eval(&block) if block
|
21
|
+
@config
|
22
|
+
end
|
23
|
+
=end
|
4
24
|
|
5
|
-
|
6
|
-
|
25
|
+
#
|
26
|
+
class Profile
|
7
27
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
28
|
+
#
|
29
|
+
def initialize
|
30
|
+
#@local = ['test/demos', 'demos', 'qed']
|
31
|
+
|
32
|
+
@before = { :session=>[], :demo=>[], :step=>[] }
|
33
|
+
@after = { :session=>[], :demo=>[], :step=>[] }
|
34
|
+
|
35
|
+
#if file = Dir.glob('{.,}config/qed.{yml,yaml}').first
|
36
|
+
# YAML.load(File.new(file)).each do |k,v|
|
37
|
+
# __send__("#{k}=", v)
|
38
|
+
# end
|
39
|
+
#end
|
13
40
|
end
|
14
41
|
|
15
|
-
|
42
|
+
#
|
43
|
+
#attr_accessor :local
|
16
44
|
|
17
|
-
#
|
18
|
-
|
45
|
+
#
|
46
|
+
def Before(type=:session, &procedure)
|
47
|
+
@before[type] << procedure if procedure
|
48
|
+
@before[type]
|
49
|
+
end
|
19
50
|
|
20
|
-
#
|
21
|
-
|
51
|
+
#
|
52
|
+
def After(type=:session, &procedure)
|
53
|
+
@after[type] << procedure if procedure
|
54
|
+
@after[type]
|
55
|
+
end
|
22
56
|
|
23
57
|
end
|
24
58
|
|
25
59
|
end
|
60
|
+
|