qed 1.3 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,124 @@
1
+ module QED
2
+
3
+ require 'tilt'
4
+ require 'nokogiri'
5
+ require 'qed/scope'
6
+
7
+ # = Demo Script Evaluator
8
+ #
9
+ #--
10
+ # TODO: Currently the Evaluator class uses #travserse to work
11
+ # thru the HTML document and trigger events accordingly. This
12
+ # works well enough for simple HTML documents --the kind produced
13
+ # by typical wiki-markup formats. However, for complex HTML it
14
+ # it will not produce ideal output (although the code segements
15
+ # should still run just fine). To counter this weakness, we will
16
+ # have to swtich to a more complex SAX parser in the future.
17
+ #--
18
+ class Evaluator
19
+
20
+ #
21
+ def initialize(script, *observers)
22
+ @script = script
23
+ @file = script.file
24
+ @scope = script.scope
25
+ @root = script.root
26
+
27
+ @observers = observers
28
+ end
29
+
30
+ #
31
+ def run
32
+ Dir.chdir(File.dirname(@file)) do
33
+ advise!(:before_document, @script)
34
+ @root.traverse do |element|
35
+ call_tag(element)
36
+ end
37
+ advise!(:after_document, @script)
38
+ end
39
+ end
40
+
41
+ #
42
+ def call_tag(element)
43
+ advise!(:tag, element)
44
+ __send__("tag_#{element.name}", element)
45
+ end
46
+
47
+ # T A G S
48
+
49
+ #
50
+ def tag_a(element)
51
+ case element['href']
52
+ when /qed:\/\/(.*?)$/
53
+ file = $1
54
+ case File.extname(file)
55
+ when '.rb'
56
+ import!(file)
57
+ else
58
+ Script.new(file, scope).run
59
+ end
60
+ end
61
+ end
62
+
63
+ #
64
+ def tag_pre(element)
65
+ advise!(:before_code, element, @file)
66
+ begin
67
+ eval(element.text, @scope.__binding__, @file, element.line)
68
+ pass!(element)
69
+ rescue Assertion => exception
70
+ fail!(element, exception)
71
+ rescue Exception => exception
72
+ error!(element, exception)
73
+ end
74
+ advise!(:after_code, element, @file)
75
+ end
76
+
77
+ #
78
+ def tag_p(element)
79
+ advise!(:when, element.text)
80
+ end
81
+
82
+ #
83
+ def method_missing(s, *a)
84
+ super(s, *a) unless /^tag/ =~ s.to_s
85
+ end
86
+
87
+ #
88
+ def pass!(element)
89
+ advise!(:pass, element)
90
+ end
91
+
92
+ #
93
+ def fail!(element, exception)
94
+ advise!(:fail, element, exception)
95
+ #raise exception
96
+ end
97
+
98
+ #
99
+ def error!(element, exception)
100
+ advise!(:error, element, exception)
101
+ #raise exception
102
+ end
103
+
104
+ #
105
+ def import!(file)
106
+ advise!(:unload)
107
+ eval(File.read(file), @scope.__binding__, file)
108
+ advise!(:load, file)
109
+ end
110
+
111
+ #
112
+ def advise!(signal, *args)
113
+ @observers.each{ |o| o.update(signal, *args) }
114
+ @scope.__advice__.call(signal, *args)
115
+ end
116
+
117
+ #
118
+ #def advise_when!(match)
119
+ # @scope.__advice__.call_when(match)
120
+ #end
121
+
122
+ end
123
+
124
+ end
@@ -6,99 +6,153 @@ module Reporter
6
6
 
7
7
  # = Reporter BaseClass
8
8
  #
9
- # Serves as the base class for all other specification
10
- # output formats.
9
+ # Serves as the base class for all other output formats.
11
10
  #
12
11
  class BaseClass
13
12
 
14
- ANSICode = ANSI::Code
15
-
16
13
  attr :io
17
14
  attr :steps
15
+ attr :omit
18
16
  attr :pass
19
17
  attr :fail
20
18
  attr :error
21
19
 
22
20
  def initialize(options={})
23
- @io = options[:io] || STDOUT
24
- @verbose = options[:verbose]
21
+ @io = options[:io] || STDOUT
22
+ @trace = options[:trace]
25
23
 
26
24
  @demos = 0
27
25
  @steps = 0
26
+ @omit = []
28
27
  @pass = []
29
28
  @fail = []
30
29
  @error = []
31
30
  end
32
31
 
33
32
  #
34
- def verbose?
35
- @verbose
33
+ def trace?
34
+ @trace
36
35
  end
37
36
 
38
- # Before running any specifications.
39
- def report_intro
37
+ #
38
+ def update(type, *args)
39
+ __send__("#{type}", *args)
40
40
  end
41
41
 
