rscm 0.1.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.
Files changed (43) hide show
  1. data/README +198 -0
  2. data/Rakefile +118 -0
  3. data/ext/rscm.jar +0 -0
  4. data/lib/rscm.rb +10 -0
  5. data/lib/rscm/abstract_log_parser.rb +49 -0
  6. data/lib/rscm/abstract_scm.rb +229 -0
  7. data/lib/rscm/changes.rb +271 -0
  8. data/lib/rscm/cvs/cvs.rb +363 -0
  9. data/lib/rscm/cvs/cvs_log_parser.rb +161 -0
  10. data/lib/rscm/darcs/darcs.rb +69 -0
  11. data/lib/rscm/line_editor.rb +46 -0
  12. data/lib/rscm/logging.rb +5 -0
  13. data/lib/rscm/monotone/monotone.rb +107 -0
  14. data/lib/rscm/mooky/mooky.rb +13 -0
  15. data/lib/rscm/parser.rb +39 -0
  16. data/lib/rscm/path_converter.rb +92 -0
  17. data/lib/rscm/perforce/perforce.rb +415 -0
  18. data/lib/rscm/starteam/starteam.rb +99 -0
  19. data/lib/rscm/svn/svn.rb +337 -0
  20. data/lib/rscm/svn/svn_log_parser.rb +134 -0
  21. data/lib/rscm/time_ext.rb +125 -0
  22. data/test/rscm/apply_label_scm_tests.rb +26 -0
  23. data/test/rscm/changes_fixture.rb +20 -0
  24. data/test/rscm/changes_test.rb +129 -0
  25. data/test/rscm/cvs/cvs_log_parser_test.rb +575 -0
  26. data/test/rscm/cvs/cvs_test.rb +22 -0
  27. data/test/rscm/darcs/darcs_test.rb +14 -0
  28. data/test/rscm/difftool_test.rb +40 -0
  29. data/test/rscm/file_ext.rb +12 -0
  30. data/test/rscm/generic_scm_tests.rb +282 -0
  31. data/test/rscm/line_editor_test.rb +76 -0
  32. data/test/rscm/mockit.rb +130 -0
  33. data/test/rscm/mockit_test.rb +117 -0
  34. data/test/rscm/monotone/monotone_test.rb +19 -0
  35. data/test/rscm/mooky/mooky_test.rb +14 -0
  36. data/test/rscm/parser_test.rb +47 -0
  37. data/test/rscm/path_converter_test.rb +52 -0
  38. data/test/rscm/perforce/perforce_test.rb +14 -0
  39. data/test/rscm/starteam/starteam_test.rb +36 -0
  40. data/test/rscm/svn/svn_log_parser_test.rb +111 -0
  41. data/test/rscm/svn/svn_test.rb +28 -0
  42. data/test/rscm/tempdir.rb +12 -0
  43. metadata +81 -0
