rscm-accurev 0.0.3 → 0.0.4

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/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