42
- # Beginning of a specification.
43
- def report_start(spec)
44
- @demos += 1
42
+
43
+ def self.When(type, &block)
44
+ #raise ArgumentError unless %w{session demo demonstration step}.include?(type.to_s)
45
+ #type = :demonstration if type.to_s == 'demo'
46
+ define_method(type, &block)
45
47
  end
46
48
 
47
- # Report a header.
48
- def report_header(step)
49
+ def self.Before(type, &block)
50
+ # raise ArgumentError unless %w{session demo demonstration step}.include?(type.to_s)
51
+ # type = :demonstration if type.to_s == 'demo'
52
+ define_method("before_#{type}", &block)
49
53
  end
50
54
 
51
- # Report a comment.
52
- def report_comment(step)
55
+ def self.After(type, &block)
56
+ # raise ArgumentError unless %w{session demo demonstration step pass fail error}.include?(type.to_s)
57
+ # type = :demonstration if type.to_s == 'demo'
58
+ define_method("after_#{type}", &block)
53
59
  end
54
60
 
55
- # Er... what was this for?
56
- #def report_mode(step)
57
- # report_literal(step)
61
+ #
62
+ #def Before(type, target, *args)
63
+ # type = :demonstration if type.to_s == 'demo'
64
+ # __send__("before_#{type}", target, *args)
65
+ #end
66
+
67
+ #
68
+ #def After(type, target, *args)
69
+ # type = :demonstration if type.to_s == 'demo'
70
+ # __send__("after_#{type}", target, *args)
58
71
  #end
59
72
 
73
+ # At the start of a session, before running any demonstrations.
74
+ def before_session(session)
75
+ end
76
+
77
+ # Beginning of a demonstration.
78
+ def before_document(demo) #demo(demo)
79
+ @demos += 1
80
+ end
81
+
82
+ #
83
+ def tag(element)
84
+ end
85
+
86
+ #
87
+ def load(demo)
88
+ end
89
+ #
90
+ def import(file)
91
+ end
92
+
60
93
  # Before running a step.
61
- def report_step(step)
94
+ def element(step)
95
+ end
96
+
97
+ def comment(elem)
98
+ end
99
+
100
+ # Before running a step that is omitted.
101
+ #def omit_step(step)
102
+ # @omit << step
103
+ #end
104
+
105
+ #
106
+ def before_code(step, file)
62
107
  @steps += 1
63
108
  end
64
109
 
65
- # Report step passed.
66
- def report_pass(step)
110
+ # After running a step that passed.
111
+ def pass(step)
67
112
  @pass << step
68
113
  end
69
114
 
70
- # Report step failed.
71
- def report_fail(step, assertion)
115
+ # After running a step that failed.
116
+ def fail(step, assertion)
72
117
  @fail << [step, assertion]
73
118
  end
74
119
 
75
- # Report step raised an error.
76
- def report_error(step, exception)
120
+ # After running a step that raised an error.
121
+ def error(step, exception)
77
122
  raise exception if $DEBUG
78
123
  @error << [step, exception]
79
124
  end
80
125
 
81
- # Since regular macro step does not pass or fail,
82
- # this method is used instead.
83
126
  #
84
- # TODO: Rename to #report_nominal (?)
85
- def report_macro(step)
127
+ def after_code(step, file)
86
128
  end
87
129
 
88
- # Report on omitted step.
89
- def report_omit(step)
130
+ #
131
+ def after_element(elem)
90
132
  end
91
133
 
92
- # After running a step.
93
- def report_step_end(step)
134
+ #
135
+ def unload
94
136
  end
95
137
 
96
- # End of a specification.
97
- def report_end(spec)
138
+ # End of a demonstration.
139
+ def after_document(demo) #demo(demo)
98
140
  end
99
141
 
100
- # After running all specifications.
101
- def report_summary
142
+ # After running all demonstrations. This is the place
143
+ # to output a summary of the session, if applicable.
144
+ def after_session(session)
145
+ end
146
+
147
+ #
148
+ def when(*args)
149
+ end
150
+
151
+ private
152
+
153
+ #
154
+ def clean_backtrace(btrace)
155
+ btrace.chomp(":in \`__binding__'")
102
156
  end
103
157
 
104
158
  end
