pivotal-piston 1.9.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. data/.gitignore +8 -0
  2. data/History.txt +11 -0
  3. data/License.txt +20 -0
  4. data/Manifest.txt +85 -0
  5. data/README.txt +136 -0
  6. data/Rakefile +4 -0
  7. data/bin/piston +5 -0
  8. data/config/hoe.rb +79 -0
  9. data/config/requirements.rb +18 -0
  10. data/lib/piston.rb +18 -0
  11. data/lib/piston/cli.rb +315 -0
  12. data/lib/piston/commands.rb +4 -0
  13. data/lib/piston/commands/base.rb +44 -0
  14. data/lib/piston/commands/import.rb +42 -0
  15. data/lib/piston/commands/info.rb +14 -0
  16. data/lib/piston/commands/lock_unlock.rb +21 -0
  17. data/lib/piston/commands/update.rb +29 -0
  18. data/lib/piston/git.rb +12 -0
  19. data/lib/piston/git/client.rb +77 -0
  20. data/lib/piston/git/commit.rb +74 -0
  21. data/lib/piston/git/repository.rb +63 -0
  22. data/lib/piston/git/working_copy.rb +86 -0
  23. data/lib/piston/repository.rb +57 -0
  24. data/lib/piston/revision.rb +53 -0
  25. data/lib/piston/svn.rb +14 -0
  26. data/lib/piston/svn/client.rb +88 -0
  27. data/lib/piston/svn/repository.rb +67 -0
  28. data/lib/piston/svn/revision.rb +74 -0
  29. data/lib/piston/svn/working_copy.rb +108 -0
  30. data/lib/piston/version.rb +9 -0
  31. data/lib/piston/working_copy.rb +183 -0
  32. data/lib/subclass_responsibility_error.rb +2 -0
  33. data/log/.gitignore +0 -0
  34. data/samples/common.rb +19 -0
  35. data/samples/import_git_git.rb +39 -0
  36. data/samples/import_git_svn.rb +36 -0
  37. data/samples/import_svn_git.rb +29 -0
  38. data/samples/import_svn_svn.rb +24 -0
  39. data/script/destroy +14 -0
  40. data/script/generate +14 -0
  41. data/script/txt2html +74 -0
  42. data/setup.rb +1585 -0
  43. data/tasks/deployment.rake +34 -0
  44. data/tasks/environment.rake +7 -0
  45. data/tasks/samples.rake +6 -0
  46. data/tasks/test.rake +69 -0
  47. data/tasks/website.rake +17 -0
  48. data/test/integration/test_git_git.rb +99 -0
  49. data/test/integration/test_git_svn.rb +121 -0
  50. data/test/integration/test_import_svn_git.rb +47 -0
  51. data/test/integration/test_import_svn_svn.rb +38 -0
  52. data/test/integration_helpers.rb +33 -0
  53. data/test/test_helper.rb +83 -0
  54. data/test/unit/git/commit/test_checkout.rb +31 -0
  55. data/test/unit/git/commit/test_each.rb +30 -0
  56. data/test/unit/git/commit/test_rememberance.rb +21 -0
  57. data/test/unit/git/commit/test_validation.rb +34 -0
  58. data/test/unit/git/repository/test_at.rb +23 -0
  59. data/test/unit/git/repository/test_basename.rb +12 -0
  60. data/test/unit/git/repository/test_branchanme.rb +15 -0
  61. data/test/unit/git/repository/test_guessing.rb +32 -0
  62. data/test/unit/git/working_copy/test_copying.rb +25 -0
  63. data/test/unit/git/working_copy/test_creation.rb +22 -0
  64. data/test/unit/git/working_copy/test_existence.rb +18 -0
  65. data/test/unit/git/working_copy/test_finalization.rb +15 -0
  66. data/test/unit/git/working_copy/test_guessing.rb +35 -0
  67. data/test/unit/git/working_copy/test_rememberance.rb +21 -0
  68. data/test/unit/svn/repository/test_at.rb +19 -0
  69. data/test/unit/svn/repository/test_basename.rb +24 -0
  70. data/test/unit/svn/repository/test_guessing.rb +45 -0
  71. data/test/unit/svn/revision/test_checkout.rb +28 -0
  72. data/test/unit/svn/revision/test_each.rb +22 -0
  73. data/test/unit/svn/revision/test_rememberance.rb +38 -0
  74. data/test/unit/svn/revision/test_validation.rb +50 -0
  75. data/test/unit/svn/working_copy/test_copying.rb +26 -0
  76. data/test/unit/svn/working_copy/test_creation.rb +16 -0
  77. data/test/unit/svn/working_copy/test_existence.rb +23 -0
  78. data/test/unit/svn/working_copy/test_externals.rb +56 -0
  79. data/test/unit/svn/working_copy/test_finalization.rb +17 -0
  80. data/test/unit/svn/working_copy/test_guessing.rb +18 -0
  81. data/test/unit/svn/working_copy/test_merging.rb +47 -0
  82. data/test/unit/svn/working_copy/test_rememberance.rb +26 -0
  83. data/test/unit/test_info.rb +37 -0
  84. data/test/unit/test_lock_unlock.rb +47 -0
  85. data/test/unit/test_repository.rb +51 -0
  86. data/test/unit/test_revision.rb +31 -0
  87. data/test/unit/working_copy/test_guessing.rb +35 -0
  88. data/test/unit/working_copy/test_info.rb +14 -0
  89. data/test/unit/working_copy/test_rememberance.rb +42 -0
  90. data/test/unit/working_copy/test_validate.rb +63 -0
  91. data/website/index.html +11 -0
  92. data/website/index.txt +39 -0
  93. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  94. data/website/stylesheets/screen.css +138 -0
  95. data/website/template.rhtml +48 -0
  96. metadata +244 -0
