rscm-accurev 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ require 'rake/rdoctask'
6
6
  require 'rake/packagetask'
7
7
  require 'rake/gempackagetask'
8
8
 
9
- # rakefile borrowed shamelessly from rscm
9
+ # this rakefile originally borrowed shamelessly from rscm
10
10
 
11
11
  PKG_NAME = 'rscm-accurev'
12
12
  PKG_BUILD = ENV['PKG_BUILD'] ? '.'+ENV['PKG_BUILD'] : ''
@@ -17,20 +17,52 @@ PKG_SUMMARY = 'RSCM::Accurev - RSCM API for Accurev'
17
17
  desc "Default Task"
18
18
  task :default => [ :test, :gem ]
19
19
 
20
- # define a task to run tests
21
- Rake::TestTask.new do |t|
20
+ #task :test => [ :backup_testresults, :xmltest ]
21
+
22
+ # define a task(s) to run tests
23
+
24
+ test_files = FileList.new( "test/**/t_*.rb" )
25
+ TEST_OUTPUT = "doc"
26
+
27
+ Rake::TestTask.new( :plaintest ) do |t|
22
28
  t.libs << "test"
23
- t.test_files = FileList.new( "test/**/t_*.rb" )
29
+ t.test_files = test_files
24
30
  t.verbose = true
25
31
  end
26
32
 
33
+ # requires a patch to rake_test_loader.rb to exclude options
34
+ # requires a patch to rake/testtask.rb to support ruby_opts
35
+ # (see doc/patches)
36
+ Rake::TestTask.new( :xmltest ) do |t|
37
+ t.libs << "test"
38
+ t.test_files = test_files
39
+ t.verbose = true
40
+ t.ruby_opts << '-rtest/unit/ui/xml/testrunner'
41
+ ENV['XMLTEST_OUTPUT'] = "#{TEST_OUTPUT}/testresults.xml"
42
+ t.options = "--runner=xml"
43
+ end
44
+
45
+ # backs up existing testresults.xml files in test target dir
46
+ task :backup_testresults do
47
+ old = "#{TEST_OUTPUT}/testresults.xml"
48
+ if File.exist?( old )
49
+ stat = File.stat( old )
50
+ bak = stat.ctime.strftime('testresults-%Y%m%d-%H%M.xml')
51
+ new = "#{TEST_OUTPUT}/#{bak}"
52
+ #puts "...Backing up previous test results to #{new}"
53
+ mv( old, new )
54
+ end
55
+ end
56
+
27
57
  # define a task to create rdocs
28
58
  # keep a reference to it so we can reuse it in the gempkg task
29
- rd_task = Rake::RDocTask.new do |rdoc|
59
+ rd_task = Rake::RDocTask.new( :rdoc ) do |rdoc|
30
60
  rdoc.title = PKG_SUMMARY
61
+ rdoc.template = "doc/jamis.rb" # so nice
31
62
  rdoc.options << '--line-numbers' << '--inline-source'
32
- #rdoc.rdoc_files.include( 'TODO' )
63
+ rdoc.rdoc_files.include( 'STATUS' )
33
64
  rdoc.rdoc_files.include( 'lib/**/*.rb' )
65
+ rdoc.rdoc_files.include( 'doc/*.rd' )
34
66
  end
35
67
 
