qed 2.3.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +15 -0
- data/eg/hello_world.rdoc +15 -0
- data/eg/view_error.rdoc +21 -0
- data/eg/website.rdoc +12 -0
- data/lib/qed/advice.rb +4 -3
- data/lib/qed/command.rb +2 -3
- data/lib/qed/core_ext/instance_exec.rb +36 -0
- data/lib/qed/demo.rb +0 -1
- data/lib/qed/evaluator.rb +75 -36
- data/lib/qed/extensions/filefixtures.rb +27 -0
- data/lib/qed/extensions/shell_session.rb +2 -0
- data/lib/qed/meta/data.rb +29 -0
- data/lib/qed/meta/gemfile +10 -0
- data/{PROFILE → lib/qed/meta/profile} +0 -0
- data/lib/qed/parser.rb +148 -74
- data/lib/qed/reporter/abstract.rb +175 -25
- data/lib/qed/reporter/bullet.rb +14 -10
- data/lib/qed/reporter/dotprogress.rb +26 -9
- data/lib/qed/reporter/verbatim.rb +36 -15
- data/lib/qed/scope.rb +18 -8
- data/lib/qed/session.rb +2 -2
- data/meta/data.rb +29 -0
- data/meta/gemfile +10 -0
- data/{lib/qed/profile.yml → meta/profile} +0 -0
- data/{demo → qed}/01_demos.rdoc +7 -13
- data/{demo → qed}/02_advice.rdoc +7 -7
- data/{demo → qed}/03_helpers.rdoc +2 -2
- data/{demo → qed}/04_samples.rdoc +0 -0
- data/{demo → qed}/05_quote.rdoc +0 -0
- data/{demo → qed}/07_toplevel.rdoc +0 -0
- data/{demo → qed}/08_cross_script.rdoc +0 -2
- data/{demo → qed}/09_cross_script.rdoc +5 -3
- data/{demo → qed}/10_constant_lookup.rdoc +0 -0
- data/{demo → qed}/applique/constant.rb +0 -0
- data/{demo → qed}/applique/env.rb +0 -0
- data/{demo → qed}/applique/fileutils.rb +0 -0
- data/{demo → qed}/applique/markup.rb +0 -0
- data/{demo → qed}/applique/quote.rb +0 -0
- data/{demo → qed}/applique/toplevel.rb +0 -0
- data/{demo → qed}/helpers/advice.rb +0 -0
- data/{demo → qed}/helpers/sample.rb +0 -0
- data/{demo → qed}/helpers/toplevel.rb +0 -0
- data/{demo → qed}/samples/data.txt +0 -0
- data/{demo → qed}/samples/table.yml +0 -0
- metadata +43 -38
- data/REQUIRE +0 -7
- data/VERSION +0 -5
- data/lib/qed/package.yml +0 -5
- data/script/qedoc +0 -2
- data/script/test +0 -4
data/History.rdoc
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
= RELEASE HISTORY
|
2
2
|
|
3
|
+
== 2.4.0 / 2010-09-02
|
4
|
+
|
5
|
+
All engines go! QED has not been tested against 1.8.6, 1.8.7 and 1.9.2.
|
6
|
+
Underthehood steps are not organized in doubely-linked lists, which makes
|
7
|
+
them much more robust and flexible. This release also improves scoping,
|
8
|
+
test counts, and inline documentation parsing.
|
9
|
+
|
10
|
+
Changes:
|
11
|
+
|
12
|
+
* Use new doubly-linked list step design.
|
13
|
+
* Fix -r option on command line.
|
14
|
+
* Provide #instance_exec core extension for Ruby 1.8.6.
|
15
|
+
* Scope is extended by and includes applique.
|
16
|
+
|
17
|
+
|
3
18
|
== 2.3.0 / 2010-07-14
|
4
19
|
|
5
20
|
Bug to the scurry! QED has broken through the code/document ceiling and
|
data/eg/hello_world.rdoc
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
= Hello World
|
2
|
+
|
3
|
+
Did you know that famous `Hello World` moniker is
|
4
|
+
eleven characters long?
|
5
|
+
|
6
|
+
"Hello World".size.assert == 11
|
7
|
+
|
8
|
+
To pass a piece of literal text on with a description
|
9
|
+
we simply need to end it with a ...
|
10
|
+
|
11
|
+
Now this text will appear verbatim.
|
12
|
+
In the applique arguments.
|
13
|
+
|
14
|
+
That's all.
|
15
|
+
|
data/eg/view_error.rdoc
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
= Examples of Failure
|
2
|
+
|
3
|
+
This document is here simply to demonstrate what
|
4
|
+
a failed and error raising code steps looks like.
|
5
|
+
|
6
|
+
When run with the -v (verbatim) option, for instance, +qed+
|
7
|
+
will highlight the following sections in red and give a brief
|
8
|
+
error message.
|
9
|
+
|
10
|
+
== Failure
|
11
|
+
|
12
|
+
This step demonstrates a failed assertion.
|
13
|
+
|
14
|
+
1.assert == 2
|
15
|
+
|
16
|
+
== Error
|
17
|
+
|
18
|
+
This step demonstrates a raised error.
|
19
|
+
|
20
|
+
raise "Just because"
|
21
|
+
|
data/eg/website.rdoc
ADDED
data/lib/qed/advice.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'qed/core_ext/instance_exec'
|
2
|
+
|
1
3
|
module QED
|
2
4
|
|
3
5
|
# = Advice
|
@@ -12,8 +14,7 @@ module QED
|
|
12
14
|
#
|
13
15
|
# == Pattern Matchers (When)
|
14
16
|
#
|
15
|
-
# Matchers are evaluated when they match a
|
16
|
-
# commentary.
|
17
|
+
# Matchers are evaluated when they match a description.
|
17
18
|
#
|
18
19
|
# == Event Signals (Before, After)
|
19
20
|
#
|
@@ -67,7 +68,7 @@ module QED
|
|
67
68
|
|
68
69
|
#
|
69
70
|
def call_matchers(scope, section)
|
70
|
-
match = section.
|
71
|
+
match = section.text
|
71
72
|
args = section.arguments
|
72
73
|
matchers.each do |(patterns, proc)|
|
73
74
|
compare = match
|
data/lib/qed/command.rb
CHANGED
@@ -134,7 +134,7 @@ module QED
|
|
134
134
|
@options[:loadpath] ||= []
|
135
135
|
@options[:loadpath].concat(arg.split(/[:;]/).map{ |dir| File.expand_path(dir) })
|
136
136
|
end
|
137
|
-
opt.on('--require', "-r", "require library") do |arg|
|
137
|
+
opt.on('--require', "-r LIB", "require library") do |arg|
|
138
138
|
@options[:requires] ||= []
|
139
139
|
@options[:requires].concat(arg.split(/[:;]/)) #.map{ |dir| File.expand_path(dir) })
|
140
140
|
end
|
@@ -207,7 +207,7 @@ module QED
|
|
207
207
|
end
|
208
208
|
end
|
209
209
|
files = files.flatten.uniq
|
210
|
-
files.map{|f| File.expand_path(f) }.sort
|
210
|
+
files.map{|f| File.expand_path(f) }.uniq.sort
|
211
211
|
end
|
212
212
|
|
213
213
|
# Parse command-line options along with profile options.
|
@@ -349,4 +349,3 @@ module QED
|
|
349
349
|
end
|
350
350
|
|
351
351
|
end
|
352
|
-
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class Object
|
2
|
+
|
3
|
+
unless method_defined?(:instance_exec) # 1.9
|
4
|
+
require 'thread'
|
5
|
+
|
6
|
+
module InstanceExecMethods #:nodoc:
|
7
|
+
end
|
8
|
+
|
9
|
+
include InstanceExecMethods
|
10
|
+
|
11
|
+
# Evaluate the block with the given arguments within the context of
|
12
|
+
# this object, so self is set to the method receiver.
|
13
|
+
#
|
14
|
+
# From Mauricio's http://eigenclass.org/hiki/bounded+space+instance_exec
|
15
|
+
#
|
16
|
+
# This version has been borrowed from Rails for compatibility sake.
|
17
|
+
def instance_exec(*args, &block)
|
18
|
+
begin
|
19
|
+
old_critical, Thread.critical = Thread.critical, true
|
20
|
+
n = 0
|
21
|
+
n += 1 while respond_to?(method_name = "__instance_exec#{n}")
|
22
|
+
InstanceExecMethods.module_eval { define_method(method_name, &block) }
|
23
|
+
ensure
|
24
|
+
Thread.critical = old_critical
|
25
|
+
end
|
26
|
+
|
27
|
+
begin
|
28
|
+
send(method_name, *args)
|
29
|
+
ensure
|
30
|
+
InstanceExecMethods.module_eval { remove_method(method_name) } rescue nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
data/lib/qed/demo.rb
CHANGED
data/lib/qed/evaluator.rb
CHANGED
@@ -8,7 +8,7 @@ module QED
|
|
8
8
|
#
|
9
9
|
def initialize(script, *observers)
|
10
10
|
@script = script
|
11
|
-
@
|
11
|
+
@steps = script.parse
|
12
12
|
|
13
13
|
#@file = script.file
|
14
14
|
#@scope = script.scope
|
@@ -21,46 +21,85 @@ module QED
|
|
21
21
|
#
|
22
22
|
def run
|
23
23
|
advise!(:before_demo, @script)
|
24
|
-
|
24
|
+
advise!(:demo, @script)
|
25
|
+
run_steps
|
25
26
|
advise!(:after_demo, @script)
|
26
27
|
end
|
27
28
|
|
28
29
|
#
|
29
|
-
def process
|
30
|
-
@
|
31
|
-
evaluate(
|
30
|
+
def run_steps #process
|
31
|
+
@steps.each do |step|
|
32
|
+
evaluate(step)
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
35
|
-
#
|
36
|
-
def evaluate(
|
37
|
-
|
38
|
-
|
39
|
-
advise!(
|
36
|
+
#
|
37
|
+
def evaluate(step)
|
38
|
+
type = step.type
|
39
|
+
advise!(:before_step, step) #, @script.file)
|
40
|
+
advise!("before_#{type}".to_sym, step) #, @script.file)
|
41
|
+
case type
|
42
|
+
when :head
|
43
|
+
evaluate_head(step)
|
44
|
+
when :desc
|
45
|
+
evaluate_desc(step)
|
46
|
+
when :data
|
47
|
+
evaluate_data(step)
|
48
|
+
when :code
|
49
|
+
evaluate_code(step)
|
50
|
+
else
|
51
|
+
raise "fatal: unknown #{type}"
|
52
|
+
end
|
53
|
+
advise!("after_#{type}".to_sym, step) #, @script.file)
|
54
|
+
advise!(:after_step, step) #, @script.file)
|
55
|
+
end
|
56
|
+
|
57
|
+
#
|
58
|
+
def evaluate_head(step)
|
59
|
+
advise!(:head, step)
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
def evaluate_desc(step)
|
64
|
+
evaluate_links(step)
|
40
65
|
begin
|
41
|
-
advise!(:
|
42
|
-
|
66
|
+
advise!(:desc, step)
|
67
|
+
advise!(:when, step) # triggers matchers
|
68
|
+
rescue SystemExit
|
69
|
+
pass!(step)
|
70
|
+
rescue Assertion => exception
|
71
|
+
fail!(step, exception)
|
72
|
+
rescue Exception => exception
|
73
|
+
error!(step, exception)
|
74
|
+
else
|
75
|
+
pass!(step)
|
43
76
|
end
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
def evaluate_data(step)
|
81
|
+
advise!(:data, step)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Evaluate a demo step.
|
85
|
+
def evaluate_code(step)
|
86
|
+
begin
|
87
|
+
advise!(:code, step)
|
88
|
+
@script.evaluate(step.code, step.lineno)
|
89
|
+
rescue SystemExit
|
90
|
+
pass!(step)
|
91
|
+
rescue Assertion => exception
|
92
|
+
fail!(step, exception)
|
93
|
+
rescue Exception => exception
|
94
|
+
error!(step, exception)
|
95
|
+
else
|
96
|
+
pass!(step)
|
57
97
|
end
|
58
|
-
advise!(:after_step, section, @script.file)
|
59
98
|
end
|
60
99
|
|
61
|
-
# TODO: Not sure how to handle loading links in comment mode.
|
62
|
-
def evaluate_links(
|
63
|
-
|
100
|
+
# TODO: Not sure how to handle loading links in --comment runner mode.
|
101
|
+
def evaluate_links(step)
|
102
|
+
step.text.scan(/\[qed:\/\/(.*?)\]/) do |match|
|
64
103
|
file = $1
|
65
104
|
# relative to demo script
|
66
105
|
if File.exist?(File.join(@script.directory,file))
|
@@ -77,25 +116,25 @@ module QED
|
|
77
116
|
end
|
78
117
|
|
79
118
|
#
|
80
|
-
def pass!(
|
81
|
-
advise!(:pass,
|
119
|
+
def pass!(step)
|
120
|
+
advise!(:pass, step)
|
82
121
|
end
|
83
122
|
|
84
123
|
#
|
85
|
-
def fail!(
|
86
|
-
advise!(:fail,
|
124
|
+
def fail!(step, exception)
|
125
|
+
advise!(:fail, step, exception)
|
87
126
|
#raise exception
|
88
127
|
end
|
89
128
|
|
90
129
|
#
|
91
|
-
def error!(
|
92
|
-
advise!(:error,
|
130
|
+
def error!(step, exception)
|
131
|
+
advise!(:error, step, exception)
|
93
132
|
#raise exception
|
94
133
|
end
|
95
134
|
|
96
135
|
#
|
97
136
|
def import!(file)
|
98
|
-
advise!(:unload)
|
137
|
+
advise!(:unload) # should this also occur just befor after_demo ?
|
99
138
|
eval(File.read(file), @script.binding, file)
|
100
139
|
advise!(:load, file)
|
101
140
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# This extension provides a simple means for
|
2
|
+
# create file-system fixtures.
|
3
|
+
|
4
|
+
require 'erb'
|
5
|
+
|
6
|
+
# Set global temporary directory.
|
7
|
+
$tmpdir = 'tmp'
|
8
|
+
|
9
|
+
#
|
10
|
+
def copy_fixture(name, tmpdir=$tmpdir)
|
11
|
+
FileUtils.mkdir(tmpdir)
|
12
|
+
srcdir = File.join(demo_directory, 'fixtures', name)
|
13
|
+
paths = Dir.glob(File.join(srcdir, '**', '*'), File::FNM_DOTMATCH)
|
14
|
+
paths.each do |path|
|
15
|
+
basename = File.basename(path)
|
16
|
+
next if basename == '.'
|
17
|
+
next if basename == '..'
|
18
|
+
dest = File.join(tmpdir, path.sub(srcdir+'/', ''))
|
19
|
+
if File.directory?(path)
|
20
|
+
FileUtils.mkdir(dest)
|
21
|
+
else
|
22
|
+
text = ERB.new(File.read(path)).result
|
23
|
+
File.open(dest, 'w'){ |f| f << text }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Object.__send__(:remove_const, :VERSION) if Object.const_defined?(:VERSION) # becuase Ruby 1.8~ gets in the way
|
2
|
+
|
3
|
+
module QED
|
4
|
+
|
5
|
+
def self.__DIR__
|
6
|
+
File.dirname(__FILE__)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.gemfile
|
10
|
+
@gemfile ||= (
|
11
|
+
require 'yaml'
|
12
|
+
YAML.load(File.new(__DIR__ + '/gemfile'))
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.profile
|
17
|
+
@profile ||= (
|
18
|
+
require 'yaml'
|
19
|
+
YAML.load(File.new(__DIR__ + '/profile'))
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.const_missing(name)
|
24
|
+
key = name.to_s.downcase
|
25
|
+
gemfile[key] || profile[key] || super(name)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
File without changes
|
data/lib/qed/parser.rb
CHANGED
@@ -36,7 +36,7 @@ module QED
|
|
36
36
|
when :comment
|
37
37
|
parse_comment_lines
|
38
38
|
else
|
39
|
-
index =
|
39
|
+
index = 0 #-1
|
40
40
|
File.readlines(file).to_a.map do |line|
|
41
41
|
[index += 1, line]
|
42
42
|
end
|
@@ -46,25 +46,32 @@ module QED
|
|
46
46
|
# TODO: It would be nice if we could get ther require statement for the
|
47
47
|
# comment mode to be relative to an actual loadpath.
|
48
48
|
def parse_comment_lines
|
49
|
-
|
49
|
+
ruby_omit = false
|
50
|
+
rdoc_omit = false
|
50
51
|
lines = [
|
51
52
|
[0, "Load #{File.basename(file)} script.\n"],
|
52
53
|
[0, "\n"],
|
53
54
|
[0, " require '#{file}'\n"]
|
54
55
|
]
|
55
|
-
index =
|
56
|
+
index = 1
|
56
57
|
File.readlines(file).each do |l|
|
57
58
|
case l
|
59
|
+
when /^=begin(?!\s+qed)/
|
60
|
+
ruby_omit = true
|
61
|
+
when /^=end/
|
62
|
+
ruby_omit = false
|
58
63
|
when /^\s*\#\-\-\s*$/
|
59
|
-
|
64
|
+
rdoc_omit = true
|
60
65
|
when /^\s*\#\+\+\s*$/
|
61
|
-
|
62
|
-
when /^\s*\#\ \-\-/ #
|
63
|
-
|
64
|
-
when /^\s
|
65
|
-
|
66
|
+
rdoc_omit = false
|
67
|
+
##when /^\s*\#\ \-\-/ # not needed just double comment
|
68
|
+
## # -- skip internal comments
|
69
|
+
when /^\s*##/
|
70
|
+
## skip internal comments
|
71
|
+
when /^\s*\#/
|
72
|
+
lines << [index, l.lstrip.sub(/^\#\ ?/, '')] unless (ruby_omit or rdoc_omit)
|
66
73
|
else
|
67
|
-
lines << [index, "\n"] unless lines.last[1] == "\n"
|
74
|
+
lines << [index, "\n"] unless lines.last[1] == "\n" unless (ruby_omit or rdoc_omit)
|
68
75
|
end
|
69
76
|
index += 1
|
70
77
|
end
|
@@ -135,33 +142,37 @@ module QED
|
|
135
142
|
|
136
143
|
def parse
|
137
144
|
tree = []
|
138
|
-
|
145
|
+
flush = true
|
139
146
|
pend = false
|
140
|
-
block = Block.new
|
147
|
+
block = Block.new(file)
|
141
148
|
lines.each do |lineno, line|
|
142
149
|
case line
|
143
150
|
when /^\s*$/
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
when :raw
|
151
|
+
if flush
|
152
|
+
pend = true unless lineno == 0
|
153
|
+
block.raw << [lineno, line]
|
154
|
+
else
|
149
155
|
block.raw << [lineno, line]
|
150
156
|
end
|
151
157
|
when /\A\s+/
|
152
|
-
|
158
|
+
if flush
|
159
|
+
tree << block.ready!(flush, tree.last)
|
160
|
+
block = Block.new(file)
|
161
|
+
end
|
162
|
+
pend = false
|
163
|
+
flush = false
|
153
164
|
block.raw << [lineno, line]
|
154
165
|
else
|
155
|
-
if pend ||
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
block = Block.new
|
166
|
+
if pend || !flush
|
167
|
+
tree << block.ready!(flush, tree.last)
|
168
|
+
pend = false
|
169
|
+
flush = true
|
170
|
+
block = Block.new(file)
|
160
171
|
end
|
161
|
-
block.
|
172
|
+
block.raw << [lineno, line]
|
162
173
|
end
|
163
174
|
end
|
164
|
-
tree << block.ready!
|
175
|
+
tree << block.ready!(flush, tree.last)
|
165
176
|
@ast = tree
|
166
177
|
end
|
167
178
|
|
@@ -176,97 +187,160 @@ module QED
|
|
176
187
|
|
177
188
|
# Section Block
|
178
189
|
class Block
|
179
|
-
# Block commentary.
|
180
|
-
attr :rem
|
181
|
-
|
182
190
|
# Block raw code/text.
|
183
191
|
attr :raw
|
184
192
|
|
193
|
+
# previous block
|
194
|
+
attr :back_step
|
195
|
+
|
196
|
+
# next block
|
197
|
+
attr :next_step
|
198
|
+
|
185
199
|
#
|
186
|
-
def initialize
|
187
|
-
@
|
188
|
-
@raw
|
189
|
-
@
|
200
|
+
def initialize(file)
|
201
|
+
@file = file
|
202
|
+
@raw = []
|
203
|
+
@type = :description
|
204
|
+
@back_step = nil
|
205
|
+
@next_step = nil
|
190
206
|
end
|
191
207
|
|
192
208
|
#
|
193
|
-
def ready!
|
194
|
-
@
|
195
|
-
@
|
196
|
-
|
197
|
-
@
|
209
|
+
def ready!(flush, back_step)
|
210
|
+
@flush = flush
|
211
|
+
@back_step = back_step
|
212
|
+
|
213
|
+
@text = raw.map{ |lineno, line| line }.join
|
214
|
+
@type = parse_type
|
215
|
+
|
216
|
+
@back_step.next_step = self if @back_step
|
217
|
+
|
198
218
|
self
|
199
219
|
end
|
200
220
|
|
201
221
|
#
|
202
|
-
def
|
203
|
-
|
222
|
+
def to_s
|
223
|
+
case type
|
224
|
+
when :description
|
225
|
+
text
|
226
|
+
else
|
227
|
+
text
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
#
|
232
|
+
def text
|
233
|
+
@text
|
204
234
|
end
|
205
235
|
|
206
236
|
#
|
207
|
-
def
|
208
|
-
@
|
237
|
+
def flush?
|
238
|
+
@flush
|
209
239
|
end
|
210
240
|
|
211
241
|
# Returns an Array of prepared example text
|
212
242
|
# for use in advice.
|
213
243
|
def arguments
|
214
|
-
|
244
|
+
if next_step && next_step.data?
|
245
|
+
[next_step.sample_text]
|
246
|
+
else
|
247
|
+
[]
|
248
|
+
end
|
215
249
|
end
|
216
250
|
|
217
|
-
#
|
218
|
-
def
|
219
|
-
@
|
251
|
+
# What type of block is this?
|
252
|
+
def type
|
253
|
+
@type
|
220
254
|
end
|
221
255
|
|
222
|
-
#
|
223
|
-
def
|
224
|
-
@line ||= @raw.first.first
|
225
|
-
end
|
256
|
+
#
|
257
|
+
def head? ; @type == :head ; end
|
226
258
|
|
227
259
|
#
|
228
|
-
def
|
229
|
-
@example
|
230
|
-
end
|
260
|
+
def desc? ; @type == :desc ; end
|
231
261
|
|
232
262
|
#
|
233
|
-
def
|
234
|
-
|
263
|
+
def code? ; @type == :code ; end
|
264
|
+
|
265
|
+
# Any commentary ending in `...` or `:` will mark the following
|
266
|
+
# block as a plain text *sample* and not example code to be evaluated.
|
267
|
+
def data? ; @type == :data ; end
|
268
|
+
|
269
|
+
#
|
270
|
+
alias_method :header?, :head?
|
271
|
+
|
272
|
+
#
|
273
|
+
alias_method :description?, :desc?
|
274
|
+
|
275
|
+
|
276
|
+
# First line of example text.
|
277
|
+
def lineno
|
278
|
+
@line ||= @raw.first.first
|
235
279
|
end
|
236
280
|
|
237
281
|
#
|
238
|
-
def
|
239
|
-
code
|
240
|
-
code.gsub!(/\n\s*\#\ ?\=\>/, '.assert == ')
|
241
|
-
code.gsub!(/\s*\#\ ?\=\>/, '.assert == ')
|
242
|
-
code
|
282
|
+
def code
|
283
|
+
@code ||= tweak_code
|
243
284
|
end
|
244
285
|
|
245
286
|
# Clean up the example text, removing unccesseary white lines
|
246
287
|
# and triple quote brackets, but keep indention intact.
|
247
|
-
def
|
248
|
-
|
249
|
-
if md = /\A["]{3,}(.*?)["]{3,}\Z/.match(
|
250
|
-
|
288
|
+
def clean_text
|
289
|
+
str = text.chomp.sub(/\A\n/,'')
|
290
|
+
if md = /\A["]{3,}(.*?)["]{3,}\Z/.match(str)
|
291
|
+
str = md[1]
|
251
292
|
end
|
252
|
-
|
293
|
+
str.rstrip
|
253
294
|
end
|
254
295
|
|
255
|
-
# When the
|
296
|
+
# When the text is sample text and passed to an adivce block, this
|
256
297
|
# provides the prepared form of the example text, removing white lines,
|
257
298
|
# triple quote brackets and indention.
|
258
|
-
def
|
259
|
-
|
260
|
-
if md = /\A["]{3,}(.*?)["]{3,}\Z/.match(
|
261
|
-
|
299
|
+
def sample_text
|
300
|
+
str = text.tabto(0).chomp.sub(/\A\n/,'')
|
301
|
+
if md = /\A["]{3,}(.*?)["]{3,}\Z/.match(str)
|
302
|
+
str = md[1]
|
303
|
+
end
|
304
|
+
str.rstrip
|
305
|
+
end
|
306
|
+
|
307
|
+
# TODO: object_hexid
|
308
|
+
def inspect
|
309
|
+
%[#<Block:#{object_id} "#{text[0..25]} ...">]
|
310
|
+
end
|
311
|
+
|
312
|
+
protected
|
313
|
+
|
314
|
+
#
|
315
|
+
def next_step=(n)
|
316
|
+
@next_step = n
|
317
|
+
end
|
318
|
+
|
319
|
+
private
|
320
|
+
|
321
|
+
#
|
322
|
+
def parse_type
|
323
|
+
if flush?
|
324
|
+
if /\A[=#]/ =~ text
|
325
|
+
:head
|
326
|
+
else
|
327
|
+
:desc
|
328
|
+
end
|
329
|
+
else
|
330
|
+
if back_step && /(\.\.\.|\:)\s*\Z/m =~ back_step.text.strip
|
331
|
+
:data
|
332
|
+
else
|
333
|
+
:code
|
334
|
+
end
|
262
335
|
end
|
263
|
-
text.rstrip
|
264
336
|
end
|
265
337
|
|
266
|
-
#
|
267
|
-
|
268
|
-
|
269
|
-
|
338
|
+
#
|
339
|
+
def tweak_code
|
340
|
+
code = text.dup
|
341
|
+
code.gsub!(/\n\s*\#\ ?\=\>/, '.assert = ')
|
342
|
+
code.gsub!(/\s*\#\ ?\=\>/, '.assert = ')
|
343
|
+
code
|
270
344
|
end
|
271
345
|
|
272
346
|
end
|