rscm-accurev 0.0 → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +7 -76
- data/TODO +3 -17
- data/lib/rscm/accurev.rb +1 -13
- data/lib/rscm/scm/accurev/#command.rb# +95 -0
- data/lib/rscm/scm/accurev/api.rb +77 -258
- data/lib/rscm/scm/accurev/command.rb +40 -97
- data/lib/rscm/scm/accurev/filterio.rb +4 -6
- data/lib/rscm/scm/accurev/xml.rb +11 -199
- data/test/t_command.rb +11 -59
- data/test/t_load.rb +0 -1
- data/test/t_scrubio.rb +6 -1
- data/{apitest.rb → test.rb} +0 -1
- data/{test/eg/update-newwksp.xml → testing.log} +138 -0
- metadata +15 -57
- data/STATUS +0 -63
- data/bumprelease.sh +0 -13
- data/lib/rscm/scm/accurev/api.rb.mine +0 -382
- data/lib/rscm/scm/accurev/api.rb.r263 +0 -364
- data/lib/rscm/scm/accurev/api.rb.r265 +0 -393
- data/lib/rscm/scm/accurev/exception.rb +0 -38
- data/lib/test/unit/ui/xml/testrunner.rb +0 -165
- data/lib/test/unit/ui/xml/xmltestrunner.xslt +0 -79
- data/test/coverage/analyzer.rb +0 -127
- data/test/coverage/c_loader.rb +0 -34
- data/test/coverage/cover.rb +0 -91
- data/test/coverage/coverage_loader.rb +0 -21
- data/test/coverage/coveragetask.rb +0 -38
- data/test/coverage/index_tmpl.html +0 -42
- data/test/coverage/template.html +0 -36
- data/test/eg/ac-files.xml +0 -172
- data/test/eg/ac-pop.txt +0 -195
- data/test/eg/files-various-states.xml +0 -188
- data/test/eg/hist-oneweek-all.xml +0 -1483
- data/test/eg/hist-oneweek-external.xml +0 -246
- data/test/eg/hist-oneweek-promotes.xml +0 -1092
- data/test/eg/info.txt +0 -14
- data/test/eg/stat-a-various.xml +0 -1789
- data/test/eg/stat-m.xml +0 -13
- data/test/eg/stat-overlap.xml +0 -13
- data/test/eg/stat-x.xml +0 -20
- data/test/eg/update-i-mods-and-updates-and-overlap.xml +0 -73
- data/test/eg/update-i-nochanges.xml +0 -8
- data/test/eg/update-i-stale.xml +0 -0
- data/test/eg/update-i-updates.xml +0 -125
- data/test/eg/update-nochanges.xml +0 -7
- data/test/eg/update-stale.xml +0 -12
- data/test/eg/update-updates.xml +0 -147
- data/test/t_api.rb +0 -163
- data/test/t_xmlmapper.rb +0 -75
@@ -1,393 +0,0 @@
|
|
1
|
-
# -*- ruby -*-
|
2
|
-
#
|
3
|
-
# = api.rb
|
4
|
-
#
|
5
|
-
# API for interacting with accurev workspaces.
|
6
|
-
#
|
7
|
-
# Includes:
|
8
|
-
#
|
9
|
-
# * API
|
10
|
-
#
|
11
|
-
require 'stringio'
|
12
|
-
require 'rscm/base'
|
13
|
-
require 'rscm/path_converter'
|
14
|
-
require 'rexml/document'
|
15
|
-
require 'rscm/scm/accurev/xml'
|
16
|
-
require 'rscm/scm/accurev/filterio'
|
17
|
-
require 'rscm/scm/accurev/command'
|
18
|
-
require 'rscm/scm/accurev/exception'
|
19
|
-
|
20
|
-
# need to define module within module before you can use module X::Y
|
21
|
-
module RSCM; module Accurev; end; end
|
22
|
-
|
23
|
-
module RSCM::Accurev
|
24
|
-
|
25
|
-
#
|
26
|
-
# RSCM implementation for Accurev (http://www.accurev.com).
|
27
|
-
#
|
28
|
-
# Requires an accurev cli executable on the path (see also
|
29
|
-
# RSCM::Accurev::Command), and the correct environment
|
30
|
-
# configuration for ac server/principal/password.
|
31
|
-
#
|
32
|
-
# ---
|
33
|
-
#
|
34
|
-
# === Example
|
35
|
-
#
|
36
|
-
# api = RSCM::Accurev::API.new( "./ws/proj-1", "proj", "proj-1" )
|
37
|
-
# api.checkout() each do |file|
|
38
|
-
# puts "Updated #{file}..."
|
39
|
-
# end
|
40
|
-
#
|
41
|
-
class API < RSCM::Base
|
42
|
-
register self
|
43
|
-
|
44
|
-
ann :description => "Accurev Depot"
|
45
|
-
attr_accessor :depot
|
46
|
-
|
47
|
-
ann :description => "Backing Stream (autodetected)"
|
48
|
-
attr_accessor :backing_stream
|
49
|
-
|
50
|
-
# If workspace stream is nil (the default), checkout/update will be
|
51
|
-
# done using `accurev pop`. This is faster and more appropriate for
|
52
|
-
# read-only use; however a workspace is required for commits.
|
53
|
-
ann :description => "Workspace Stream"
|
54
|
-
attr_accessor :workspace_stream
|
55
|
-
|
56
|
-
# [defined in Base]
|
57
|
-
# ann :description => "Filesystem Path to Workspace"
|
58
|
-
# attr_accessor :checkout_dir
|
59
|
-
|
60
|
-
ann :description => "Overwrite Mode: if true, co overwrites existing"
|
61
|
-
attr_accessor :overwrite
|
62
|
-
|
63
|
-
def initialize(checkout_dir=nil, backing_stream=nil, workspace_stream=nil)
|
64
|
-
@depot = nil # will be pulled from files cmd output
|
65
|
-
@workspace_stream = workspace_stream
|
66
|
-
@backing_stream = backing_stream
|
67
|
-
@checkout_dir = checkout_dir
|
68
|
-
@overwrite = false
|
69
|
-
end
|
70
|
-
|
71
|
-
def name()
|
72
|
-
return "Accurev"
|
73
|
-
end
|
74
|
-
|
75
|
-
# Accurev operations are atomic: returns true.
|
76
|
-
def transactional?
|
77
|
-
return true
|
78
|
-
end
|
79
|
-
|
80
|
-
# "Adds +relative_filename+ to the working copy."
|
81
|
-
def add( relative_filename )
|
82
|
-
raise "XXX implement me"
|
83
|
-
end
|
84
|
-
|
85
|
-
def edit( relative_filename )
|
86
|
-
# NOP - not required for ac
|
87
|
-
end
|
88
|
-
|
89
|
-
# "Returns a Revisions object for the period specified ... (inclusive)."
|
90
|
-
#
|
91
|
-
# list txns (promotes to bs) from hist within the period
|
92
|
-
#
|
93
|
-
def revisions( from_identifier, to_identifier=Time.infinity )
|
94
|
-
raise "XXX implement me"
|
95
|
-
end
|
96
|
-
|
97
|
-
# default impl depends on a correct impl of revisions()
|
98
|
-
# def uptodate?( identifier=nil )
|
99
|
-
#
|
100
|
-
# end
|
101
|
-
|
102
|
-
# def checked_out? - base
|
103
|
-
|
104
|
-
# accurev actually does have triggers, but I haven't implemented that yet
|
105
|
-
def supports_trigger?
|
106
|
-
false
|
107
|
-
end
|
108
|
-
|
109
|
-
# def diff() XXX
|
110
|
-
|
111
|
-
|
112
|
-
# --- ac specific
|
113
|
-
|
114
|
-
def ac_files( relative_path )
|
115
|
-
cmd = Command.instance
|
116
|
-
ret = []
|
117
|
-
with_working_dir( @checkout_dir ) do
|
118
|
-
acresponse = cmd.accurev( "files", relative_path )
|
119
|
-
acresponse['element'].each do |fd|
|
120
|
-
yield fd if block_given?
|
121
|
-
ret << fd
|
122
|
-
end
|
123
|
-
end
|
124
|
-
return ret
|
125
|
-
end
|
126
|
-
|
127
|
-
# yeilds the TransactionData objects for the given time period
|
128
|
-
# (promotes only)
|
129
|
-
def ac_hist( from, to=Time.infinite )
|
130
|
-
cmd = Command.instance
|
131
|
-
lower = from.to_accurev
|
132
|
-
upper = "now"
|
133
|
-
unless to == Time.infinite
|
134
|
-
upper = to.to_accurev
|
135
|
-
end
|
136
|
-
with_working_dir( self.co_filepath ) do
|
137
|
-
acresponse = cmd.accurev( "hist",
|
138
|
-
"-t", "'#{upper}-#{lower}'",
|
139
|
-
"-k", "promote"
|
140
|
-
)
|
141
|
-
ret = []
|
142
|
-
acresponse['transaction'].each do |txn|
|
143
|
-
ret << txn
|
144
|
-
yield txn if block_given?
|
145
|
-
end
|
146
|
-
return ret
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
def ac_keep( files=[], message="" )
|
151
|
-
raise "XXX implement me"
|
152
|
-
end
|
153
|
-
|
154
|
-
def ac_promote( files=[], message="" )
|
155
|
-
raise "XXX implement me"
|
156
|
-
end
|
157
|
-
|
158
|
-
def ac_update( relative_path="." )
|
159
|
-
d = accurev( "update", relative_path )
|
160
|
-
if xxx_error_stale
|
161
|
-
raise StaleWorkspaceError.new( "#{relative_path} is stale -- keep/anchor all changes and re-update" )
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
def ac_purge( files=[] )
|
166
|
-
raise "XXX implement me"
|
167
|
-
end
|
168
|
-
|
169
|
-
def ac_revert( files=[] )
|
170
|
-
raise "XXX implement me"
|
171
|
-
end
|
172
|
-
|
173
|
-
def ac_move( current_file, new_file )
|
174
|
-
raise "XXX implement me"
|
175
|
-
end
|
176
|
-
|
177
|
-
#
|
178
|
-
# Performs an "accurev info" command in the workspace.
|
179
|
-
# Returns a map of
|
180
|
-
#
|
181
|
-
# ac info: shows eg, backing stream
|
182
|
-
# but doesn't support -fx!
|
183
|
-
#
|
184
|
-
def ac_info()
|
185
|
-
co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
|
186
|
-
unless File.exists?( co )
|
187
|
-
raise AccurevException.new( "Checkout dir #{co} does not exist" )
|
188
|
-
end
|
189
|
-
info = {}
|
190
|
-
with_working_dir( co ) do
|
191
|
-
cmd = Command.instance
|
192
|
-
io = StringIO.new( cmd.accurev_nofx( "info" ) )
|
193
|
-
io.each_line do |line|
|
194
|
-
next unless line =~ /\S/
|
195
|
-
if line =~ /^(.*?):\s+(.*)$/
|
196
|
-
info[$1] = $2
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
200
|
-
return info
|
201
|
-
end
|
202
|
-
|
203
|
-
# ac mkws
|
204
|
-
# -b orbitz-host-gt3-0-impl
|
205
|
-
# -w orbitz-host-gt3-0-impl-test2_gfast
|
206
|
-
# -l `pwd`
|
207
|
-
# - does not support fx (argh!@)
|
208
|
-
# - does not pop
|
209
|
-
#
|
210
|
-
|
211
|
-
# diff: /usr/local/bin/acdiff (!) --fx
|
212
|
-
# (after an ac cat on the backed file)
|
213
|
-
# (eg, no in-process diffing ala cvs diff)
|
214
|
-
# lists modified lines in xml
|
215
|
-
|
216
|
-
#
|
217
|
-
# "Checks out or updates[!] contents from a central SCM
|
218
|
-
# to +checkout_dir+ - a local working copy."
|
219
|
-
#
|
220
|
-
# "The +to_identifier+ parameter may be optionally specified to
|
221
|
-
# obtain files up to a particular time or label."
|
222
|
-
#
|
223
|
-
# For accurev, this:
|
224
|
-
# * checks to see if +@checkout_dir+ exists and appears checked out.
|
225
|
-
# If it's already checked out, this calls +update()+. If
|
226
|
-
# +@checkout_dir+ exists and +to_identifier+ is given, an
|
227
|
-
# exception is raised.
|
228
|
-
# * otherwise, this creates a new workspace stream and populates it
|
229
|
-
# at +@checkout_dir+.
|
230
|
-
#
|
231
|
-
# This both returns and yields a list of updated files.
|
232
|
-
# Only updated files are returned, not directories.
|
233
|
-
#
|
234
|
-
# Current, ac_update returns both files and directories, including
|
235
|
-
# deleted files.
|
236
|
-
#
|
237
|
-
def checkout( to_identifier=Time.infinite )
|
238
|
-
co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
|
239
|
-
if @backing_stream.nil?
|
240
|
-
self.attempt_init_from_info()
|
241
|
-
end
|
242
|
-
if @workspace_stream.nil?
|
243
|
-
self.checkout_pop()
|
244
|
-
else
|
245
|
-
unless File.exists?( co )
|
246
|
-
# create new workspace
|
247
|
-
self.checkout_workspace()
|
248
|
-
end
|
249
|
-
# update workspace
|
250
|
-
self.update( to_identifier )
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
def checkout_pop()
|
255
|
-
co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
|
256
|
-
raise "A backing stream is required" if @backing_stream.nil?
|
257
|
-
raise "A working stream may not be given" unless @working_stream.nil?
|
258
|
-
# for `accurev pop`: remove and re-pop the checkout copy
|
259
|
-
if File.exists?( co )
|
260
|
-
unless @overwrite
|
261
|
-
raise "Checkout dir #{co} already exists (@overwrite=#@overwrite)"
|
262
|
-
end
|
263
|
-
rm_rf( co )
|
264
|
-
end
|
265
|
-
mkdir(co)
|
266
|
-
with_working_dir( co ) do
|
267
|
-
cmd = Command.instance
|
268
|
-
pop_out = cmd.accurev_nofx("pop",
|
269
|
-
"-R",
|
270
|
-
"-v", @backing_stream,
|
271
|
-
"-L", ".", ".")
|
272
|
-
elems = []
|
273
|
-
popio = StringIO.new( pop_out )
|
274
|
-
popio.each_line do |line|
|
275
|
-
if line =~ /^Populating element \/.\/(.*)$/
|
276
|
-
loc = $1
|
277
|
-
elems << loc
|
278
|
-
yield loc if block_given?
|
279
|
-
end
|
280
|
-
end
|
281
|
-
return elems
|
282
|
-
end
|
283
|
-
end
|
284
|
-
|
285
|
-
def checkout_workspace()
|
286
|
-
co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
|
287
|
-
raise "A backing stream is required" if @backing_stream.nil?
|
288
|
-
raise "A workspace is required" if @working_stream.nil?
|
289
|
-
if File.exist?( co ) and !@overwrite
|
290
|
-
raise "Checkout dir #{co} already exists (@overwrite=#@overwrite)"
|
291
|
-
end
|
292
|
-
cmd = Command.instance
|
293
|
-
mkws_out = cmd.accurev_nofx( "mkws",
|
294
|
-
"-b", @backing_stream,
|
295
|
-
"-w", @workspace_stream,
|
296
|
-
"-l", co )
|
297
|
-
# kinda sucks:
|
298
|
-
if ( mkws_out =~ /already exists/ )
|
299
|
-
raise AccurevException.new( "Failed to checkout", mkws_out )
|
300
|
-
end
|
301
|
-
end
|
302
|
-
|
303
|
-
def update( to_identifier=Time.infinite )
|
304
|
-
co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
|
305
|
-
unless File.exists?( co )
|
306
|
-
raise AccurevException.new( "Workspace does not exist!" )
|
307
|
-
end
|
308
|
-
updated = []
|
309
|
-
with_working_dir( co ) do
|
310
|
-
cmd = Command.instance
|
311
|
-
acresponse = cmd.accurev( "update" )
|
312
|
-
if acresponse.error
|
313
|
-
if acresponse.error =~ /workspace have been modified/
|
314
|
-
raise StaleWorkspaceException.new( "Workspace stale",
|
315
|
-
acresponse.error )
|
316
|
-
else
|
317
|
-
# some other update problem
|
318
|
-
raise AccurevException.new( "Error on update", acresponse.error )
|
319
|
-
end
|
320
|
-
end
|
321
|
-
if acresponse['element']
|
322
|
-
acresponse['element'].each do |up|
|
323
|
-
# "ac update" on a new workspace yields element locations
|
324
|
-
# with leading "/"s, which should be removed to get a proper
|
325
|
-
# relative path:
|
326
|
-
loc = up.location.sub( /^\//, "" )
|
327
|
-
yield loc if block_given?
|
328
|
-
updated << loc
|
329
|
-
end
|
330
|
-
end
|
331
|
-
end
|
332
|
-
return updated
|
333
|
-
end
|
334
|
-
|
335
|
-
# --- internals
|
336
|
-
|
337
|
-
# status flag mappings for "stat", "file" commands
|
338
|
-
STATUSES = {
|
339
|
-
'(backed)' => :backed,
|
340
|
-
'(external)' => :external,
|
341
|
-
'(modified)' => :modified,
|
342
|
-
'(kept)' => :kept,
|
343
|
-
'(defunct)' => :defunct,
|
344
|
-
'(missing)' => :missing,
|
345
|
-
'(stranded)' => :stranded,
|
346
|
-
'(overlap)' => :overlap
|
347
|
-
}
|
348
|
-
|
349
|
-
# private
|
350
|
-
|
351
|
-
# psuedo-accessor (cached)
|
352
|
-
def co_filepath
|
353
|
-
if @co_filepath.nil?
|
354
|
-
@co_filepath = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
|
355
|
-
end
|
356
|
-
return @co_filepath
|
357
|
-
end
|
358
|
-
|
359
|
-
#
|
360
|
-
# Runs an `ac info` command in +@checkout_dir+, and tries to
|
361
|
-
# set +@backing_stream+ and +@workspace_stream+ from the output.
|
362
|
-
#
|
363
|
-
def attempt_init_from_info()
|
364
|
-
if File.exists?( self.co_filepath )
|
365
|
-
info = self.ac_info
|
366
|
-
if info.has_key?( "Basis" )
|
367
|
-
@backing_stream = info["Basis"]
|
368
|
-
end
|
369
|
-
if info.has_key?( "ws/ref" )
|
370
|
-
@workspace_stream = info["ws/ref"]
|
371
|
-
end
|
372
|
-
end
|
373
|
-
end
|
374
|
-
|
375
|
-
# Takes a status flags line (eg, "(modified)(kept)")
|
376
|
-
# and returns a list of status flags.
|
377
|
-
def map_status( status_line )
|
378
|
-
l = status_line.split( " " ).map {|x| x.trim}
|
379
|
-
end
|
380
|
-
|
381
|
-
end
|
382
|
-
|
383
|
-
end
|
384
|
-
|
385
|
-
class Time
|
386
|
-
def to_accurev
|
387
|
-
self.strftime( "%Y/%m/%d %H:%M:%S" )
|
388
|
-
end
|
389
|
-
end
|
390
|
-
|
391
|
-
#
|
392
|
-
# Copyright (c) 2005 Gregory D. Fast <gdf@speakeasy.net>
|
393
|
-
#
|
@@ -1,38 +0,0 @@
|
|
1
|
-
# -*- ruby -*-
|
2
|
-
#
|
3
|
-
# = exception.rb
|
4
|
-
#
|
5
|
-
# Exception classes for RSCM::Accurev
|
6
|
-
#
|
7
|
-
# Includes:
|
8
|
-
#
|
9
|
-
# * AccurevException
|
10
|
-
#
|
11
|
-
# * StaleWorkspaceException
|
12
|
-
#
|
13
|
-
module RSCM
|
14
|
-
module Accurev
|
15
|
-
|
16
|
-
#
|
17
|
-
# General exception class for errors processing commands.
|
18
|
-
#
|
19
|
-
# @attr error_msg Error message output by accurev.
|
20
|
-
#
|
21
|
-
class AccurevException < Exception
|
22
|
-
attr_reader :error_msg
|
23
|
-
def initialize( msg, error_msg=nil )
|
24
|
-
super( "#{msg}: #{error_msg}" )
|
25
|
-
@error_msg = error_msg
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
#
|
30
|
-
# Exception thrown when an update is performed
|
31
|
-
# on a workspace with unkept/unanchored modifications.
|
32
|
-
# Accurev requires that all modifications be handled before
|
33
|
-
# an update is performed.
|
34
|
-
#
|
35
|
-
class StaleWorkspaceException < AccurevException; end
|
36
|
-
|
37
|
-
end
|
38
|
-
end
|
@@ -1,165 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'test/unit/ui/testrunnermediator'
|
4
|
-
require 'test/unit/ui/testrunnerutilities'
|
5
|
-
require 'test/unit/ui/console/testrunner'
|
6
|
-
require 'test/unit/autorunner'
|
7
|
-
require 'rexml/document'
|
8
|
-
|
9
|
-
module Test
|
10
|
-
module Unit
|
11
|
-
module UI
|
12
|
-
module XML
|
13
|
-
|
14
|
-
#
|
15
|
-
# XML::TestRunner - generate xml output for test results
|
16
|
-
#
|
17
|
-
# Example use:
|
18
|
-
#
|
19
|
-
# $ ruby -rtest/unit/ui/xml/testrunner test/test_1.rb --runner=xml
|
20
|
-
#
|
21
|
-
# By default, XML::TestRunner will output to stdout.
|
22
|
-
# You can set the environment variable $XMLTEST_OUTPUT to
|
23
|
-
# a filename to send the output to that file.
|
24
|
-
#
|
25
|
-
# The summary file created by this testrunner is XML, but
|
26
|
-
# this module also includes a stylesheet
|
27
|
-
# (test/unit/ui/xml/xmltestrunner.xslt) which converts it to
|
28
|
-
# HTML. Copy the XSLT file into the same directory as the
|
29
|
-
# test results file, and open the results file with a browser.
|
30
|
-
#
|
31
|
-
# ---
|
32
|
-
#
|
33
|
-
# (todo: use with rake)
|
34
|
-
#
|
35
|
-
class TestRunner < Test::Unit::UI::Console::TestRunner
|
36
|
-
|
37
|
-
def initialize( suite, output_level )
|
38
|
-
super( suite )
|
39
|
-
if ENV['XMLTEST_OUTPUT']
|
40
|
-
fn = ENV['XMLTEST_OUTPUT']
|
41
|
-
puts "Writing to #{fn}"
|
42
|
-
@io = File.open( fn, "w" )
|
43
|
-
@using_stdout = false
|
44
|
-
else
|
45
|
-
puts "Writing to stdout (along with everyone else...)"
|
46
|
-
@io = STDOUT
|
47
|
-
@using_stdout = true
|
48
|
-
end
|
49
|
-
create_document()
|
50
|
-
end
|
51
|
-
|
52
|
-
def create_document()
|
53
|
-
@doc = REXML::Document.new()
|
54
|
-
@doc << REXML::XMLDecl.new()
|
55
|
-
|
56
|
-
pi = REXML::Instruction.new(
|
57
|
-
"xml-stylesheet",
|
58
|
-
"type='text/xsl' href='xmltestrunner.xslt' "
|
59
|
-
)
|
60
|
-
@doc << pi
|
61
|
-
|
62
|
-
e = REXML::Element.new( "testsuite" )
|
63
|
-
e.attributes['rundate'] = Time.now
|
64
|
-
@doc << e
|
65
|
-
end
|
66
|
-
|
67
|
-
def to_s
|
68
|
-
@doc.to_s
|
69
|
-
end
|
70
|
-
|
71
|
-
def start
|
72
|
-
@current_test = nil
|
73
|
-
# setup_mediator
|
74
|
-
@mediator = TestRunnerMediator.new( @suite )
|
75
|
-
suite_name = @suite.to_s
|
76
|
-
if @suite.kind_of?(Module)
|
77
|
-
suite_name = @suite.name
|
78
|
-
end
|
79
|
-
@doc.root.attributes['name'] = suite_name
|
80
|
-
# attach_to_mediator - define callbacks
|
81
|
-
@mediator.add_listener( TestResult::FAULT,
|
82
|
-
&method(:add_fault) )
|
83
|
-
@mediator.add_listener( TestRunnerMediator::STARTED,
|
84
|
-
&method(:started) )
|
85
|
-
@mediator.add_listener( TestRunnerMediator::FINISHED,
|
86
|
-
&method(:finished) )
|
87
|
-
@mediator.add_listener( TestCase::STARTED,
|
88
|
-
&method(:test_started) )
|
89
|
-
@mediator.add_listener( TestCase::FINISHED,
|
90
|
-
&method(:test_finished) )
|
91
|
-
# return start_mediator
|
92
|
-
return @mediator.run_suite
|
93
|
-
end
|
94
|
-
|
95
|
-
# callbacks
|
96
|
-
|
97
|
-
def add_fault( fault )
|
98
|
-
##STDERR.puts "Fault:"
|
99
|
-
@faults << fault
|
100
|
-
e = REXML::Element.new( "fault" )
|
101
|
-
e << REXML::CData.new( fault.long_display )
|
102
|
-
@current_test << e
|
103
|
-
end
|
104
|
-
|
105
|
-
def started( result )
|
106
|
-
#STDERR.puts "Started"
|
107
|
-
@result = result
|
108
|
-
end
|
109
|
-
|
110
|
-
def finished( elapsed_time )
|
111
|
-
#STDERR.puts "Finished"
|
112
|
-
res = REXML::Element.new( "result" )
|
113
|
-
summ = REXML::Element.new( "summary" )
|
114
|
-
summ.text = @result
|
115
|
-
res << summ
|
116
|
-
# @result is a Test::Unit::TestResults
|
117
|
-
res.attributes['passed'] = @result.passed?
|
118
|
-
res.attributes['testcount'] = @result.run_count
|
119
|
-
res.attributes['assertcount'] = @result.assertion_count
|
120
|
-
res.attributes['failures'] = @result.failure_count
|
121
|
-
res.attributes['errors'] = @result.error_count
|
122
|
-
@doc.root << res
|
123
|
-
|
124
|
-
e = REXML::Element.new( "elapsed-time" )
|
125
|
-
e.text = elapsed_time
|
126
|
-
@doc.root << e
|
127
|
-
@io.puts( @doc.to_s )
|
128
|
-
|
129
|
-
unless @using_stdout
|
130
|
-
puts @result
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
def test_started( name )
|
135
|
-
#STDERR.puts "Test: #{name} started"
|
136
|
-
e = REXML::Element.new( "test" )
|
137
|
-
e.attributes['name'] = name
|
138
|
-
#e.attributes['status'] = "failed"
|
139
|
-
@doc.root << e
|
140
|
-
@current_test = e
|
141
|
-
end
|
142
|
-
|
143
|
-
def test_finished( name )
|
144
|
-
#STDERR.puts "Test: #{name} finished"
|
145
|
-
# find //test[@name='name']
|
146
|
-
@current_test = nil
|
147
|
-
end
|
148
|
-
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
# "plug in" xmltestrunner into autorunner's list of known runners
|
156
|
-
# This enables the "--runner=xml" commandline option.
|
157
|
-
Test::Unit::AutoRunner::RUNNERS[:xml] = proc do |r|
|
158
|
-
require 'test/unit/ui/xml/testrunner'
|
159
|
-
Test::Unit::UI::XML::TestRunner
|
160
|
-
end
|
161
|
-
|
162
|
-
if __FILE__ == $0
|
163
|
-
Test::Unit::UI::XML::TestRunner.start_command_line_test
|
164
|
-
end
|
165
|
-
|
@@ -1,79 +0,0 @@
|
|
1
|
-
<?xml version="1.0"?>
|
2
|
-
<xsl:stylesheet
|
3
|
-
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
|
4
|
-
>
|
5
|
-
|
6
|
-
<xsl:output method="html" />
|
7
|
-
|
8
|
-
<xsl:template match="/testsuite">
|
9
|
-
<html>
|
10
|
-
<head>
|
11
|
-
<title>Test Suite Results for <xsl:value-of select="@name" /></title>
|
12
|
-
<style>
|
13
|
-
.error { color: #ff0000; }
|
14
|
-
.eresult {
|
15
|
-
background: #ffcccc;
|
16
|
-
color: #ff0000;
|
17
|
-
}
|
18
|
-
h1,h2 {
|
19
|
-
background: #cccccc;
|
20
|
-
color: #000055;
|
21
|
-
border: 1px dotted black;
|
22
|
-
}
|
23
|
-
</style>
|
24
|
-
</head>
|
25
|
-
<body>
|
26
|
-
<h1>Test Suite Results</h1>
|
27
|
-
|
28
|
-
<p>Results for: <xsl:value-of select="@name" /></p>
|
29
|
-
|
30
|
-
<p>
|
31
|
-
Test suite run at: <b><xsl:value-of select="@rundate" /></b>
|
32
|
-
</p>
|
33
|
-
|
34
|
-
<h2>Summary</h2>
|
35
|
-
|
36
|
-
<p>
|
37
|
-
<xsl:if test="result[@passed = 'false']">
|
38
|
-
<xsl:attribute name="class">error</xsl:attribute>
|
39
|
-
</xsl:if>
|
40
|
-
<xsl:value-of select="result/summary/text()" />
|
41
|
-
</p>
|
42
|
-
<p>
|
43
|
-
Elapsed time: <xsl:value-of select="elapsed-time/text()" />
|
44
|
-
</p>
|
45
|
-
|
46
|
-
<table border="1">
|
47
|
-
<tr>
|
48
|
-
<th>Case</th>
|
49
|
-
<th>Result</th>
|
50
|
-
</tr>
|
51
|
-
<xsl:for-each select="test">
|
52
|
-
<tr>
|
53
|
-
<td>
|
54
|
-
<xsl:if test="fault/text()">
|
55
|
-
<xsl:attribute name="class">error</xsl:attribute>
|
56
|
-
</xsl:if>
|
57
|
-
<xsl:value-of select="@name" />
|
58
|
-
</td>
|
59
|
-
<td>
|
60
|
-
<xsl:choose>
|
61
|
-
<xsl:when test="fault/text()">
|
62
|
-
<xsl:attribute name="class">eresult</xsl:attribute>
|
63
|
-
<pre>
|
64
|
-
<xsl:value-of select="fault/text()" />
|
65
|
-
</pre>
|
66
|
-
</xsl:when>
|
67
|
-
<xsl:otherwise>
|
68
|
-
(pass)
|
69
|
-
</xsl:otherwise>
|
70
|
-
</xsl:choose>
|
71
|
-
</td>
|
72
|
-
</tr>
|
73
|
-
</xsl:for-each>
|
74
|
-
</table>
|
75
|
-
</body>
|
76
|
-
</html>
|
77
|
-
</xsl:template>
|
78
|
-
|
79
|
-
</xsl:stylesheet>
|