36
68
  PKG_FILES = FileList[
@@ -64,5 +96,10 @@ else
64
96
  end
65
97
  end
66
98
 
99
+ desc "Delete all generated files (includes built packages)"
100
+ task :realclean => :clean do
101
+ f = FileList[ 'pkg', 'html', 'doc/test*.xml' ]
102
+ rm f
103
+ end
67
104
 
68
105
 
data/STATUS ADDED
@@ -0,0 +1,63 @@
1
+
2
+ = RSCM::Accurev Status
3
+
4
+ ------------------------
5
+
6
+ == Core RSCM API (RSCM::Accurev::API)
7
+
8
+ [checkout()] supported
9
+
10
+ - basic checkouts should work
11
+
12
+ - time-based checkouts do not work
13
+
14
+ [update()] basic updates work
15
+
16
+ - time-based updates ("update( yesterday )") not working
17
+
18
+ - elements list returned currently includes directories and removed files
19
+
20
+ [add()] unsupported, todo(?)
21
+
22
+ [edit()] supported (no-op)
23
+
24
+ [revisions()] supported
25
+
26
+ - time-based limits do not work
27
+
28
+ - should be history-based
29
+
30
+ -------------------------------------------
31
+
32
+ == Accurev-specific API (RSCM::Accurev::API)
33
+
34
+ [ac_update()] unsupported, todo
35
+
36
+ [ac_files()] supported
37
+
38
+ [ac_info()] supported
39
+
40
+ [ac_stat()] unsupported, use ac_files().
41
+
42
+ [ac_move()] unsupported, todo
43
+
44
+ [ac_pop()] unsupported, todo
45
+
46
+ [ac_purge()] unsupported, todo
47
+
48
+ [ac_hist()] unsupported, todo
49
+
50
+ [ac_keep()] unsupported, todo
51
+
52
+ [ac_promote()] unsupported, todo
53
+
54
+ -------------------------------------------
55
+
56
+ == Other Items
57
+
58
+ [code docs] woefully incomplete
59
+
60
+ [usage docs] virtually nonexistant
61
+
62
+ [test coverage] truly pitiful
63
+
data/TODO CHANGED
@@ -1,13 +1,13 @@
1
1
  # todo for rscm/scm/accurev.rb
2
2
 
3
- **api - checkout
3
+ api - checkout
4
4
  - there is no rscm-api update() (only checkout-to-existing-ws)
5
5
  - `pop`, `update`
6
6
 
7
7
  **api - revisions
8
8
  - `hist` (others?)
9
9
 
10
- **api - diff
10
+ api - diff
11
11
  - `diff` (yukx)
12
12
 
13
13
  api - import_central, create_central
@@ -21,10 +21,21 @@ api - triggers?
21
21
  **api - identifiers (Time or revision) to ac format
22
22
  - is this even always applicable? does stat/update take limits?
23
23
 
24
- xml - s/FileStatus/FileData/
24
+ # xml - s/FileStatus/FileData/
25
25
 
26
26
  api - checkout(Time.infinite) just does update
27
27
  checkout(x) only works if ws not exist
28
28
  unless it implies nuke-and-re-checkout (slow)
29
29
 
30
- api - need ac_update which returns an acresponse
30
+ api - need ac_update which returns an acresponse
31
+
32
+ api - update: elements list should not contain directories
33
+
34
+ api - update: elements list should probably not include removed files
35
+
36
+ # command - Command.working_dir is bad: should use with_working_dir()
37
+
38
+ *** api - checkout() should use `pop` instead of `mkws`, unless
39
+ user *really* wants it
40
+
41
+
data/lib/rscm/accurev.rb CHANGED
@@ -5,3 +5,13 @@ require 'rscm/scm/accurev/command'
5
5
  require 'rscm/scm/accurev/xml'
6
6
  require 'rscm/scm/accurev/filterio'
7
7
 
8
+ module RSCM
9
+ #
10
+ # == module RSCM::Accurev
11
+ #
12
+ # Namespace for accurev api classes and utils.
13
+ #
14
+ # See RSCM::Accurev::API.
15
+ #
16
+ module Accurev; end
17
+ end
@@ -1,4 +1,10 @@
1
1
  # -*- ruby -*-
2
+ #
3
+ # = api.rb
4
+ #
5
+ # API for interacting with accurev workspaces.
6
+ #
7
+ require 'stringio'
2
8
  require 'rubygems'
3
9
  require 'rscm/base'
4
10
  require 'rscm/path_converter'
@@ -7,12 +13,16 @@ require 'rscm/scm/accurev/xml'
7
13
  require 'rscm/scm/accurev/filterio'
8
14
  require 'rscm/scm/accurev/command'
9
15
 
10
- module RSCM
11
- module Accurev; end
12
- end
16
+ # need to define module within module before you can use module X::Y
17
+ module RSCM; module Accurev; end; end
13
18
 
14
19
  module RSCM::Accurev
15
20
 
21
+ #
22
+ # General exception class for errors processing commands.
23
+ #
24
+ # @attr error_msg Error message output by accurev.
25
+ #
16
26
  class AccurevException < Exception
17
27
  attr_reader :error_msg
18
28
  def initialize( msg, error_msg=nil )
@@ -21,12 +31,29 @@ module RSCM::Accurev
21
31
  end
22
32
  end
23
33
 
34
+ #
35
+ # Exception thrown when an update is performed
36
+ # on a workspace with unkept/unanchored modifications.
37
+ # Accurev requires that all modifications be handled before
38
+ # an update is performed.
39
+ #
24
40
  class StaleWorkspaceException < AccurevException; end
25
41
 
26
- # RSCM implementation for Accurev (http://www.accurev.com/).
27
42
  #
28
- # Requires an accurev cli executable on the path, and the correct
29
- # environment for ac server/principal/password.
43
+ # RSCM implementation for Accurev (http://www.accurev.com).
44
+ #
45
+ # Requires an accurev cli executable on the path (see also
46
+ # RSCM::Accurev::Command), and the correct environment
47
+ # configuration for ac server/principal/password.
48
+ #
49
+ # ---
50
+ #
51
+ # === Example
52
+ #
53
+ # api = RSCM::Accurev::API.new( "./ws/proj-1", "proj", "proj-1" )
54
+ # api.checkout() each do |file|
55
+ # puts "Updated #{file}..."
56
+ # end
30
57
  #
31
58
  class API < RSCM::Base
32
59
  register self
@@ -40,20 +67,21 @@ module RSCM::Accurev
40
67
  ann :description => "Workspace Stream"
41
68
  attr_accessor :workspace_stream
42
69
 
43
- # defined in Base
44
- # ann :description => "Filesystem Path to Workspace"
45
- # attr_accessor :checkout_dir
46
-
47
- STATUSES = {
48
- '(backed)' => :backed,
49
- '(external)' => :external,
50
- '(modified)' => :modified,
51
- '(kept)' => :kept,
52
- '(defunct)' => :defunct,
53
- '(missing)' => :missing,
54
- '(stranded)' => :stranded,
55
- '(overlap)' => :overlap
56
- }
70
+ # [defined in Base]
71
+ # ann :description => "Filesystem Path to Workspace"
72
+ # attr_accessor :checkout_dir
73
+
74
+ # status flag mappings for "stat", "file" commands
75
+ STATUSES = {
76
+ '(backed)' => :backed,
77
+ '(external)' => :external,
78
+ '(modified)' => :modified,
79
+ '(kept)' => :kept,
80
+ '(defunct)' => :defunct,
81
+ '(missing)' => :missing,
82
+ '(stranded)' => :stranded,
83
+ '(overlap)' => :overlap
84
+ }
57
85
 
58
86
  def initialize( checkout_dir=nil, depot=nil, workspace_stream=nil )
59
87
  @depot = depot
@@ -66,7 +94,7 @@ module RSCM::Accurev
66
94
  return "Accurev"
67
95
  end
68
96
 
69
- # Accurev operations are atomic:
97
+ # Accurev operations are atomic: returns true.
70
98
  def transactional?
71
99
  return true
72
100
  end
@@ -105,10 +133,12 @@ module RSCM::Accurev
105
133
  def ac_files( relative_path )
106
134
  cmd = Command.instance
107
135
  ret = []
108
- acresponse = cmd.accurev( "files", relative_path )
109
- acresponse['element'].each do |fd|
110
- yield fd if block_given?
111
- ret << fd
136
+ with_working_dir( @checkout_dir ) do
137
+ acresponse = cmd.accurev( "files", relative_path )
138
+ acresponse['element'].each do |fd|
139
+ yield fd if block_given?
140
+ ret << fd
141
+ end
112
142
  end
113
143
  return ret
114
144
  end
@@ -140,9 +170,32 @@ module RSCM::Accurev
140
170
  raise "XXX implement me"
141
171
  end
142
172
 
173
+ #
174
+ # Performs an "accurev info" command in the workspace.
175
+ # Returns a map of
176
+ #
143
177
  # ac info: shows eg, backing stream
144
- # but doesn't support -fx!
145
-
178
+ # but doesn't support -fx!
179
+ #
180
+ def ac_info()
181
+ co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
182
+ unless File.exists?( co )
183
+ raise AccurevException.new( "Checkout dir does not exist" )
184
+ end
185
+ info = {}
186
+ with_working_dir( co ) do
187
+ cmd = Command.instance
188
+ io = StringIO.new( cmd.accurev_nofx( "info" ) )
189
+ io.each_line do |line|
190
+ next unless line =~ /\S/
191
+ if line =~ /^(.*?):\s+(.*)$/
192
+ info[$1] = $2
193
+ end
194
+ end
195
+ end
196
+ return info
197
+ end
198
+
146
199
  # ac mkws
147
200
  # -b orbitz-host-gt3-0-impl
148
201
  # -w orbitz-host-gt3-0-impl-test2_gfast
@@ -156,7 +209,7 @@ module RSCM::Accurev
156
209
  # (eg, no in-process diffing ala cvs diff)
157
210
  # lists modified lines in xml
158
211
 
159
- # checkout():
212
+ #
160
213
  # "Checks out or updates[!] contents from a central SCM
161
214
  # to +checkout_dir+ - a local working copy."
162
215
  #
@@ -164,20 +217,21 @@ module RSCM::Accurev
164
217
  # obtain files up to a particular time or label."
165
218
  #
166
219
  # For accurev, this:
167
- # * checks to see if @checkout_dir exists and appears checked out.
168
- # If it's already checked out, this calls update().
220
+ # * checks to see if +@checkout_dir+ exists and appears checked out.
221
+ # If it's already checked out, this calls +update()+. If
222
+ # +@checkout_dir+ exists and +to_identifier+ is given, an
223
+ # exception is raised.
169
224
  # * otherwise, this creates a new workspace stream and populates it
170
- # at @checkout_dir.
225
+ # at +@checkout_dir+.
171
226
  #
172
- # Unknown: support for +to_identifier+ (esp for update)?
227
+ # This both returns and yields a list of updated files.
228
+ # Only updated files are returned, not directories.
229
+ #
230
+ # Current, ac_update returns both files and directories, including
231
+ # deleted files.
173
232
  #
174
- # This method yields files in the workspace and doesn't need to be
175
- # overridden.
176
- # The checkout_silent() method does the actual work.
177
- #
178
- # Only yields files, not directories
179
233
  def checkout( to_identifier=Time.infinite )
180
- co = PathConverter.nativepath_to_filepath( @checkout_dir )
234
+ co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
181
235
  unless File.exists?( co )
182
236
  puts "> creating new workspace..."
183
237
  if @backing_stream.nil?
@@ -186,13 +240,16 @@ module RSCM::Accurev
186
240
  if @workspace_stream.nil?
187
241
  raise "Workspace stream must be set"
188
242
  end
189
- mkws_out = self.accurev_nofx( "mkws",
190
- "-b", @backing_stream,
191
- "-w", @workspace_stream,
192
- "-l", co )
193
- # sucks:
194
- if ( mkws_out =~ /already exists/ )
195
- raise AccurevException.new( "Failed to checkout", mkws_out )
243
+ Command.instance do |cmd|
244
+ cmd.working_dir = co
245
+ mkws_out = cmd.accurev_nofx( "mkws",
246
+ "-b", @backing_stream,
247
+ "-w", @workspace_stream,
248
+ "-l", co )
249
+ # sucks:
250
+ if ( mkws_out =~ /already exists/ )
251
+ raise AccurevException.new( "Failed to checkout", mkws_out )
252
+ end
196
253
  end
197
254
  end
198
255
  puts "> Updating workspace.."
@@ -205,8 +262,8 @@ module RSCM::Accurev
205
262
  raise AccurevException.new( "Workspace does not exist!" )
206
263
  end
207
264
  updated = []
208
- Command.instance do |cmd|
209
- cmd.working_dir = co
265
+ with_working_dir( co ) do
266
+ cmd = Command.instance
210
267
  acresponse = cmd.accurev( "update" )
211
268
  if acresponse.error
212
269
  if acresponse.error =~ /workspace have been modified/
@@ -219,8 +276,12 @@ module RSCM::Accurev
219
276
  end
220
277
  if acresponse['element']
221
278
  acresponse['element'].each do |up|
222
- yield up.location if block_given?
223
- updated << up.location
279
+ # "ac update" on a new workspace yields element locations
280
+ # with leading "/"s, which should be removed to get a proper
281
+ # relative path:
282
+ loc = up.location.sub( /^\//, "" )
283
+ yield loc if block_given?
284
+ updated << loc
224
285
  end
225
286
  end
226
287
  end
@@ -240,3 +301,7 @@ module RSCM::Accurev
240
301
  end
241
302
 
242
303
  end
304
+
305
+ #
306
+ # Copyright (c) 2005 Gregory D. Fast <gdf@speakeasy.net>
307
+ #
@@ -10,7 +10,7 @@ module RSCM
10
10
  #
11
11
  class Command
12
12
 
13
- attr_accessor :debug, :debug_to, :accurev_bin, :working_dir
13
+ attr_accessor :debug, :debug_to, :accurev_bin
14
14
 
15
15
  # If you need to swap out the mapper class
16
16
  attr_accessor :xmlmapper
@@ -20,7 +20,6 @@ module RSCM
20
20
  @debug = false
21
21
  @debug_to = STDOUT
22
22
  @accurev_bin = "accurev"
23
- @working_dir = "."
24
23
  end
25
24
 
26
25
  #
@@ -41,10 +40,10 @@ module RSCM
41
40
  # `-fx` for xml output.)
42
41
  #
43
42
  def accurev_nofx( cmd, *opts )
44
- # nativepath_to_filepath is actually generic to native
45
- dir = PathConverter.nativepath_to_filepath( @working_dir )
46
- dir = File.expand_path( dir )
47
- with_working_dir( dir ) do
43
+ ## # nativepath_to_filepath is actually generic to native
44
+ ## dir = PathConverter.nativepath_to_filepath( @working_dir )
45
+ ## dir = File.expand_path( dir )
46
+ ## with_working_dir( dir ) do
48
47
  cmdline = self.accurev_cmdline( cmd, opts )
49
48
  if @debug
50
49
  @debug_to.puts("ac> #{cmdline}")
@@ -52,7 +51,7 @@ module RSCM
52
51
  Better.popen( cmdline ) do |stdout|
53
52
  return stdout.read()
54
53
  end
55
- end
54
+ ## end
56
55
  end
57
56
 
58
57
  #
@@ -67,11 +66,11 @@ module RSCM
67
66
  # accurev subcommands support the "-fx" option.
68
67
  #
69
68
  def accurev_xml( cmd, *opts )
70
- # nativepath_to_filepath is actually generic to native
71
- dir = PathConverter.nativepath_to_filepath( @working_dir )
72
- dir = File.expand_path( dir )
73
69
  opts << "-fx"
74
- with_working_dir( dir ) do
70
+ ## # nativepath_to_filepath is actually generic to native
71
+ ## dir = PathConverter.nativepath_to_filepath( @working_dir )
72
+ ## dir = File.expand_path( dir )
73
+ ## with_working_dir( dir ) do
75
74
  cmdline = self.accurev_cmdline( cmd, opts )
76
75
  if @debug
77
76
  @debug_to.puts("ac> #{cmdline}")
@@ -88,7 +87,7 @@ module RSCM
88
87
  raise "Unexpected output from #{cmdline}: #{e}"
89
88
  end
90
89
  end
91
- end
90
+ ## end
92
91
  end
93
92
 
94
93
  #
@@ -3,17 +3,19 @@ require 'stringio'
3
3
  module RSCM
4
4
  module Accurev
5
5
 
6
+ #
6
7
  # IO stream which cleans irregularities out of accurev xml output.
7
8
  #
8
9
  # In particular:
9
10
  #
10
- # * the -fx output from `accurev update` has a root element of
11
- # <acResponse>, not <AcResponse> like the other commands
11
+ # * Unlike other commands, the +-fx+ output from _accurev update_
12
+ # has a root element of +<acResponse>+, not +<AcResponse>+.
12
13
  #
13
- # * `accurev update` emits broken XML when there are no files
14
- # needing updates.
14
+ # * _accurev update_ emits broken XML when there are no files
15
+ # to update.
15
16
  #
16
17
  class AcXMLScrubIO < StringIO
18
+
17
19
  # @param: sourceio - io or string source to wrap
18
20
  def initialize( sourceio )
19
21
  if sourceio.respond_to?( :read )
@@ -11,9 +11,11 @@ module RSCM::Accurev
11
11
  # and builds a new object of that type from the element.
12
12
  #
13
13
  # The nodename-class associations are determined by finding all
14
- # classes derived from +RSCM::Accurev::ElementBackedClass+ and checking
14
+ # classes derived from ElementBackedClass and checking
15
15
  # each of those classes +element_name+ methods.
16
16
  #
17
+ # See ElementBackedClass for examples.
18
+ #
17
19
  class XMLMapper
18
20
 
19
21
  # Map of element (tag) names to (ruby) class.
@@ -55,19 +57,47 @@ module RSCM::Accurev
55
57
  end
56
58
 
57
59
  #
58
- # Generic base class for defining typed mirror classes for XML elements.
60
+ # Abstract base class for defining typed mirror classes for XML elements.
59
61
  #
60
62
  # A subclass of ElementBackedClass has:
61
63
  #
62
- # * A class static +element_name+ method, identifying what
63
- # type of XML element it shadows
64
+ # * A class static +element_name+ method, identifying what
65
+ # type of XML element it shadows
66
+ #
67
+ # * A set of attributes shadowing the XML attributes of its target element
68
+ #
69
+ # * A map (+children+) of child elements, keyed by element name
70
+ #
71
+ # * A (optional) +text_content+ attribute, populated when the
72
+ # target element has text subnodes.
73
+ #
74
+ # ---
75
+ #
76
+ # === Example
77
+ #
78
+ # For the XML element:
79
+ #
80
+ # <book title="The Monkey Wrench Gang" author="Edward Albee">
81
+ # <note>Lots of beer and dynamite</note>
82
+ # </book>
83
+ #
84
+ # You can define:
64
85
  #
65
- # * A set of attributes shadowing the XML attributes of its target element
86
+ # class Book < ElementBackedClass
87
+ # element_name 'book'
88
+ # attr_accessor :title, :author
89
+ # end
66
90
  #
67
- # * A map (+children+) of child elements, keyed by element name
91
+ # And then use XMLMapper to create instances:
68
92
  #
69
- # * A (optional) +text_content+ attribute, populated when the
70
- # target element has text subnodes.
93
+ # e = ...; # <book> node: REXML::Element
94
+ # book = XMLMapper.map(e)
95
+ # puts "Title: #{book.title}"
96
+ # puts "Author: #{book.author}"
97
+ # puts "Notes:"
98
+ # book['note'].each do |n|
99
+ # puts n.text_content
100
+ # end
71
101
  #
72
102
  class ElementBackedClass
73
103
 
@@ -0,0 +1,165 @@
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
+
@@ -0,0 +1,79 @@
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>
data/test/eg/info.txt ADDED
@@ -0,0 +1,14 @@
1
+
2
+ Principal: gfast
3
+ Shell: /bin/zsh
4
+ Host: gfast.duncllc.com
5
+ Domain: (none)
6
+ server_name: accurev.duncllc.com
7
+ port: 5050
8
+ ACCUREV_BIN: /usr/local/accurev/bin
9
+ client_time: 2005/08/16 08:56:13 CDT (1124200573)
10
+ server_time: 2005/08/16 08:56:14 CDT (1124200574)
11
+ Depot: orbitz-api-hiredcar
12
+ ws/ref: orbitz-api-hiredcar-0-rc-testing_gfast
13
+ Basis: orbitz-api-hiredcar-1-rc
14
+ Top: /home/gfast/dev/orbitz-api-hirdcar-0-rc
data/test/t_api.rb CHANGED
@@ -7,11 +7,10 @@ include RSCM::Accurev
7
7
  class AccurevAPITest < Test::Unit::TestCase
8
8
 
9
9
  def test_ac_files()
10
- Command.instance do |cmd|
11
- cmd.working_dir = "test"
10
+ Command.instance do |cmd|
12
11
  cmd.accurev_bin = "./acreplay.rb eg/ac-files.xml"
13
12
  end
14
- api = API.new( ".", "test-bogus-depot", "test-bogus-depot-0-impl" )
13
+ api = API.new( "test", "test-bogus-depot", "test-bogus-depot-0-impl" )
15
14
  # test array returns
16
15
  files = api.ac_files( "." )
17
16
  assert( files.length > 0, "Should get some stat-ed files" )
@@ -62,15 +61,61 @@ class AccurevAPITest < Test::Unit::TestCase
62
61
  assert_equal( 44, u_elements.length )
63
62
  u_elements.each do |location|
64
63
  # api.update returns a list of relative filenames
65
- assert( location =~ /^\// )
64
+ assert( location =~ /^[^\/]/, "Location '#{location}' should be a relpath" )
66
65
  end
67
66
  # test yield and array return XXX
68
67
  updated = 0
69
68
  api.update().each do |location|
70
69
  updated += 1
71
- assert( location =~ /^\// )
70
+ assert( location =~ /^[^\/]/, "Location '#{location}' should be a relpath" )
72
71
  end
73
72
  assert_equal( 44, updated )
74
73
  end
75
74
 
75
+ # update-updates.xml - update with updated files
76
+ def test_update_updates()
77
+ Command.instance do |cmd|
78
+ cmd.accurev_bin = "./acreplay.rb eg/update-updates.xml"
79
+ end
80
+ api = API.new( "test", "test-bogus-depot", "test-bogus-depot-0-impl" )
81
+ # XXX elements in elements list are just "modified" -
82
+ # may have been removed!
83
+ # XXX update() should return only filenames, right? eliminate dirs
84
+ ue = api.update()
85
+ assert_not_nil( ue )
86
+ assert_equal( 23, ue.length )
87
+ ue.each do |location|
88
+ assert( location =~ /^[^\/]/, "Location '#{location}' should be a relpath" )
89
+ end
90
+ # yielding behavior
91
+ updated = 0
92
+ api.update().each do |location|
93
+ updated += 1
94
+ assert( location =~ /^[^\/]/, "Location '#{location}' should be a relpath" )
95
+ end
96
+ assert_equal( 23, updated )
97
+ end
98
+
99
+ def test_info()
100
+ Command.instance do |cmd|
101
+ cmd.accurev_bin = "./acreplay.rb eg/info.txt"
102
+ end
103
+ api = API.new( "test", "depot", "stream" )
104
+ info = api.ac_info()
105
+ assert( info.size == 13 )
106
+ # some crap
107
+ assert_equal( "gfast", info['Principal'] )
108
+ assert_equal( "5050", info['port'] )
109
+ assert_equal( "/usr/local/accurev/bin", info['ACCUREV_BIN'] )
110
+ # the interesting stuff:
111
+ # - depot name
112
+ assert_equal( "orbitz-api-hiredcar", info['Depot'] )
113
+ # - workspace or reference stream name
114
+ assert_equal( "orbitz-api-hiredcar-0-rc-testing_gfast", info['ws/ref'] )
115
+ # - basis stream name
116
+ assert_equal( "orbitz-api-hiredcar-1-rc", info['Basis'] )
117
+ # - workspace checkout location
118
+ assert_equal( "/home/gfast/dev/orbitz-api-hirdcar-0-rc", info['Top'] )
119
+ end
120
+
76
121
  end
data/test/t_command.rb CHANGED
@@ -23,18 +23,20 @@ class CommandTest < Test::Unit::TestCase
23
23
 
24
24
  def test_a_e
25
25
  cmd = Command.instance
26
- cmd.working_dir = "test"
26
+ ## cmd.working_dir = "test"
27
27
  cmd.debug = true
28
28
  cmd.debug_to = File.open( "/tmp/testing.log", "w" )
29
29
  cmd.accurev_bin = "./acreplay.rb eg/update-newwksp.xml"
30
30
  # test listy output
31
- acresponse = cmd.accurev( "files" )
32
- assert_not_nil( acresponse )
33
- assert( acresponse.kind_of?( AcResponseData ) )
34
- assert( acresponse['element'].size == 44 )
35
- assert( acresponse['message'].size == 44 )
36
- acresponse['element'].each do |e|
37
- assert( e.kind_of?( ElementData ) )
31
+ with_working_dir( "test" ) do
32
+ acresponse = cmd.accurev( "files" )
33
+ assert_not_nil( acresponse )
34
+ assert( acresponse.kind_of?( AcResponseData ) )
35
+ assert( acresponse['element'].size == 44 )
36
+ assert( acresponse['message'].size == 44 )
37
+ acresponse['element'].each do |e|
38
+ assert( e.kind_of?( ElementData ) )
39
+ end
38
40
  end
39
41
  Command.discard
40
42
  end
@@ -52,29 +54,29 @@ class CommandTest < Test::Unit::TestCase
52
54
  # instance returns this thread's Command object
53
55
  begin
54
56
  cmd = Command.instance
55
- cmd.working_dir = "/one/two/three"
56
- assert_equal( cmd.working_dir, "/one/two/three" )
57
+ cmd.accurev_bin = "/bin/bash"
58
+ assert_equal( cmd.accurev_bin, "/bin/bash" )
57
59
  end
58
60
  # and calling it again returns the same object
59
61
  begin
60
62
  cmd = Command.instance
61
- assert_equal( cmd.working_dir, "/one/two/three" )
63
+ assert_equal( cmd.accurev_bin, "/bin/bash" )
62
64
  end
63
65
  # but instance in another thread should be different
64
66
  Thread.new do
65
67
  cmd = Command.instance
66
- assert_not_equal( cmd.working_dir, "/one/two/three" )
68
+ assert_not_equal( cmd.accurev_bin, "/bin/bash" )
67
69
  end.join()
68
70
  # ...and calling it *again* returns the same object
69
71
  begin
70
72
  cmd = Command.instance
71
- assert_equal( cmd.working_dir, "/one/two/three" )
73
+ assert_equal( cmd.accurev_bin, "/bin/bash" )
72
74
  end
73
75
  # but discard tosses this thread's object:
74
76
  Command.discard
75
77
  begin
76
78
  cmd = Command.instance
77
- assert_not_equal( cmd.working_dir, "/one/two/three" )
79
+ assert_not_equal( cmd.accurev_bin, "/bin/bash" )
78
80
  end
79
81
 
80
82
  end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: rscm-accurev
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.0.3
7
- date: 2005-08-15 00:00:00 -05:00
6
+ version: 0.0.4
7
+ date: 2005-08-21 00:00:00 -05:00
8
8
  summary: "RSCM::Accurev - RSCM API for Accurev"
9
9
  require_paths:
10
10
  - lib
@@ -31,15 +31,17 @@ authors:
31
31
  files:
32
32
  - apitest.rb
33
33
  - bumprelease.sh
34
+ - doc
34
35
  - lib
35
36
  - LICENSE
36
- - pkg
37
37
  - Rakefile
38
38
  - README
39
+ - STATUS
39
40
  - test
40
41
  - tmp
41
42
  - TODO
42
43
  - lib/rscm
44
+ - lib/test
43
45
  - lib/rscm/accurev.rb
44
46
  - lib/rscm/scm
45
47
  - lib/rscm/scm/accurev
@@ -47,6 +49,11 @@ files:
47
49
  - lib/rscm/scm/accurev/command.rb
48
50
  - lib/rscm/scm/accurev/filterio.rb
49
51
  - lib/rscm/scm/accurev/xml.rb
52
+ - lib/test/unit
53
+ - lib/test/unit/ui
54
+ - lib/test/unit/ui/xml
55
+ - lib/test/unit/ui/xml/testrunner.rb
56
+ - lib/test/unit/ui/xml/xmltestrunner.xslt
50
57
  - test/acreplay.rb
51
58
  - test/eg
52
59
  - test/t_api.rb
@@ -56,6 +63,7 @@ files:
56
63
  - test/t_scrubio.rb
57
64
  - test/t_xmlmapper.rb
58
65
  - test/eg/ac-files.xml
66
+ - test/eg/info.txt
59
67
  - test/eg/update-i-nochanges.xml
60
68
  - test/eg/update-i-updates.xml
61
69
  - test/eg/update-newwksp.xml