@@ -0,0 +1,33 @@
1
+ PISTON_ROOT = Pathname.new(File.dirname(__FILE__)).parent.realpath
2
+
3
+ def logger
4
+ @logger ||= Log4r::Logger["test"]
5
+ end
6
+
7
+ def runcmd(cmd, *args)
8
+ cmdline = [cmd]
9
+ cmdline += args
10
+ cmdline = cmdline.flatten.map {|s| s.to_s}.join(" ")
11
+ logger.debug "> #{cmdline}"
12
+
13
+ output = `#{cmdline}`
14
+ logger.debug "< #{output}"
15
+ return output if $?.success?
16
+ raise output
17
+ end
18
+
19
+ def svn(*args)
20
+ runcmd(:svn, *args)
21
+ end
22
+
23
+ def svnadmin(*args)
24
+ runcmd(:svnadmin, *args)
25
+ end
26
+
27
+ def git(*args)
28
+ runcmd(:git, *args)
29
+ end
30
+
31
+ def piston(*args)
32
+ runcmd(:ruby, "-I", PISTON_ROOT + "lib", PISTON_ROOT + "bin/piston", *args)
33
+ end
@@ -0,0 +1,83 @@
1
+ require "test/unit"
2
+ require "rubygems"
3
+ require "mocha"
4
+ require "log4r"
5
+ require "fileutils"
6
+
7
+ begin
8
+ require "turn"
9
+ rescue LoadError
10
+ # NOP: ignore, this is not a real dependency
11
+ end
12
+
13
+ require File.expand_path("#{File.dirname(__FILE__)}/../config/requirements")
14
+ require File.expand_path("#{File.dirname(__FILE__)}/integration_helpers")
15
+ require "find"
16
+
17
+ module Test
18
+ module Unit
19
+ module Assertions
20
+ def deny(boolean, message = nil)
21
+ message = build_message message, '<?> is not false or nil.', boolean
22
+ assert_block message do
23
+ not boolean
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ class Piston::TestCase < Test::Unit::TestCase
31
+ class << self
32
+ def logger
33
+ @@logger ||= Log4r::Logger["test"]
34
+ end
35
+ end
36
+
37
+ attr_reader :pathnames
38
+ def setup
39
+ super
40
+ @pathnames = []
41
+ end
42
+
43
+ def teardown
44
+ pathnames.each do |pathname|
45
+ pathname.rmtree if File.exists?(pathname)
46
+ end
47
+ super
48
+ end
49
+
50
+ def run(*args)
51
+ return if method_name.to_sym == :default_test && self.class == Piston::TestCase
52
+ super
53
+ end
54
+
55
+ def mkpath(path_or_pathname)
56
+ returning(path_or_pathname.is_a?(Pathname) ? path_or_pathname : Pathname.new(File.expand_path(path_or_pathname))) do |path|
57
+ path.mkpath
58
+ pathnames.push(path)
59
+ end
60
+ end
61
+
62
+ def logger
63
+ self.class.logger
64
+ end
65
+ end
66
+
67
+ LOG_DIR = Pathname.new(File.expand_path("#{File.dirname(__FILE__)}/../log")) unless Object::const_defined?(:LOG_DIR)
68
+ LOG_DIR.mkdir rescue nil
69
+
70
+ Log4r::Logger.root.level = Log4r::DEBUG
71
+
72
+ Log4r::Logger.new("main")
73
+ Log4r::Logger.new("handler")
74
+ Log4r::Logger.new("handler::client")
75
+ Log4r::Logger.new("handler::client::out")
76
+ Log4r::Logger.new("test")
77
+
78
+ FileUtils.touch("#{LOG_DIR}/test.log")
79
+ Log4r::FileOutputter.new("log", :trunc => true, :filename => (LOG_DIR + "test.log").realpath.to_s)
80
+
81
+ Log4r::Logger["main"].add "log"
82
+ Log4r::Logger["handler"].add "log"
83
+ Log4r::Logger["test"].add "log"
@@ -0,0 +1,31 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../../test_helper")
2
+
3
+ class Piston::Git::TestGitCommitCheckout < Piston::TestCase
4
+ def setup
5
+ super
6
+ @repos = mock("repos")
7
+ @repos.stubs(:url).returns("git://a.repos.com/project.git")
8
+ @reposdir = Pathname.new("tmp/.repos.tmp.git")
9
+ end
10
+
11
+ def test_clones_repository_at_indicated_path
12
+ @sha1 = "a9302"
13
+ @commit = Piston::Git::Commit.new(@repos, @sha1)
14
+ @commit.expects(:git).with(:clone, @repos.url, @reposdir)
15
+ @commit.expects(:git).with(:checkout, "-b", "my-#{@sha1}", @sha1)
16
+ @commit.expects(:git).with(:log, "-n", "1").returns("commit 922b12a6bcbb6f6a2cec60bcf5de17118086080a\nAuthor: Fran\303\247ois Beausoleil <francois@teksol.info>\nDate: Fri Mar 14 13:28:41 2008 -0400\n\n Changed how dependencies are found and managed, by using config/requirements.rb everywhere.\n \n Updated test/test_helper.rb where appropriate.\n")
17
+ Dir.expects(:chdir).with(@reposdir).yields
18
+ @commit.checkout_to(@reposdir)
19
+ end
20
+
21
+ def test_cloning_head_finds_head_commit
22
+ @sha1 = "HEAD"
23
+ @commit = Piston::Git::Commit.new(@repos, @sha1)
24
+ @commit.expects(:git).with(:clone, @repos.url, @reposdir)
25
+ @commit.expects(:git).with(:checkout, "-b", "my-#{@sha1}", @sha1)
26
+ @commit.expects(:git).with(:log, "-n", "1").returns("commit 922b12a6bcbb6f6a2cec60bcf5de17118086080a\nAuthor: Fran\303\247ois Beausoleil <francois@teksol.info>\nDate: Fri Mar 14 13:28:41 2008 -0400\n\n Changed how dependencies are found and managed, by using config/requirements.rb everywhere.\n \n Updated test/test_helper.rb where appropriate.\n")
27
+ Dir.expects(:chdir).with(@reposdir).yields
28
+ @commit.checkout_to(@reposdir)
29
+ assert_equal "922b12a6bcbb6f6a2cec60bcf5de17118086080a", @commit.sha1
30
+ end
31
+ end
@@ -0,0 +1,30 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../../test_helper")
2
+
3
+ class Piston::Git::TestGitCommitEach < Piston::TestCase
4
+ def setup
5
+ super
6
+ @repos = mock("repository")
7
+ @repos.stubs(:url).returns("git://github.com/francois/arepos.git")
8
+ @tmpdir = mkpath("tmp/.arepos.tmp.git")
9
+
10
+ @commit = Piston::Git::Commit.new(@repos, "ab"*20)
11
+ @commit.stubs(:git).returns("commit " + "ab" * 20)
12
+ @commit.checkout_to(@tmpdir)
13
+ end
14
+
15
+ def test_prunes_search_tree_on_dot_git_directory
16
+ @tmpdir.expects(:find).yields(@tmpdir + ".git")
17
+ assert_throws :prune do
18
+ @commit.each do |relpath|
19
+ # Can't assert anything
20
+ end
21
+ end
22
+ end
23
+
24
+ def test_yields_paths_relative_to_working_copy
25
+ @tmpdir.expects(:find).yields(@tmpdir + "a.rb")
26
+ @commit.each do |relpath|
27
+ assert_equal Pathname.new("a.rb"), relpath
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,21 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../../test_helper")
2
+
3
+ class Piston::Git::TestGitCommitRememberance < Piston::TestCase
4
+ def setup
5
+ super
6
+ @repos = mock("repository")
7
+ @repos.stubs(:url).returns("git://github.com/francois/arepos.git")
8
+
9
+ @reposdir = Pathname.new("tmp/repos.git")
10
+ @commit = Piston::Git::Commit.new(@repos, "ab"*20)
11
+ @values = @commit.remember_values
12
+ end
13
+
14
+ def test_remembers_original_commit_sha1
15
+ assert_equal @values[Piston::Git::COMMIT], @commit.sha1
16
+ end
17
+
18
+ def test_remembers_original_branch_name
19
+ assert_equal @values[Piston::Git::BRANCH], @commit.revision
20
+ end
21
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../../test_helper")
2
+
3
+ class Piston::Git::TestGitCommitValidation < Piston::TestCase
4
+ def setup
5
+ super
6
+ @repository = mock("repository")
7
+ @repository.stubs(:url).returns("git://my-git-repos/my-project.git")
8
+ end
9
+
10
+ def test_is_invalid_if_cannot_ls_remote_repository
11
+ commit = new_commit("HEAD")
12
+ commit.expects(:git).with("ls-remote", @repository.url).raises(Piston::Git::Client::CommandError)
13
+ assert_raise Piston::Git::Commit::Gone do
14
+ commit.validate!
15
+ end
16
+ end
17
+
18
+ def test_is_valid_when_ls_remote_succeeds
19
+ commit = new_commit("HEAD")
20
+ commit.expects(:git).with("ls-remote", @repository.url).returns(INFO)
21
+ assert_nothing_raised do
22
+ commit.validate!
23
+ end
24
+ end
25
+
26
+ protected
27
+ def new_commit(commit, recalled_values={})
28
+ Piston::Git::Commit.new(@repository, commit, recalled_values)
29
+ end
30
+
31
+ INFO = <<EOF
32
+ a7c46c702243f145a4089b0cb33d189870f1ae53 HEAD
33
+ EOF
34
+ end
@@ -0,0 +1,23 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../../test_helper")
2
+
3
+ class Piston::Git::TestGitRepositoryAt < Piston::TestCase
4
+ def setup
5
+ super
6
+ @repos = Piston::Git::Repository.new("git://a.repos.com/project.git")
7
+ end
8
+
9
+ def test_returns_a_piston_git_commit
10
+ Piston::Git::Commit.expects(:new).with(@repos, "a93029").returns(commit = mock("commit"))
11
+ assert_equal commit, @repos.at("a93029")
12
+ end
13
+
14
+ def test_returns_a_piston_git_commit_at_head_when_appropriate
15
+ Piston::Git::Commit.expects(:new).with(@repos, "HEAD").returns(commit = mock("commit"))
16
+ assert_equal commit, @repos.at(:head)
17
+ end
18
+
19
+ def test_returns_a_git_commit_using_recalled_values
20
+ Piston::Git::Commit.expects(:new).with(@repos, "a"*40).returns(commit = mock("commit"))
21
+ assert_equal commit, @repos.at(Piston::Git::COMMIT => "a"*40)
22
+ end
23
+ end
@@ -0,0 +1,12 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../../test_helper")
2
+
3
+ class Piston::Git::TestGitRepositoryBasename < Piston::TestCase
4
+ def test_basename_is_urls_last_component_minus_dot_git
5
+ assert_equal "piston", basename("git://github.com/francois/piston.git")
6
+ end
7
+
8
+ private
9
+ def basename(url)
10
+ Piston::Git::Repository.new(url).basename
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../../test_helper")
2
+
3
+ class Piston::Git::TestGitRepositoryBranchname < Piston::TestCase
4
+ def test_branchname_is_nil_when_no_branch_in_url
5
+ assert_nil Piston::Git::Repository.new("git://github.com/francois/piston.git").branchname
6
+ end
7
+
8
+ def test_branchname_is_branch_when_branch_in_url
9
+ assert_equal "branch", Piston::Git::Repository.new("git://github.com/francois/piston.git?branch").branchname
10
+ end
11
+
12
+ def test_url_does_not_include_branchname
13
+ assert_equal "git://github.com/francois/piston.git", Piston::Git::Repository.new("git://github.com/francois/piston.git?branch").url
14
+ end
15
+ end
@@ -0,0 +1,32 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../../test_helper")
2
+
3
+ class Piston::Git::TestGitRepositoryGuessing < Piston::TestCase
4
+ def test_understands_git_protocol
5
+ assert Piston::Git::Repository.understands_url?("git://github.com/francois/piston.git")
6
+ end
7
+
8
+ def test_understands_git_ssh_protocol
9
+ Piston::Git::Repository.expects(:git).with("ls-remote", "--heads", "git@github.com:francois/piston.git").returns("ab"*20 + " refs/heads/master")
10
+ assert Piston::Git::Repository.understands_url?("git@github.com:francois/piston.git")
11
+ end
12
+
13
+ def test_understand_http_when_heads_returned
14
+ Piston::Git::Repository.expects(:git).with("ls-remote", "--heads", "http://github.com/francois/piston.git").returns("ab"*20 + " refs/heads/master")
15
+ assert Piston::Git::Repository.understands_url?("http://github.com/francois/piston.git")
16
+ end
17
+
18
+ def test_does_not_understand_http_when_no_heads
19
+ Piston::Git::Repository.expects(:git).with("ls-remote", "--heads", "http://github.com/francois/piston.git").returns("")
20
+ deny Piston::Git::Repository.understands_url?("http://github.com/francois/piston.git")
21
+ end
22
+
23
+ def test_asks_url_when_ssh_protocol
24
+ Piston::Git::Repository.expects(:git).with("ls-remote", "--heads", "ssh://francois@github.com/francois/piston.git").returns("ab"*20 + " refs/heads/master")
25
+ assert Piston::Git::Repository.understands_url?("ssh://francois@github.com/francois/piston.git")
26
+ end
27
+
28
+ def test_asks_base_url_when_named_branch_in_url
29
+ Piston::Git::Repository.expects(:git).with("ls-remote", "--heads", "ssh://francois@github.com/francois/piston.git").returns("ab"*20 + " refs/heads/master")
30
+ assert Piston::Git::Repository.understands_url?("ssh://francois@github.com/francois/piston.git?convert")
31
+ end
32
+ end
@@ -0,0 +1,25 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../../test_helper")
2
+
3
+ class Piston::Git::TestGitWorkingCopyCopying < Piston::TestCase
4
+ def setup
5
+ super
6
+ @wcdir = mkpath("tmp/wc")
7
+ @wc = Piston::Git::WorkingCopy.new(@wcdir)
8
+ @wc.stubs(:git)
9
+ end
10
+
11
+ def test_copies_file
12
+ files = ["file.rb"]
13
+ files.expects(:copy_to).with("file.rb", @wcdir + files.first)
14
+ @wc.copy_from(files)
15
+ end
16
+
17
+ def test_ensures_directories_are_created
18
+ files = ["file/a.rb"]
19
+ @wcdir.expects(:+).with(files.first).returns(target = mock("target"))
20
+ target.expects(:dirname).returns(target)
21
+ target.expects(:mkdir)
22
+ files.expects(:copy_to).with("file/a.rb", target)
23
+ @wc.copy_from(files)
24
+ end
25
+ end
@@ -0,0 +1,22 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../../test_helper")
2
+
3
+ class Piston::Git::TestGitWorkingCopyCreation < Piston::TestCase
4
+ def setup
5
+ super
6
+ @wcdir = mkpath("tmp/wc")
7
+ @wc = Piston::Git::WorkingCopy.new(@wcdir)
8
+ @wc.stubs(:git)
9
+ end
10
+
11
+ def test_create_does_a_simple_mkpath
12
+ @wcdir.expects(:mkpath)
13
+ @wc.create
14
+ end
15
+
16
+ def test_create_succeeds_even_if_mkpath_fails
17
+ @wcdir.expects(:mkpath).raises(Errno::EEXIST)
18
+ assert_nothing_raised do
19
+ @wc.create
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../../test_helper")
2
+
3
+ class Piston::Git::TestGitWorkingCopyExistence < Piston::TestCase
4
+ def setup
5
+ super
6
+ @wc = Piston::Git::WorkingCopy.new("tmp/wc")
7
+ @wcdir = @wc.path
8
+ end
9
+
10
+ def test_exist_false_when_no_dir
11
+ deny @wc.exist?
12
+ end
13
+
14
+ def test_exist_true_when_dir_present
15
+ @wcdir.mkdir
16
+ assert @wc.exist?
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../../test_helper")
2
+
3
+ class Piston::Git::TestGitWorkingCopyFinalization < Piston::TestCase
4
+ def setup
5
+ super
6
+ @wcdir = mkpath("tmp/wc")
7
+ @wc = Piston::Git::WorkingCopy.new(@wcdir)
8
+ end
9
+
10
+ def test_finalize_adds_path_to_git
11
+ Dir.expects(:chdir).with(@wcdir).yields
12
+ @wc.expects(:git).with(:add, ".")
13
+ @wc.finalize
14
+ end
15
+ end
@@ -0,0 +1,35 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../../test_helper")
2
+
3
+ class Piston::Git::TestGitWorkingCopyGuessing < Piston::TestCase
4
+ def setup
5
+ super
6
+ @dir = mkpath("tmp/wc")
7
+ end
8
+
9
+ def test_does_git_status_on_directory
10
+ Dir.expects(:chdir).with(@dir).yields
11
+ Piston::Git::WorkingCopy.expects(:git).with(:status).returns("# On branch master
12
+ nothing to commit (working directory clean)
13
+ ")
14
+ assert Piston::Git::WorkingCopy.understands_dir?(@dir)
15
+ end
16
+
17
+ def test_does_git_status_on_parent_directories_recursively
18
+ @wc = @dir
19
+ @tmp = @wc.parent
20
+ @root = @tmp.parent
21
+
22
+ Dir.expects(:chdir).with(@dir).raises(Errno::ENOENT)
23
+ Dir.expects(:chdir).with(@tmp).raises(Errno::ENOENT)
24
+ Dir.expects(:chdir).with(@root).yields
25
+ Piston::Git::WorkingCopy.expects(:git).with(:status).returns("# On branch master
26
+ nothing to commit (working directory clean)
27
+ ")
28
+ assert Piston::Git::WorkingCopy.understands_dir?(@dir)
29
+ end
30
+
31
+ def test_denies_when_git_unavailable
32
+ Piston::Git::WorkingCopy.stubs(:git).raises(Piston::Git::Client::BadCommand)
33
+ deny Piston::Git::WorkingCopy.understands_dir?(@dir)
34
+ end
35
+ end