@@ -0,0 +1,79 @@
1
+ module QED
2
+ module Reporter #:nodoc:
3
+
4
+ require 'qed/reporter/base'
5
+
6
+ # = Bullet Point Reporter
7
+ #
8
+ # Similar to the Verbatim reporter, but does
9
+ # not display test code for passing tests.
10
+ class BulletPoint < BaseClass
11
+
12
+ #
13
+ def tag(step)
14
+ case step.name
15
+ when 'pre'
16
+ # none
17
+ when /h\d/
18
+ io.puts ANSI::Code.bold("#{step.text}\n")
19
+ when 'p'
20
+ txt = step.text.to_s.strip.tabto(2)
21
+ txt[0,1] = "*"
22
+ io.puts txt
23
+ io.puts
24
+ end
25
+ end
26
+
27
+ def pass(step)
28
+ #io.puts ANSICode.green("#{step}")
29
+ end
30
+
31
+ def fail(step, assertion)
32
+ msg = ''
33
+ msg << " ##### FAIL #####\n"
34
+ msg << " # " + assertion.to_s
35
+ msg = ANSI::Code.magenta(msg)
36
+ io.puts msg
37
+ #io.puts
38
+ io.puts ANSI::Code.red("#{step.text}")
39
+ end
40
+
41
+ def error(step, exception)
42
+ raise exception if $DEBUG
43
+ msg = ''
44
+ msg << " ##### ERROR #####\n"
45
+ msg << " # " + exception.to_s + "\n"
46
+ msg << " # " + clean_backtrace(exception.backtrace[0])
47
+ msg = ANSI::Code.magenta(msg)
48
+ io.puts msg
49
+ #io.puts
50
+ io.puts ANSI::Code.red("#{step.text}")
51
+ end
52
+
53
+ #def report(str)
54
+ # count[-1] += 1 unless count.empty?
55
+ # str = str.chomp('.') + '.'
56
+ # str = count.join('.') + ' ' + str
57
+ # io.puts str.strip
58
+ #end
59
+
60
+ #def report_comment(step)
61
+ # txt = step.to_s.strip.tabto(2)
62
+ # txt[0,1] = "*"
63
+ # io.puts txt
64
+ # io.puts
65
+ #end
66
+
67
+ #def report_macro(step)
68
+ # txt = step.to_s.tabto(2)
69
+ # txt[0,1] = "*"
70
+ # io.puts txt
71
+ # #io.puts
72
+ # #io.puts ANSICode.magenta("#{step}")
73
+ #end
74
+
75
+ end #class Summary
76
+
77
+ end#module Reporter
78
+ end#module QED
79
+
@@ -8,37 +8,24 @@ module Reporter #:nodoc:
8
8
  class DotProgress < BaseClass
9
9
 
10
10
  #
11
- def report_intro
11
+ def before_session(session)
12
12
  @start_time = Time.now
13
13
  io.puts "Started"
14
14
  end
15
15
 
16
16
  #
17
- def report_step(step)
18
- super
19
- #if step.code
20
- io.print "."
21
- #str = "(%s) %s" % [count.join('.'), str.tab(6).strip]
22
- #puts "* #{step.text.tab(2).strip}"
23
- #puts "\n#{step.code}\n" if $VERBOSE
24
- #else
25
- #puts "\n#{step.text}"
26
- #end
17
+ def before_code(step, file)
18
+ super(step, file)
19
+ io.print "." if step.name == 'pre'
27
20
  end
28
21
 
29
- #def report(str)
30
- # count[-1] += 1 unless count.empty?
31
- # str = str.chomp('.') + '.'
32
- # str = count.join('.') + ' ' + str
33
- # puts str.strip
34
- #end
35
-
36
- def report_summary
22
+ #
23
+ def after_session(session)
37
24
  io.puts "\nFinished in #{Time.now - @start_time} seconds.\n\n"
38
25
 
39
26
  @error.each do |step, exception|
40
27
  backtrace = clean_backtrace(exception.backtrace[0])
41
- io.puts ANSICode.red("***** ERROR *****")
28
+ io.puts ANSI::Code.red("***** ERROR *****")
42
29
  io.puts "#{exception}"
43
30
  io.puts ":#{backtrace}:"
44
31
  #io.puts ":#{exception.backtrace[1]}:"
@@ -48,8 +35,8 @@ module Reporter #:nodoc:
48
35
 
49
36
  @fail.each do |step, assertion|
50
37
  backtrace = clean_backtrace(assertion.backtrace[0])
51
- io.puts ANSICode.red("***** FAIL *****")
52
- io.puts ANSICode.bold("#{assertion}")
38
+ io.puts ANSI::Code.red("***** FAIL *****")
39
+ io.puts ANSI::Code.bold("#{assertion}")
53
40
  io.puts ":#{backtrace}:"
54
41
  #io.puts assertion if $VERBOSE
55
42
  io.puts
@@ -58,13 +45,6 @@ module Reporter #:nodoc:
58
45
  io.puts "%s demos, %s steps, %s failures, %s errors" % [@demos, @steps, @fail.size, @error.size] #, @pass.size ]
59
46
  end
60
47
 
61
- private
62
-
63
- #
64
- def clean_backtrace(btrace)
65
- btrace.chomp(":in `_binding'")
66
- end
67
-
68
48
  end#class DotProgress
69
49
 
70
50
  end#module Reporter