@@ -0,0 +1,130 @@
1
+ require 'test/unit/assertions'
2
+
3
+ module MockIt
4
+
5
+ def setup
6
+ @to_verify = []
7
+ end
8
+ module_function :setup
9
+
10
+ def teardown
11
+ super
12
+ if(@test_passed && @to_verify)
13
+ @to_verify.each{|m| m.__verify}
14
+ end
15
+ end
16
+
17
+ def new_mock
18
+ mock = MockIt::Mock.new
19
+ @to_verify = [] unless @to_verify
20
+ @to_verify << mock
21
+ mock
22
+ end
23
+
24
+ class Mock
25
+ include Test::Unit::Assertions
26
+
27
+ def initialize
28
+ @expected_methods=[]
29
+ @expected_validation_procs=[]
30
+ @setup_call_procs={}
31
+ @unexpected_calls = []
32
+ end
33
+
34
+ def __expect(method, &validation_proc)
35
+ validation_proc=Proc.new {|*args| nil} if validation_proc.nil?
36
+ @expected_methods<<method
37
+ @expected_validation_procs<<validation_proc
38
+ self
39
+ end
40
+
41
+ def __setup(method, &proc)
42
+ proc=Proc.new {|*args| nil} if proc.nil?
43
+ @setup_call_procs[method]=proc
44
+ self
45
+ end
46
+
47
+ def __verify
48
+ begin
49
+ assert_no_unexpected_calls
50
+ assert_all_expected_methods_called
51
+ ensure
52
+ initialize
53
+ end
54
+ end
55
+
56
+ def method_missing(method, *args, &proc)
57
+ if(is_expected_call(method))
58
+ handle_expected_call(method, *args, &proc)
59
+ elsif(is_setup_call(method))
60
+ handle_setup_call(method, *args, &proc)
61
+ else
62
+ handle_unexpected_call(method)
63
+ end
64
+ end
65
+
66
+ def respond_to?(method)
67
+ return super.respond_to?(method) if super.respond_to?(method)
68
+ method = symbol(method)
69
+ return true if is_setup_call(method)
70
+ return true if currently_expected_method == method
71
+ false
72
+ end
73
+
74
+ private
75
+
76
+ def symbol(string)
77
+ return nil if string==""
78
+ if string.is_a? String then string.intern else string end
79
+ end
80
+
81
+ def assert_no_unexpected_calls
82
+ assert_equal([], @unexpected_calls, "got unexpected call")
83
+ end
84
+
85
+ def assert_all_expected_methods_called
86
+ assert(@expected_validation_procs.empty?, "not all expected methods called, calls left: #{@expected_methods.inspect}")
87
+ end
88
+
89
+ def is_expected_call(method)
90
+ @expected_methods.index(method)
91
+ end
92
+
93
+ def is_setup_call(method)
94
+ not @setup_call_procs[method].nil?
95
+ end
96
+
97
+ def handle_setup_call(method, *args, &proc)
98
+ @setup_call_procs[method].call(*args, &proc)
99
+ end
100
+
101
+ def handle_expected_call(method, *args, &proc)
102
+ assert_equal(currently_expected_method, method, "got unexpected call")
103
+ validation_proc = current_validation_proc
104
+ next_call
105
+ validation_proc.call(*args, &proc)
106
+ end
107
+
108
+ def handle_unexpected_call(method)
109
+ @unexpected_calls << method
110
+ flunk("Unexpected method invocation: #{method}")
111
+ end
112
+
113
+ def currently_expected_method
114
+ if @expected_methods.empty? then nil
115
+ else @expected_methods[0] end
116
+ end
117
+
118
+ def current_validation_proc
119
+ if @expected_validation_procs.empty? then nil
120
+ else @expected_validation_procs[0] end
121
+ end
122
+
123
+ def next_call
124
+ @expected_methods.delete_at(0)
125
+ @expected_validation_procs.delete_at(0)
126
+ end
127
+
128
+ end
129
+ end
130
+
@@ -0,0 +1,117 @@
1
+ require 'test/unit'
2
+ require 'rscm/mockit'
3
+
4
+ module MockIt
5
+ class MockTest < Test::Unit::TestCase
6
+ def setup
7
+ @mock = Mock.new
8
+ end
9
+
10
+ def test_unmocked_call_fails
11
+ assert_raises(Test::Unit::AssertionFailedError) do
12
+ @mock.unmocked_call
13
+ end
14
+ end
15
+
16
+ def test_call_to_unexpected_call_fails
17
+ assert_raises(Test::Unit::AssertionFailedError) do
18
+ @mock.expected_not_called
19
+ end
20
+ end
21
+
22
+ def test_expected_call_works
23
+ @mock.__expect(:expected_call)
24
+ @mock.expected_call
25
+ end
26
+
27
+ def test_sequential_expected_methods_work
28
+ @mock.__expect(:expected_call1)
29
+ @mock.__expect(:expected_call2)
30
+ @mock.expected_call1
31
+ @mock.expected_call2
32
+ end
33
+
34
+ def test_sequential_expected_methods_in_wrong_order_fails
35
+ @mock.__expect(:expected_call1)
36
+ @mock.__expect(:expected_call2)
37
+ assert_raises(Test::Unit::AssertionFailedError) do
38
+ @mock.expected_call2
39
+ @mock.expected_call1
40
+ end
41
+ end
42
+
43
+ def test_provided_block_can_validate_arguments
44
+ @mock.__expect(:expected_call) {|arg| assert_equal("arg", arg)}
45
+ assert_raises(Test::Unit::AssertionFailedError) do
46
+ @mock.expected_call("incorrect arg")
47
+ end
48
+ end
49
+
50
+ def DOESNT_WORK_test_provided_block_can_validate_whether_block_was_given
51
+ @mock.__expect(:expect_call_with_block) { assert(block_given?) }
52
+ @mock.expect_call_with_block do end
53
+ end
54
+
55
+ def test_provided_block_can_validate_whether_block_was_not_given
56
+ @mock.__expect(:expect_call_without_block) { assert(!block_given?) }
57
+ @mock.expect_call_without_block
58
+ end
59
+
60
+ def test_provided_block_can_validate_several_arguments
61
+ @mock.__expect(:expected_call) {|*args| assert_equal(["arg1", "arg2"], args)}
62
+ @mock.expected_call("arg1", "arg2")
63
+ end
64
+
65
+ def test_verify_fails_if_not_all_expected_methods_were_called
66
+ @mock.__expect(:expected_call)
67
+ assert_raises(Test::Unit::AssertionFailedError) do
68
+ @mock.__verify
69
+ end
70
+ end
71
+
72
+ def test_setup_method_can_always_be_called_and_procs_returns_value
73
+ @mock.__setup(:setup_call) {|| :return_value}
74
+ assert_equal(:return_value, @mock.setup_call)
75
+ assert_equal(:return_value, @mock.setup_call)
76
+ assert_equal(:return_value, @mock.setup_call)
77
+ end
78
+
79
+ def test_respond_to_gives_true_for_setups_but_not_for_others
80
+ @mock.__setup(:setup_method)
81
+ assert(@mock.respond_to?(:setup_method))
82
+ assert(@mock.respond_to?("setup_method"))
83
+ assert(!@mock.respond_to?(:other_method))
84
+ assert(!@mock.respond_to?("other_method"))
85
+ end
86
+
87
+ def test_respond_to_gives_true_for_currently_expected_method_but_not_for_others
88
+ @mock.__expect(:expected_method)
89
+ assert(@mock.respond_to?(:expected_method))
90
+ assert(@mock.respond_to?("expected_method"))
91
+ assert(!@mock.respond_to?(:other_method))
92
+ assert(!@mock.respond_to?("other_method"))
93
+ end
94
+
95
+ def test_can_verify_several_times_with_different_excepts
96
+ @mock.__expect(:expected_method)
97
+ @mock.expected_method
98
+ @mock.__verify
99
+ @mock.__expect(:another_expected_method)
100
+ @mock.another_expected_method
101
+ @mock.__verify
102
+ end
103
+
104
+ def test_verify_fails_if_got_unexpected_call
105
+ assert_raises(Test::Unit::AssertionFailedError) do
106
+ @mock.unexpected_call
107
+ end
108
+ assert_raises(Test::Unit::AssertionFailedError) do
109
+ @mock.__verify
110
+ end
111
+ # should reset state after __verify
112
+ @mock.__verify
113
+ end
114
+
115
+ end
116
+
117
+ end
@@ -0,0 +1,19 @@
1
+ require 'test/unit'
2
+ require 'rscm/generic_scm_tests'
3
+ require 'rscm/monotone/monotone'
4
+
5
+ module RSCM
6
+ class MonotoneTest < Test::Unit::TestCase
7
+ include GenericSCMTests
8
+
9
+ def create_scm(repository_root_dir, path)
10
+ mt = Monotone.new(
11
+ "#{repository_root_dir}/MT.db",
12
+ "com.example.testproject",
13
+ "tester@test.net",
14
+ "tester@test.net",
15
+ File.dirname(__FILE__) + "/keys"
16
+ )
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ require 'test/unit'
2
+ require 'fileutils'
3
+ require 'rscm/generic_scm_tests'
4
+ require 'rscm/mooky/mooky'
5
+
6
+ module RSCM
7
+ class MookyTest < Test::Unit::TestCase
8
+ include GenericSCMTests
9
+
10
+ def create_scm(repository_root_dir, path)
11
+ Mooky.new
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,47 @@
1
+ require 'test/unit'
2
+ require 'stringio'
3
+ require 'rscm/parser'
4
+
5
+ module RSCM
6
+ class ParserTest < Test::Unit::TestCase
7
+
8
+ class TestParser < Parser
9
+ def initialize
10
+ super(/^-+$/)
11
+ @result = ""
12
+ end
13
+
14
+ protected
15
+
16
+ def parse_line(line)
17
+ @result << line
18
+ end
19
+
20
+ def next_result
21
+ r = @result
22
+ @result = ""
23
+ r
24
+ end
25
+ end
26
+
27
+ def test_can_parse_until_line_inclusive
28
+ parser = TestParser.new
29
+ io = StringIO.new(TEST_DATA)
30
+ parser.parse(io) {|line|}
31
+ assert_equal("one\ntwo\n", parser.parse(io))
32
+ assert_equal("three\nfour\n", parser.parse(io))
33
+ end
34
+
35
+ TEST_DATA = <<EOF
36
+ bla bla
37
+ --
38
+ one
39
+ two
40
+ --
41
+ three
42
+ four
43
+ --
44
+ EOF
45
+
46
+ end
47
+ end
@@ -0,0 +1,52 @@
1
+ require 'test/unit'
2
+ require 'rscm/path_converter'
3
+
4
+ module RSCM
5
+ class PathConverterTest < Test::Unit::TestCase
6
+ include PathConverter
7
+
8
+ def test_should_convert_os_path_to_native_path
9
+ p1 = nil
10
+ n1 = nil
11
+ n2 = nil
12
+
13
+ if(WIN32)
14
+ p1 = "c:\\scm\\damagecontrol"
15
+ n1 = p1
16
+ n2 = p1
17
+ elsif(CYGWIN)
18
+ p1 = "/cygdrive/c/scm/damagecontrol"
19
+ n1 = "c:\\scm\\damagecontrol"
20
+ # This format is needed when passing to an IO.popen on non-cygwin windows tools (like windows native svn)
21
+ n2 = "c:\\\\scm\\\\damagecontrol"
22
+ else
23
+ p1 = "/cygdrive/c/scm/damagecontrol"
24
+ n1 = p1
25
+ n2 = p1
26
+ end
27
+ assert_equal(n1, filepath_to_nativepath(p1, false))
28
+ assert_equal(n2, filepath_to_nativepath(p1, true))
29
+
30
+ assert_equal(p1, nativepath_to_filepath(n2))
31
+ assert_equal(p1, nativepath_to_filepath(n1))
32
+ end
33
+
34
+ def test_should_convert_os_path_to_native_url
35
+ path = nil
36
+ nativeurl = nil
37
+
38
+ if(WIN32)
39
+ path = "c:/scm/damagecontrol"
40
+ nativeurl = "file:///c:/scm/damagecontrol"
41
+ elsif(CYGWIN)
42
+ path = "/cygdrive/c/scm/damagecontrol"
43
+ nativeurl = "file:///c:/scm/damagecontrol"
44
+ else
45
+ path = "/cygdrive/c/scm/damagecontrol"
46
+ nativeurl = "file:///cygdrive/c/scm/damagecontrol"
47
+ end
48
+ assert_equal(nativeurl, filepath_to_nativeurl(path))
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,14 @@
1
+ require 'test/unit'
2
+ require 'rscm/generic_scm_tests'
3
+ require 'rscm/perforce/perforce'
4
+
5
+ module RSCM
6
+ class PerforceTest < Test::Unit::TestCase
7
+
8
+ include GenericSCMTests
9
+
10
+ def create_scm(repository_root_dir, path)
11
+ Perforce.new(repository_root_dir)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,36 @@
1
+ require 'test/unit'
2
+ require 'fileutils'
3
+ require 'rscm/generic_scm_tests'
4
+ require 'rscm/starteam/starteam'
5
+
6
+ module RSCM
7
+ class StarTeamTest < Test::Unit::TestCase
8
+ # include GenericSCMTests
9
+
10
+ def create_scm(repository_root_dir, path)
11
+ StarTeam.new(ENV["STARTEAM_USER"], ENV["STARTEAM_PASS"], "192.168.254.21", 49201, "NGST Application", "NGST Application", "java")
12
+ end
13
+
14
+ def test_changesets
15
+ from = Time.new - 2 * 3600 * 24
16
+ to = Time.new - 1 * 3600 * 24
17
+ puts "Getting changesets for #{from} - #{to}"
18
+
19
+ changesets = create_scm(nil, nil).changesets(nil, from, to)
20
+ assert_equal(1, changesets.length)
21
+ assert_equal(Time.utc(2004, 11, 30, 04, 52, 24), changesets[0][0].time)
22
+ assert_equal(Time.utc(2004, 11, 30, 04, 53, 23), changesets[0][1].time)
23
+ assert_equal(Time.utc(2004, 11, 30, 04, 53, 23), changesets[0].time)
24
+ assert_equal("rinkrank", changesets[0].developer)
25
+ assert_equal("En to\ntre buksa \nned\n", changesets[0].message)
26
+ end
27
+
28
+ def test_checkout
29
+ files = create_scm(nil, nil).checkout("target/starteam/checkout")
30
+ assert_equal(3, files.length)
31
+ assert_equal("eenie/meenie/minee/mo", files[0])
32
+ assert_equal("catch/a/redneck/by", files[1])
33
+ assert_equal("the/toe", files[2])
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,111 @@
1
+ require 'test/unit'
2
+ require 'stringio'
3
+ require 'rscm/svn/svn_log_parser'
4
+
5
+ module RSCM
6
+ class SVNLogParserTest < Test::Unit::TestCase
7
+
8
+ # include FileUtils
9
+
10
+ SIMPLE_LOG_ENTRY = <<EOF
11
+ r2 | ahelleso | 2004-07-11 14:29:35 +0100 (Sun, 11 Jul 2004) | 1 line
12
+ Changed paths:
13
+ M /damagecontrolled/build.xml
14
+ M /damagecontrolled/src/java/com/thoughtworks/damagecontrolled/Thingy.java
15
+
16
+ changed something
17
+ else
18
+ ------------------------------------------------------------------------
19
+ EOF
20
+
21
+ SIMPLE_LOG_ENTRY_WITH_BACKSLASHES = <<EOF
22
+ r2 | ahelleso | 2004-07-11 14:29:35 +0100 (Sun, 11 Jul 2004) | 1 line
23
+ Changed paths:
24
+ M \\damagecontrolled\\build.xml
25
+ M \\damagecontrolled\\src\\java\\com\\thoughtworks\\damagecontrolled\\Thingy.java
26
+
27
+ changed something
28
+ else
29
+ ------------------------------------------------------------------------
30
+ EOF
31
+
32
+ def test_can_parse_SIMPLE_LOG_ENTRIES
33
+ parser = SVNLogEntryParser.new("damagecontrolled", "damagecontrolled")
34
+ can_parse_simple_log_entry(parser, SIMPLE_LOG_ENTRY)
35
+ can_parse_simple_log_entry(parser, SIMPLE_LOG_ENTRY_WITH_BACKSLASHES)
36
+ end
37
+
38
+ def can_parse_simple_log_entry(parser, entry)
39
+ changeset = parser.parse(StringIO.new(entry)) {|line|}
40
+
41
+ assert_equal(2, changeset.revision)
42
+ assert_equal("ahelleso", changeset.developer)
43
+ assert_equal(Time.utc(2004,7,11,13,29,35), changeset.time)
44
+ assert_equal("changed something\nelse", changeset.message)
45
+
46
+ assert_equal(2, changeset.length)
47
+ assert_equal("build.xml", changeset[0].path)
48
+ assert_equal(2, changeset[0].revision)
49
+ assert_equal(Change::MODIFIED, changeset[0].status)
50
+ assert_equal("src/java/com/thoughtworks/damagecontrolled/Thingy.java", changeset[1].path)
51
+ assert_equal(Change::MODIFIED, changeset[1].status)
52
+ end
53
+
54
+ def test_parses_entire_log_into_changesets
55
+ File.open(File.dirname(__FILE__) + "/proxytoys-svn.log") do |io|
56
+ parser = SVNLogParser.new(io, "trunk/proxytoys", nil)
57
+
58
+ changesets = parser.parse_changesets
59
+
60
+ assert_equal(66, changesets.length)
61
+ # just some random assertions
62
+ assert_equal(
63
+ "DecoratingInvoker now hands off to a SimpleInvoker rather than a DelegatingInvoker if constructed with an Object to decorate.\n" +
64
+ "Added protected getDelegateMethod(name, params)\n", changesets[0].message)
65
+
66
+ assert_equal(66, changesets[3].revision)
67
+ assert_equal("tastapod", changesets[3].developer)
68
+ assert_equal(Time.utc(2004,05,24,17,06,18,0), changesets[3].time)
69
+ assert_match(/Factored delegating behaviour out/ , changesets[3].message)
70
+ assert_equal(15, changesets[3].length)
71
+
72
+ assert_equal("src/com/thoughtworks/proxy/toys/delegate/DelegatingInvoker.java" , changesets[3][1].path)
73
+ assert_equal(Change::ADDED , changesets[3][1].status)
74
+ assert_equal(66 , changesets[3][1].revision)
75
+ assert_equal(65, changesets[3][1].previous_revision)
76
+
77
+ assert_equal("src/com/thoughtworks/proxy/toys/delegate/ObjectReference.java" , changesets[3][3].path)
78
+ assert_equal(Change::MOVED, changesets[3][3].status)
79
+
80
+ assert_equal("src/com/thoughtworks/proxy/toys/delegate/OldDelegatingInvoker.java" , changesets[3][4].path)
81
+ assert_equal(Change::DELETED, changesets[3][4].status)
82
+
83
+ assert_equal("test/com/thoughtworks/proxy/toys/echo/EchoingTest.java" , changesets[3][14].path)
84
+ assert_equal(Change::MODIFIED , changesets[3][14].status)
85
+
86
+ end
87
+ end
88
+
89
+ def test_parses_entire_log_into_changesets
90
+ File.open(File.dirname(__FILE__) + "/cargo-svn.log") do |io|
91
+ parser = SVNLogParser.new(io, "trunk/proxytoys", nil)
92
+ changesets = parser.parse_changesets
93
+ assert_equal(16, changesets.length)
94
+ end
95
+ end
96
+
97
+ SVN_R_LOG_HEAD_DATA = <<-EOF
98
+ ------------------------------------------------------------------------
99
+ r48 | rinkrank | 2004-10-16 20:07:29 -0500 (Sat, 16 Oct 2004) | 1 line
100
+
101
+ nothing
102
+ ------------------------------------------------------------------------
103
+ EOF
104
+
105
+ def test_should_retrieve_head_revision
106
+ parser = SVNLogParser.new(StringIO.new(SVN_R_LOG_HEAD_DATA), "blah", nil)
107
+ changesets = parser.parse_changesets
108
+ assert_equal(48, changesets[0].revision)
109
+ end
110
+ end
111
+ end