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
@@ -0,0 +1,61 @@
|
|
1
|
+
module QED
|
2
|
+
module Reporter #:nodoc:
|
3
|
+
|
4
|
+
require 'qed/reporter/base'
|
5
|
+
|
6
|
+
# = Html Reporter
|
7
|
+
#
|
8
|
+
class Html < BaseClass
|
9
|
+
|
10
|
+
#
|
11
|
+
def pass(step)
|
12
|
+
step['class'] = 'pass' # TODO add class not replace
|
13
|
+
step['style'] = 'color: green;' # TODO add style not replace
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
def fail(step, assertion)
|
18
|
+
step['class'] = 'fail' # TODO add class not replace
|
19
|
+
step['style'] = 'color: red;' # TODO add style not replace
|
20
|
+
|
21
|
+
msg = "\n"
|
22
|
+
msg << " ##### FAIL #####\n"
|
23
|
+
msg << " # " + assertion.to_s
|
24
|
+
msg << "\n"
|
25
|
+
|
26
|
+
step.add_child(Nokogiri::HTML.fragment(msg))
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
def error(step, exception)
|
31
|
+
raise exception if $DEBUG
|
32
|
+
|
33
|
+
step['class'] = 'error' # TODO add class not replace
|
34
|
+
step['style'] = 'color: red;' # TODO add style not replace
|
35
|
+
|
36
|
+
msg = "\n"
|
37
|
+
msg << " ##### ERROR #####\n"
|
38
|
+
msg << " # " + exception.to_s + "\n"
|
39
|
+
msg << " # " + exception.backtrace[0]
|
40
|
+
msg << "\n"
|
41
|
+
|
42
|
+
step.add_child(Nokogiri::HTML.fragment(msg))
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
def after_document(demo)
|
47
|
+
io.puts demo.document.to_s
|
48
|
+
end
|
49
|
+
|
50
|
+
#def report(str)
|
51
|
+
# count[-1] += 1 unless count.empty?
|
52
|
+
# str = str.chomp('.') + '.'
|
53
|
+
# str = count.join('.') + ' ' + str
|
54
|
+
# io.puts str.strip
|
55
|
+
#end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end#module Reporter
|
60
|
+
end#module QED
|
61
|
+
|
@@ -3,74 +3,60 @@ module Reporter #:nodoc:
|
|
3
3
|
|
4
4
|
require 'qed/reporter/base'
|
5
5
|
|
6
|
-
# =
|
6
|
+
# = Verbose ANSI Console Reporter
|
7
7
|
#
|
8
8
|
class Verbatim < BaseClass
|
9
9
|
|
10
|
-
#def report_step(step)
|
11
|
-
# super
|
12
|
-
# if step.code
|
13
|
-
# #str = "(%s) %s" % [count.join('.'), str.tab(6).strip]
|
14
|
-
# #io.puts "* #{step.to_s.tab(2).strip}"
|
15
|
-
# #io.puts
|
16
|
-
# #io.puts step.to_s
|
17
|
-
# #io.puts
|
18
|
-
# else
|
19
|
-
# #io.puts "#{step}\n" # TODO: This never happens.
|
20
|
-
# end
|
21
|
-
#end
|
22
|
-
|
23
|
-
#def report_intro
|
24
|
-
# io.puts
|
25
|
-
#end
|
26
|
-
|
27
|
-
def report_header(step)
|
28
|
-
io.print ANSICode.bold("#{step}")
|
29
|
-
end
|
30
|
-
|
31
|
-
def report_comment(step)
|
32
|
-
io.print step
|
33
|
-
end
|
34
|
-
|
35
10
|
#
|
36
|
-
def
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
11
|
+
def tag(element)
|
12
|
+
case element.name
|
13
|
+
when 'pre'
|
14
|
+
# none
|
15
|
+
when /h\d/
|
16
|
+
io.print ANSI::Code.bold("#{element.text.strip}\n\n")
|
17
|
+
when 'p'
|
18
|
+
io.print "#{element.text.strip}\n\n"
|
19
|
+
#when 'a'
|
20
|
+
# io.print element.to_s
|
21
|
+
when 'ul', 'ol'
|
22
|
+
io.print "\n"
|
23
|
+
when 'li'
|
24
|
+
io.print "* #{element.text.strip}\n"
|
25
|
+
end
|
41
26
|
end
|
42
27
|
|
43
28
|
#
|
44
|
-
def
|
45
|
-
|
29
|
+
def pass(step)
|
30
|
+
txt = step.text.rstrip.sub("\n",'')
|
31
|
+
io.print ANSI::Code.green("#{txt}\n\n")
|
46
32
|
end
|
47
33
|
|
48
|
-
|
49
|
-
|
50
|
-
|
34
|
+
#
|
35
|
+
def fail(step, error)
|
36
|
+
txt = step.text.rstrip.sub("\n",'')
|
37
|
+
tab = step.text.index(/\S/) - 1
|
38
|
+
io.print ANSI::Code.red("#{txt}\n\n")
|
51
39
|
msg = []
|
52
|
-
msg <<
|
53
|
-
msg <<
|
40
|
+
msg << ANSI::Code.bold(ANSI::Code.red("FAIL: ")) + error.to_str
|
41
|
+
msg << ANSI::Code.bold(clean_backtrace(error.backtrace[0]))
|
54
42
|
io.puts msg.join("\n").tabto(tab||2)
|
55
43
|
io.puts
|
56
44
|
end
|
57
45
|
|
58
|
-
|
46
|
+
#
|
47
|
+
def error(step, error)
|
59
48
|
raise error if $DEBUG
|
60
|
-
|
61
|
-
|
49
|
+
txt = step.text.rstrip.sub("\n",'')
|
50
|
+
tab = step.text.index(/\S/) - 1
|
51
|
+
io.print ANSI::Code.red("#{txt}\n\n")
|
62
52
|
msg = []
|
63
|
-
msg <<
|
64
|
-
msg <<
|
53
|
+
msg << ANSI::Code.bold(ANSI::Code.red("ERROR: ")) + error.to_str.sub(/for QED::Context.*?$/,'')
|
54
|
+
msg << ANSI::Code.bold(clean_backtrace(error.backtrace[0]))
|
65
55
|
#msg = ANSICode.red(msg)
|
66
56
|
io.puts msg.join("\n").tabto(tab||2)
|
67
57
|
io.puts
|
68
58
|
end
|
69
59
|
|
70
|
-
def report_step_end(step)
|
71
|
-
io.puts
|
72
|
-
end
|
73
|
-
|
74
60
|
#def report(str)
|
75
61
|
# count[-1] += 1 unless count.empty?
|
76
62
|
# str = str.chomp('.') + '.'
|
@@ -82,6 +68,14 @@ module Reporter #:nodoc:
|
|
82
68
|
# puts ANSICode.magenta(set.to_yaml.tabto(2))
|
83
69
|
#end
|
84
70
|
|
71
|
+
#
|
72
|
+
#def macro(step)
|
73
|
+
# #io.puts
|
74
|
+
# #io.puts step.text
|
75
|
+
# io.print ANSICode.magenta("#{step}")
|
76
|
+
# #io.puts
|
77
|
+
#end
|
78
|
+
|
85
79
|
end
|
86
80
|
|
87
81
|
end #module Reporter
|
data/lib/qed/scope.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
module QED
|
2
|
+
|
3
|
+
require 'ae'
|
4
|
+
require 'qed/advice'
|
5
|
+
|
6
|
+
#--
|
7
|
+
# TODO: Replace Scope for TOPLEVEL?
|
8
|
+
#++
|
9
|
+
class Scope
|
10
|
+
|
11
|
+
include Advisable
|
12
|
+
|
13
|
+
def __binding__
|
14
|
+
@__binding__ ||= binding
|
15
|
+
end
|
16
|
+
|
17
|
+
# Table-based steps.
|
18
|
+
#--
|
19
|
+
# TODO: Utilize HTML table element for tables.
|
20
|
+
#++
|
21
|
+
def Table(file=nil, &blk)
|
22
|
+
file = file || @_tables.last
|
23
|
+
tbl = YAML.load(File.new(file))
|
24
|
+
tbl.each do |set|
|
25
|
+
blk.call(*set)
|
26
|
+
end
|
27
|
+
@__tables__ ||= []
|
28
|
+
@__tables__ << file
|
29
|
+
end
|
30
|
+
|
31
|
+
# Read/Write a static data fixture.
|
32
|
+
#--
|
33
|
+
# TODO: Perhaps #Data would be best as some sort of Kernel extension.
|
34
|
+
#++
|
35
|
+
def Data(file, &content)
|
36
|
+
raise if File.directory?(file)
|
37
|
+
if content
|
38
|
+
FileUtils.mkdir_p(File.dirname(fname))
|
39
|
+
case File.extname(file)
|
40
|
+
when '.yml', '.yaml'
|
41
|
+
File.open(file, 'w'){ |f| f << content.call.to_yaml }
|
42
|
+
else
|
43
|
+
File.open(file, 'w'){ |f| f << content.call }
|
44
|
+
end
|
45
|
+
else
|
46
|
+
#raise LoadError, "no such fixture file -- #{fname}" unless File.exist?(fname)
|
47
|
+
case File.extname(file)
|
48
|
+
when '.yml', '.yaml'
|
49
|
+
YAML.load(File.new(file))
|
50
|
+
else
|
51
|
+
File.read(file)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Code match-and-transform procedure.
|
57
|
+
#
|
58
|
+
# This is useful to transform human readable code examples
|
59
|
+
# into proper exectuable code. For example, say you want to
|
60
|
+
# run shell code, but want to make if look like typical
|
61
|
+
# shelle examples:
|
62
|
+
#
|
63
|
+
# $ cp fixture/a.rb fixture/b.rb
|
64
|
+
#
|
65
|
+
# You can use a transform to convert lines starting with '$'
|
66
|
+
# into executable Ruby using #system.
|
67
|
+
#
|
68
|
+
# system('cp fixture/a.rb fixture/b.rb')
|
69
|
+
#
|
70
|
+
#def Transform(pattern=nil, &procedure)
|
71
|
+
#
|
72
|
+
#end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
data/lib/qed/script.rb
CHANGED
@@ -1,449 +1,116 @@
|
|
1
1
|
module QED
|
2
2
|
require 'yaml'
|
3
|
-
require '
|
3
|
+
require 'tilt'
|
4
|
+
require 'nokogiri'
|
4
5
|
|
5
|
-
require '
|
6
|
+
require 'facets/dir/ascend'
|
6
7
|
|
7
|
-
require 'qed/
|
8
|
-
require 'qed/reporter/summary'
|
9
|
-
require 'qed/reporter/verbatim'
|
8
|
+
require 'qed/evaluator'
|
10
9
|
|
11
10
|
#Assertion = AE::Assertion
|
12
|
-
Expectation = Assertor
|
13
|
-
|
14
|
-
# Global Before
|
15
|
-
def self.Before(&procedure)
|
16
|
-
@_before = procedure if procedure
|
17
|
-
@_before
|
18
|
-
end
|
19
|
-
|
20
|
-
# Global After
|
21
|
-
def self.After(&procedure)
|
22
|
-
@_after = procedure if procedure
|
23
|
-
@_after
|
24
|
-
end
|
25
|
-
|
26
|
-
# New Specification
|
27
|
-
#def initialize(specs, output=nil)
|
28
|
-
# @specs = [specs].flatten
|
29
|
-
#end
|
11
|
+
# Expectation = Assertor
|
30
12
|
|
31
13
|
# = Script
|
32
14
|
#
|
15
|
+
# When run current working directory is changed to that of
|
16
|
+
# the demonstration script's. So any relative file references
|
17
|
+
# within a demo must take that into account.
|
18
|
+
#
|
33
19
|
class Script
|
34
20
|
|
35
|
-
#
|
36
|
-
# new(File.read(file), output)
|
37
|
-
#end
|
38
|
-
|
39
|
-
# Path of demonstration script.
|
21
|
+
# Demonstration file.
|
40
22
|
attr :file
|
41
23
|
|
42
|
-
#
|
43
|
-
attr :
|
44
|
-
|
45
|
-
# List of helper scripts to require.
|
46
|
-
attr :helpers
|
47
|
-
|
48
|
-
# New Script
|
49
|
-
def initialize(file, output=nil)
|
50
|
-
@file = file
|
51
|
-
@output = output || Reporter::Verbatim.new #(self)
|
52
|
-
parse_document(file)
|
53
|
-
end
|
54
|
-
|
55
|
-
# File basename less extension.
|
56
|
-
def name
|
57
|
-
@name ||= File.basename(file).chomp(File.extname(file))
|
58
|
-
end
|
59
|
-
|
60
|
-
#
|
61
|
-
def directory
|
62
|
-
@directory ||= Dir.pwd #File.dirname(File.expand_path(file))
|
63
|
-
end
|
64
|
-
|
65
|
-
#def convert
|
66
|
-
# @source.gsub(/^\w/, '# \1')
|
67
|
-
#end
|
68
|
-
|
69
|
-
# Run the script.
|
70
|
-
def run
|
71
|
-
@lineno = 0
|
24
|
+
# Expanded dirname of +file+.
|
25
|
+
attr :dir
|
72
26
|
|
73
|
-
$LOAD_PATH.unshift(directory)
|
74
|
-
|
75
|
-
import_helpers
|
76
|
-
|
77
|
-
steps.each do |step|
|
78
|
-
output.report_step(step)
|
79
|
-
case step
|
80
|
-
when /^[=#]/
|
81
|
-
output.report_header(step)
|
82
|
-
when /^\S/
|
83
|
-
output.report_comment(step)
|
84
|
-
context.When.each do |(regex, proc)|
|
85
|
-
if md = regex.match(step)
|
86
|
-
proc.call(*md[1..-1])
|
87
|
-
end
|
88
|
-
end
|
89
|
-
else
|
90
|
-
#if context.table
|
91
|
-
# run_table(step)
|
92
|
-
#else
|
93
|
-
run_step(step)
|
94
|
-
#end
|
95
|
-
end
|
96
|
-
@lineno += step.count("\n")
|
97
|
-
end
|
98
|
-
|
99
|
-
$LOAD_PATH.index(directory){ |i| $LOAD_PATH.delete_at(i) }
|
100
|
-
end
|
101
|
-
|
102
|
-
#--
|
103
|
-
# NOTE: The Around code is in place should we decide
|
104
|
-
# to use it. I'm not sure yet if it's really neccessary,
|
105
|
-
# since we have Before and After.
|
106
|
-
#++
|
107
|
-
def run_step(step=nil, &blk)
|
108
|
-
QED.Before.call if QED.Before
|
109
|
-
context.Before.call if context.Before
|
110
|
-
begin
|
111
|
-
if blk # TODO: Is this still used?
|
112
|
-
blk.call #eval(step, context._binding)
|
113
|
-
else
|
114
|
-
#if context.Around
|
115
|
-
# context.Around.call do
|
116
|
-
# eval(step, context._binding, @file, @lineno+1)
|
117
|
-
# end
|
118
|
-
#else
|
119
|
-
eval(step, context._binding, @file, @lineno+1)
|
120
|
-
#end
|
121
|
-
end
|
122
|
-
output.report_pass(step) if step
|
123
|
-
rescue Assertion => error
|
124
|
-
output.report_fail(step, error)
|
125
|
-
rescue Exception => error
|
126
|
-
output.report_error(step, error)
|
127
|
-
ensure
|
128
|
-
context.After.call if context.After
|
129
|
-
QED.After.call if QED.After
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
=begin
|
134
27
|
#
|
135
|
-
|
136
|
-
file = context.table
|
137
|
-
Dir.ascend(Dir.pwd) do |path|
|
138
|
-
f1 = File.join(path, file)
|
139
|
-
f2 = File.join(path, 'fixtures', file)
|
140
|
-
fr = File.file?(f1) ? f1 : File.exist?(f2) ? f2 : nil
|
141
|
-
(file = fr; break) if fr
|
142
|
-
end
|
143
|
-
output.report_pass(step) #step)
|
144
|
-
|
145
|
-
tbl = YAML.load(File.new(file))
|
146
|
-
key = tbl.shift
|
147
|
-
tbl.each do |set|
|
148
|
-
assign = key.zip(set).map{ |k, v| "#{k}=#{v.inspect};" }.join
|
149
|
-
run_table_step(assign + step, set)
|
150
|
-
#run_step(set.inspect.tabto(4)){ blk.call(set) }
|
151
|
-
#@_script.run_step(set.to_yaml.tabto(2)){ blk.call(set) }
|
152
|
-
#@_script.output.report_table(set)
|
153
|
-
end
|
154
|
-
#output.report_pass(step) #step)
|
155
|
-
context.table = nil
|
156
|
-
end
|
157
|
-
|
158
|
-
#
|
159
|
-
#def run_table_step(step, set)
|
160
|
-
def run_table_step(set, &blk)
|
161
|
-
context.before.call if context.before
|
162
|
-
begin
|
163
|
-
#eval(step, context._binding, @file) # TODO: would be nice to know file and lineno here
|
164
|
-
blk.call(*set)
|
165
|
-
output.report_pass(' ' + set.inspect) #step)
|
166
|
-
rescue Assertion => error
|
167
|
-
output.report_fail(set.inspect, error)
|
168
|
-
rescue Exception => error
|
169
|
-
output.report_error(set.inspect, error)
|
170
|
-
ensure
|
171
|
-
context.after.call if context.after
|
172
|
-
end
|
173
|
-
end
|
174
|
-
=end
|
175
|
-
|
176
|
-
# Cut-up script into steps.
|
177
|
-
def steps
|
178
|
-
@steps ||= (
|
179
|
-
code = false
|
180
|
-
str = ''
|
181
|
-
steps = []
|
182
|
-
@source.each_line do |line|
|
183
|
-
if /^\s*$/.match line
|
184
|
-
str << line
|
185
|
-
elsif /^[=]/.match line
|
186
|
-
steps << str #.chomp("\n")
|
187
|
-
steps << line #.chomp("\n")
|
188
|
-
str = ''
|
189
|
-
#str << line
|
190
|
-
code = false
|
191
|
-
elsif /^\S/.match line
|
192
|
-
if code
|
193
|
-
steps << str #.chomp("\n")
|
194
|
-
str = ''
|
195
|
-
str << line
|
196
|
-
code = false
|
197
|
-
else
|
198
|
-
str << line
|
199
|
-
end
|
200
|
-
else
|
201
|
-
if code
|
202
|
-
str << line
|
203
|
-
else
|
204
|
-
steps << str
|
205
|
-
str = ''
|
206
|
-
str << line
|
207
|
-
code = true
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|
211
|
-
steps << str
|
212
|
-
#steps.map{ |s| s.chomp("\n") }
|
213
|
-
steps
|
214
|
-
)
|
215
|
-
end
|
28
|
+
attr :scope
|
216
29
|
|
217
|
-
#
|
218
|
-
def
|
219
|
-
@
|
30
|
+
# New Script
|
31
|
+
def initialize(file, scope=nil)
|
32
|
+
@file = file
|
33
|
+
@scope = scope || Scope.new
|
34
|
+
apply_environment
|
220
35
|
end
|
221
36
|
|
222
37
|
#
|
223
|
-
def
|
224
|
-
|
225
|
-
eval(code, context._binding)
|
38
|
+
def dir
|
39
|
+
@dir ||= File.expand_path(File.dirname(file))
|
226
40
|
end
|
227
41
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
# and extract the helper document references from
|
232
|
-
# the footer.
|
233
|
-
#
|
234
|
-
def parse_document(file)
|
235
|
-
text = File.read(file)
|
236
|
-
index = text.rindex('---') || text.size
|
237
|
-
source = text[0...index]
|
238
|
-
footer = text[index+3..-1].to_s.strip
|
239
|
-
helpers = parse_helpers(footer)
|
240
|
-
@source = source
|
241
|
-
@helpers = helpers
|
42
|
+
# File basename less extension.
|
43
|
+
def name
|
44
|
+
@name ||= File.basename(file).chomp(File.extname(file))
|
242
45
|
end
|
243
46
|
|
244
|
-
#
|
245
|
-
def
|
246
|
-
|
247
|
-
footer.split("\n").each do |line|
|
248
|
-
next if line.strip == ''
|
249
|
-
case line
|
250
|
-
when /\[(.*?)\]\((.*?)\)/
|
251
|
-
helpers << $2
|
252
|
-
when /(.*?)\[(.*?)\]/
|
253
|
-
helpers << $2
|
254
|
-
end
|
255
|
-
end
|
256
|
-
helpers
|
47
|
+
# Nokogiri HTML document.
|
48
|
+
def document
|
49
|
+
@document ||= Nokogiri::HTML(to_html)
|
257
50
|
end
|
258
51
|
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
# be imported when this script is run.
|
263
|
-
|
264
|
-
def collect_helpers
|
265
|
-
dir = File.dirname(file)
|
266
|
-
list = []
|
267
|
-
list << "helper.rb" if File.exist?(File.join(dir, "helper.rb"))
|
268
|
-
list << "helpers/#{name}.rb" if File.exist?(File.join(dir, "helpers/#{name}.rb"))
|
269
|
-
list
|
52
|
+
# Root node of the html document.
|
53
|
+
def root
|
54
|
+
document.root
|
270
55
|
end
|
271
|
-
=end
|
272
|
-
|
273
|
-
# TODO: How to determine where to find the env.rb file?
|
274
|
-
#def require_environment
|
275
|
-
# dir = File.dirname(file)
|
276
|
-
# dir = File.expand_path(dir)
|
277
|
-
# env = loop do
|
278
|
-
# file = File.join(dir, 'env.rb')
|
279
|
-
# break file if File.exist?(file)
|
280
|
-
# break nil if ['demo', 'demos', 'doc', 'docs', 'test', 'tests'].include? File.basename(dir)
|
281
|
-
# break nil if dir == Dir.pwd
|
282
|
-
# dir = File.dirname(dir)
|
283
|
-
# end
|
284
|
-
# require(env) if env
|
285
|
-
#end
|
286
56
|
|
287
|
-
#
|
288
|
-
def
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
dir = File.dirname(dir)
|
57
|
+
# Open file and translate template into HTML text.
|
58
|
+
def to_html
|
59
|
+
#case file
|
60
|
+
#when /^http/
|
61
|
+
# ext = File.extname(file).sub('.','')
|
62
|
+
# Tilt[ext].new{ source }
|
63
|
+
#else
|
64
|
+
#end
|
65
|
+
if File.extname(file) == '.html'
|
66
|
+
File.read(file)
|
67
|
+
else
|
68
|
+
Tilt.new(file).render
|
300
69
|
end
|
301
|
-
hlp.each{ |helper| import(helper) }
|
302
|
-
end
|
303
|
-
|
304
|
-
end
|
305
|
-
|
306
|
-
#
|
307
|
-
class Context < Module
|
308
|
-
|
309
|
-
TABLE = /^TABLE\[(.*?)\]/i
|
310
|
-
|
311
|
-
def initialize(script)
|
312
|
-
@_script = script
|
313
|
-
@_when = []
|
314
|
-
@_tables = []
|
315
|
-
end
|
316
|
-
|
317
|
-
def _binding
|
318
|
-
@_binding ||= binding
|
319
|
-
end
|
320
|
-
|
321
|
-
# Before each step.
|
322
|
-
def Before(&procedure)
|
323
|
-
@_before = procedure if procedure
|
324
|
-
@_before
|
325
70
|
end
|
326
71
|
|
327
|
-
#
|
328
|
-
def
|
329
|
-
@
|
330
|
-
@_after
|
72
|
+
# Open, convert to HTML and cache.
|
73
|
+
def html
|
74
|
+
@html ||= to_html
|
331
75
|
end
|
332
76
|
|
333
|
-
# Run code around each step.
|
334
77
|
#
|
335
|
-
#
|
336
|
-
#
|
337
|
-
#
|
338
|
-
#
|
339
|
-
#
|
340
|
-
#
|
341
|
-
#
|
342
|
-
#
|
343
|
-
#
|
344
|
-
#
|
345
|
-
# @_around
|
78
|
+
#def source
|
79
|
+
# @source ||= (
|
80
|
+
# #case file
|
81
|
+
# #when /^http/
|
82
|
+
# # ext = File.extname(file).sub('.','')
|
83
|
+
# # open(file)
|
84
|
+
# #else
|
85
|
+
# File.read(file)
|
86
|
+
# #end
|
87
|
+
# )
|
346
88
|
#end
|
347
89
|
|
348
|
-
# Comment match procedure.
|
349
90
|
#
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
# triggered, passing in any mathcing expression arguments.
|
354
|
-
#
|
355
|
-
def When(pattern=nil, &procedure)
|
356
|
-
return @_when unless procedure
|
357
|
-
raise ArgumentError unless pattern
|
358
|
-
unless Regexp === pattern
|
359
|
-
pattern = __when_string_to_regexp(pattern)
|
360
|
-
end
|
361
|
-
@_when << [pattern, procedure]
|
91
|
+
def run(*observers)
|
92
|
+
evaluator = Evaluator.new(self, *observers)
|
93
|
+
evaluator.run
|
362
94
|
end
|
363
95
|
|
364
|
-
# Code match-and-transform procedure.
|
365
|
-
#
|
366
|
-
# This is useful to transform human readable code examples
|
367
|
-
# into proper exectuable code. For example, say you want to
|
368
|
-
# run shell code, but want to make if look like typical
|
369
|
-
# shelle examples:
|
370
|
-
#
|
371
|
-
# $ cp fixture/a.rb fixture/b.rb
|
372
|
-
#
|
373
|
-
# You can use a transform to convert lines starting with '$'
|
374
|
-
# into executable Ruby using #system.
|
375
96
|
#
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
#
|
380
|
-
#end
|
381
|
-
|
382
|
-
# Table-based steps.
|
383
|
-
def Table(file=nil, &blk)
|
384
|
-
file = file || @_tables.last
|
385
|
-
tbl = YAML.load(File.new(file))
|
386
|
-
tbl.each do |set|
|
387
|
-
blk.call(*set)
|
388
|
-
end
|
389
|
-
@_tables << file
|
97
|
+
def environment
|
98
|
+
glob = File.join(dir, '{environment,common,shared}', '*')
|
99
|
+
Dir[glob]
|
390
100
|
end
|
391
101
|
|
392
|
-
#
|
393
|
-
def
|
394
|
-
|
395
|
-
if content
|
396
|
-
FileUtils.mkdir_p(File.dirname(fname))
|
397
|
-
case File.extname(file)
|
398
|
-
when '.yml', '.yaml'
|
399
|
-
File.open(file, 'w'){ |f| f << content.call.to_yaml }
|
400
|
-
else
|
401
|
-
File.open(file, 'w'){ |f| f << content.call }
|
402
|
-
end
|
403
|
-
else
|
404
|
-
#raise LoadError, "no such fixture file -- #{fname}" unless File.exist?(fname)
|
102
|
+
#
|
103
|
+
def apply_environment
|
104
|
+
environment.each do |file|
|
405
105
|
case File.extname(file)
|
406
|
-
when '.
|
407
|
-
|
106
|
+
when '.rb'
|
107
|
+
eval(File.read(file), scope.__binding__, file)
|
408
108
|
else
|
409
|
-
|
109
|
+
Script.new(file, scope).run
|
410
110
|
end
|
411
111
|
end
|
412
112
|
end
|
413
113
|
|
414
|
-
private
|
415
|
-
|
416
|
-
def __when_string_to_regexp(str)
|
417
|
-
str = str.split(/(\(\(.*?\)\))(?!\))/).map{ |x|
|
418
|
-
x =~ /\A\(\((.*)\)\)\z/ ? $1 : Regexp.escape(x)
|
419
|
-
}.join
|
420
|
-
str = str.gsub(/(\\\ )+/, '\s+')
|
421
|
-
Regexp.new(str, Regexp::IGNORECASE)
|
422
|
-
|
423
|
-
#rexps = []
|
424
|
-
#str = str.gsub(/\(\((.*?)\)\)/) do |m|
|
425
|
-
# rexps << '(' + $1 + ')'
|
426
|
-
# "\0"
|
427
|
-
#end
|
428
|
-
#str = Regexp.escape(str)
|
429
|
-
#rexps.each do |r|
|
430
|
-
# str = str.sub("\0", r)
|
431
|
-
#end
|
432
|
-
#str = str.gsub(/(\\\ )+/, '\s+')
|
433
|
-
#Regexp.new(str, Regexp::IGNORECASE)
|
434
|
-
end
|
435
|
-
|
436
|
-
#
|
437
|
-
# check only local and maybe start paths
|
438
|
-
#def __locate_file(file)
|
439
|
-
# Dir.ascend(Dir.pwd) do |path|
|
440
|
-
# f1 = File.join(path, file)
|
441
|
-
# f2 = File.join(path, 'fixtures', file)
|
442
|
-
# fr = File.file?(f1) ? f1 : File.exist?(f2) ? f2 : nil
|
443
|
-
# (file = fr; break) if fr
|
444
|
-
# end
|
445
|
-
#end
|
446
|
-
|
447
114
|
end
|
448
115
|
|
449
116
|
end
|