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/lib/qed.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module QED
2
- VERSION="1.2" #:till: VERSION="<%= version %>"
2
+ VERSION="2.0.0" #:till: VERSION="<%= version %>"
3
3
  end
4
4
 
5
- require 'qed/runner'
5
+ require 'qed/session'
6
6
 
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 :env
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 = nil
59
- @env = nil
60
- @profile = nil
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 Options (pick one):")
87
+ opt.separator("Report Formats (pick one):")
82
88
 
83
89
  opt.on('--dotprogress', '-d', "use dot-progress reporter [default]") do
84
- @options[:format] = :summary
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('--summary', '-s', "use summary reporter") do
92
- @options[:format] = :summary
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('--script', "psuedo-reporter") do
96
- @options[:script] # psuedo-reporter
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('--env', '-e [NAME]', "runtime environment [default]") do |name|
102
- @options[:env] = name
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
- #if files.empty?
156
- # if File.directory?('test')
157
- # files << 'test/doc{,s}'
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,'**','*{.qed,.rd,.rdoc,.md,.markdown}')]
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
- # Instance of Runner class.
183
+ # Session instance.
184
184
 
185
- def runner
186
- Runner.new(demos, :format=>format, :trace=>trace)
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
- args = profiles[profile]
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
- require_environment
220
+ require_profile
220
221
 
221
- # TODO: Remove case, can :script be done with Reporter or do we ne need selectable Runner?
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 require_environment
256
- if env
257
- if file = Dir["#{CONFDIR}/{env,environments}/#{env}.rb"].first
258
- require(file)
259
- end
260
- else
261
- if file = Dir["#{CONFDIR}/env.rb"].first
262
- require(file)
263
- elsif file = Dir["#{CONFDIR}/{env,environments}/default.rb"].first
264
- require(file)
265
- end
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
- class Config
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
- def initialize
6
- @local = ['qed', 'demos', 'test/demos']
25
+ #
26
+ class Profile
7
27
 
8
- if file = File.glob('{.,}config/qed.{yml,yaml}')
9
- YAML.load(File.new(file)).each do |k,v|
10
- __send__("#{k}=", v)
11
- end
12
- end
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
- attr_accessor :local
42
+ #
43
+ #attr_accessor :local
16
44
 
17
- # How ot identify a header?
18
- #attr_accessor :header
45
+ #
46
+ def Before(type=:session, &procedure)
47
+ @before[type] << procedure if procedure
48
+ @before[type]
49
+ end
19
50
 
20
- # How ot identify a footer?
21
- #attr_accessor :footer
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
+