class TestRepository(unittest.TestCase): """Repository object test suite.""" def setUp(self): """Setup sandbox.""" self.sandbox = Sandbox() def tearDown(self): """Destroy sandbox.""" self.sandbox.destroy() def test_path_not_exists(self): """Test repository path when doesn't exists.""" self.assertRaises( RepositoryPathInvalid, Repository, "/dir/doesnt/exists") def test_repository_not_valid_path_isfile(self): """Test repository is not valid because path is file.""" self.sandbox.touch("invalid_repo") self.assertRaises( RepositoryPathInvalid, Repository, os.path.join(self.sandbox.path, "invalid_repo")) def test_repository_not_valid_path_isdir(self): """ Test repository is not valid when path is directory, but adapter not found. """ self.sandbox.mkdir("invalid_repo") self.assertRaises( RepositoryAdapterNotFound, Repository, os.path.join(self.sandbox.path, "invalid_repo")) def test_repository_valid_scm_git(self): """Test repository is valid and is a git repository.""" self.sandbox.mkdir("git_repo") self.sandbox.mkdir("git_repo/.git") repo = Repository("%s/git_repo" % self.sandbox.path) self.assertIsInstance(repo.adapter, GitAdapter) def test_get_scm(self): """Test get scm for a repository.""" self.sandbox.mkdir("git_repo") self.sandbox.mkdir("git_repo/.git") repo = Repository("%s/git_repo" % self.sandbox.path) self.assertEqual("Git", repo.get_scm()) def test_get_scm_none(self): """Test get scm for a repository when adapter is None.""" self.sandbox.mkdir("git_repo") self.sandbox.mkdir("git_repo/.git") repo = Repository("%s/git_repo" % self.sandbox.path) repo.adapter = None self.assertEqual(None, repo.get_scm())
class TestGit(unittest.TestCase): """Git adapter test suite.""" sandbox = None git = None def setUp(self): """Set up git adapter and sandbox.""" self.sandbox = Sandbox() self.sandbox.mkdir("repo") self.git = Git(os.path.join(self.sandbox.path, "repo")) self.git.execute = Mock(return_value=None) def tearDown(self): """Unset test object.""" self.sandbox.destroy() self.git = None def test_status(self): """Test git status.""" self.git.status() self.git.execute.assert_called_once_with( "git status", os.path.join(self.sandbox.path, "repo")) def test_update(self): """Test git update.""" self.git.update() self.git.execute.assert_called_once_with( "git pull --rebase", os.path.join(self.sandbox.path, "repo")) def test_clone(self): """Test git status.""" self.git.clone("[email protected]:foo/bar") self.git.execute.assert_called_once_with( "git clone %s %s" % ( "[email protected]:foo/bar", os.path.join(self.sandbox.path, "repo")))
class TestClone(unittest.TestCase): """Clone function test suite.""" def setUp(self): """Setup sandbox.""" self.sandbox = Sandbox() def tearDown(self): """Destroy sandbox.""" self.sandbox.destroy() def test_clone_git_repository_http(self): """Test clone git repository over http.""" with patch("yoda.repository.Git.clone") as patch_clone: clone( "https://git.project.org/foo/bar.git", "%s/bar" % self.sandbox.path) patch_clone.assert_called_once_with( "https://git.project.org/foo/bar.git") def test_clone_git_repository_ssh(self): """Test clone git repository over ssh.""" with patch("yoda.repository.Git.clone") as patch_clone: clone( "[email protected]:foo/bar", "%s/bar" % self.sandbox.path) patch_clone.assert_called_once_with( "[email protected]:foo/bar") def test_clone_git_repository_adapter_not_found(self): """Test clone git repository when adapter not found.""" self.assertRaises( RepositoryAdapterNotFound, clone, "https://project.org/foo/bar", "%s/bar" % self.sandbox.path)
class TestWorkspace(unittest.TestCase): """Test workspace commands.""" config = None sandbox = None def setUp(self): self.sandbox = Sandbox() self.config = Config(self.sandbox.path + "/config") def tearDown(self): self.sandbox.destroy() def test_add(self): """Test add workspace.""" self.config.update({ "workspaces": {"foo": {"path": "/foo", "repositories": {}}}}) ws = Workspace(self.config) ws.add("bar", os.path.realpath(__file__)) def test_add_existing_workspace(self): """Test add workspace with existing name.""" self.config.update({ "workspaces": {"foo": {"path": "/foo", "repositories": {}}}}) ws = Workspace(self.config) self.assertRaises( ValueError, ws.add, "foo", os.path.realpath(__file__)) def test_add_with_nonexistent_path(self): """Test add workspace with path doesn't exists.""" self.config.update({"workspaces": {}}) ws = Workspace(self.config) self.assertRaises( ValueError, ws.add, "foo", "/dir/doesnt/exists") def test_remove(self): """Test remove workspace.""" self.config.update({ "workspaces": {"foo": {"path": "/foo", "repositories": {}}}}) ws = Workspace(self.config) ws.remove("foo") def test_remove_nonexistent(self): """Test remove workspace that doesn't exists.""" self.config.update({ "workspaces": {"foo": {"path": "/foo", "repositories": {}}}}) ws = Workspace(self.config) self.assertRaises( ValueError, ws.remove, "bar") def test_list(self): """Test list workspace.""" config_mock_data = {"workspaces": { "foo": {"path": "/foo", "repositories": {}}, "bar": {"path": "/bar", "repositories": {}}}} self.config.update(config_mock_data) ws = Workspace(self.config) list = ws.list() self.assertIn("foo", list) self.assertIn("bar", list) self.assertEqual( {"name": "foo", "path": "/foo", "repositories": {}}, list["foo"]) self.assertEqual( {"name": "bar", "path": "/bar", "repositories": {}}, list["bar"]) def test_get_workspace(self): """Test get workspace from name.""" config_mock_data = {"workspaces": { "foo": {"path": "/foo", "repositories": {}}}} self.config.update(config_mock_data) ws = Workspace(self.config) self.assertEqual({ "name": "foo", "path": "/foo", "repositories": {}}, ws.get("foo")) def test_get_workspace_none(self): """Test get workspace that doesn't exists.""" ws = Workspace(self.config) self.assertIsNone(ws.get("foo")) def test_exists(self): """Test exists workspace.""" config_mock_data = { "workspaces": {"foo": {"path": "/foo", "repositories": {}}}} self.config.update(config_mock_data) ws = Workspace(self.config) self.assertTrue(ws.exists("foo")) def test_not_exists(self): """Test workspace doesn't exists.""" config_mock_data = { "workspaces": {"foo": {"path": "/foo", "repositories": {}}}} self.config.update(config_mock_data) ws = Workspace(self.config) self.assertFalse(ws.exists("bar")) def test_not_instance_of_config(self): """Test if parameter is an instance of Config.""" self.assertRaises(TypeError, lambda: Workspace(())) def test_repository_exists(self): """Test workspace has repository.""" config_mock_data = {"workspaces": { "foo": {"path": "/foo", "repositories": {"repo1": "/foo/repo1"}}}} self.config.update(config_mock_data) ws = Workspace(self.config) self.assertTrue(ws.repository_exists("foo", "repo1")) def test_has_not_repo(self): """Test workspace has not repository.""" config_mock_data = {"workspaces": { "foo": {"path": "/foo", "repositories": {"repo1": "/foo/repo1"}}}} self.config.update(config_mock_data) ws = Workspace(self.config) self.assertFalse(ws.repository_exists("foo", "repo2")) def test_repository_exists_invalid_workspace(self): """Test workspace has not repository.""" config_mock_data = {"workspaces": { "foo": {"path": "/foo", "repositories": {"repo1": "/foo/repo1"}}}} self.config.update(config_mock_data) ws = Workspace(self.config) self.assertFalse(ws.repository_exists("bar", "repo1"))
class TestFindPathFunction(unittest.TestCase): """Test suite for find_path function.""" def setUp(self): """Setup test suite.""" self.sandbox = Sandbox() self.sandbox.mkdir("yoda") self.sandbox.mkdir("yoda/yoda") self.sandbox.mkdir("yoda/other") self.sandbox.mkdir("sliim") self.sandbox.mkdir("sliim/emacs.d") self.sandbox.mkdir("sliim/yoda") config_data = { "workspaces": { "yoda": { "path": os.path.join(self.sandbox.path, "yoda"), "repositories": { "yoda": os.path.join(self.sandbox.path, "yoda/yoda"), "other": os.path.join(self.sandbox.path, "yoda/other"), "1337": os.path.join(self.sandbox.path, "yoda/1337") } }, "sliim": { "path": os.path.join(self.sandbox.path, "sliim"), "repositories": { "misc": os.path.join(self.sandbox.path, "sliim/misc"), "yoda": os.path.join(self.sandbox.path, "sliim/yoda") } } } } self.sandbox = Sandbox() self.config = Config(self.sandbox.path + "/config") self.config.update(config_data) def tearDown(self): """Destroy sandbox.""" self.sandbox.destroy() def test_find_path_workspace(self): """Test find_path for workspace.""" res = find_path("yoda", self.config) self.assertEqual(4, len(res)) self.assertIn("yoda/yoda", res) self.assertIn("yoda/other", res) self.assertIn("yoda/1337", res) self.assertIn("sliim/yoda", res) def test_find_path_workspace_only(self): """Test find_path for workspace only.""" res = find_path("sliim", self.config, True) self.assertEqual(1, len(res)) self.assertIn("sliim", res) def test_find_path_repository(self): """Test find_path for repository.""" res = find_path("other", self.config) self.assertEqual(1, len(res)) self.assertIn("yoda/other", res) def test_find_path_workspace_and_repository(self): """Test find_path for workspace/repository.""" res = find_path("yoda/1337", self.config) self.assertEqual(1, len(res)) self.assertIn("yoda/1337", res) def test_find_path_no_matches(self): """Test find_path when no matches found.""" self.assertEqual({}, find_path("foo/bar", self.config)) def test_find_path_no_workspace(self): """Test find_path when no workspace registered.""" self.config = Config(self.sandbox.path + "/fake-config") self.assertEqual({}, find_path( "yoda/yoda", self.config))
class TestSubcommandWorkspace(unittest.TestCase): """Workspace subcommand test suite.""" sandbox = None parser = None subparser = None workspace = None def setUp(self): """Setup test suite.""" self.parser = argparse.ArgumentParser(prog="yoda_test") self.subparser = self.parser.add_subparsers(dest="subcommand_test") self.sandbox = Sandbox() self.sandbox.mkdir("tmp") self.sandbox.mkdir("tmp/repo-name") config_data = { "workspaces": { "yoda": { "path": "/yoda", "repositories": { "yoda": "/project/yoda" } } } } conf = Config(self.sandbox.path + "/config") conf.update(config_data) self.workspace = Workspace() self.workspace.setup( "workspace", conf, self.subparser) def tearDown(self): """Tear down test suite.""" self.sandbox.destroy() self.parser = None self.workspace = None def test_parse_add(self): """Test workspace add parsing.""" self.workspace.parse() args = self.parser.parse_args(["workspace", "add", "foo", "/tmp/foo"]) self.assertEqual("workspace", args.subcommand_test) self.assertEqual("add", args.workspace_subcommand) self.assertEqual("foo", args.name) self.assertEqual("/tmp/foo", args.path) def test_parse_remove(self): """Test workspace remove parsing.""" self.workspace.parse() args = self.parser.parse_args(["workspace", "remove", "foo"]) self.assertEqual("workspace", args.subcommand_test) self.assertEqual("remove", args.workspace_subcommand) self.assertEqual("foo", args.name) def test_parse_list(self): """Test workspace list parsing.""" self.workspace.parse() args = self.parser.parse_args(["workspace", "list"]) self.assertEqual("workspace", args.subcommand_test) self.assertEqual("list", args.workspace_subcommand) def test_exec_add(self): """Test workspace add execution.""" ws = Mock() ws.add = Mock() args = Mock() args.workspace_subcommand = "add" args.name = "foo" args.path = "/foo" self.workspace.ws = ws self.workspace.execute(args) ws.add.assert_called_with("foo", "/foo") def test_exec_remove(self): """Test workspace remove execution.""" ws = Mock() ws.remove = Mock() args = Mock() args.workspace_subcommand = "remove" args.name = "foo" self.workspace.ws = ws self.workspace.execute(args) ws.remove.assert_called_with("foo") def test_exec_list(self): """Test workspace list execution.""" ws_list = { "yoda": { "path": "/project/yoda", "repositories": { "yoda": "/project/yoda/src" } }, "test": { "path": "/project/test" } } ws = Mock() ws.list = Mock(return_value=ws_list) args = Mock() args.workspace_subcommand = "list" self.workspace.ws = ws self.workspace.execute(args) ws.list.assert_called_with() def test_exec_without_command(self): """Test workspace without subcommand.""" ws = Mock() args = Mock() args.workspace_subcommand = None self.workspace.ws = ws self.assertIsNone(self.workspace.execute(args)) def test_exec_with_wrong_command(self): """Test workspace without subcommand.""" ws = Mock() args = Mock() args.workspace_subcommand = "test" self.workspace.ws = ws self.assertIsNone(self.workspace.execute(args)) def test_load_workspaces_subcommands(self): """Test workspaces subcommands.""" ws = Mock() ws.list = Mock(return_value={"foo": {"path": "/foo", "repositories": {}}}) subcmd = Mock() subcmd.commands = {} self.workspace.ws = ws self.workspace.load_workspaces_subcommands(subcmd) self.assertTrue("foo" in subcmd.commands) self.assertIsInstance(subcmd.commands["foo"], WorkspaceSubcommands)
class TestWorkspacesSubcommands(unittest.TestCase): """Test suite for workspaces subcommands setup.""" config = None parser = None config_data = None directory = None def setUp(self): """Setup test suite.""" self.sandbox = Sandbox() self.directory = self.sandbox.path + "/tmp" self.parser = argparse.ArgumentParser(prog="yoda_test") self.config_data = { "workspaces": { "yoda": { "path": self.directory } } } self.config = Config(self.sandbox.path + "/config") self.config.update(self.config_data) def tearDown(self): """Tear down test suite.""" self.sandbox.destroy() self.parser = None def test_exec_without_command(self): """Test repository execute without subcommand.""" subparser = self.parser.add_subparsers(dest="subcommand_test") ws_subcmds = WorkspaceSubcommands( "yoda", subparser, self.config ) ws_subcmds.parse() try: args = self.parser.parse_args(["yoda"]) self.assertIsNone(ws_subcmds.execute(args)) except SystemExit: #Raised in Python 2.7.x self.assertEqual("2.7", sys.version[:3]) def test_parse_add(self): """Test parse add subcommands.""" subparser = self.parser.add_subparsers(dest="subcommand_test") ws_subcmds = WorkspaceSubcommands( "yoda", subparser, self.config ) ws_subcmds.parse() args = self.parser.parse_args([ "yoda", "add", "repo-name", "-u", "repo-url", "-p", "repo-path"]) self.assertEqual("add", args.action) self.assertEqual("repo-name", args.repo_name) self.assertEqual("repo-url", args.url) self.assertEqual("repo-path", args.path) def test_execute_add_subcommand_repo_already_exists(self): """Test execute add subcommands when repo name already exists.""" subparser = self.parser.add_subparsers(dest="subcommand") ws_subcmds = WorkspaceSubcommands( "yoda", subparser, self.config ) ws_subcmds.parse() args = self.parser.parse_args(["yoda", "add", "repo-name"]) self.sandbox.mkdir("tmp") ws_subcmds.execute(args) self.assertTrue(os.path.exists(self.directory + "/repo-name")) self.assertRaises(ValueError, lambda: ws_subcmds.execute(args)) def test_execute_add_subcommand(self): """Test execute add subcommand.""" subparser = self.parser.add_subparsers(dest="subcommand") ws_subcmds = WorkspaceSubcommands( "yoda", subparser, self.config ) ws_subcmds.parse() args = self.parser.parse_args( ["yoda", "add", "other-repo", "-p", "%s/repo-name" % self.directory, "-u", "repo-url"]) with patch( "yoda.subcommand.workspace.clone") as patch_clone: self.sandbox.mkdir("tmp") ws_subcmds.execute(args) patch_clone.assert_called_once_with( "repo-url", "%s/repo-name" % self.directory) @patch("%s.input" % builtins_module, Mock(side_effect=["n", "y"])) def test_execute_remove_subcommad(self): """Test execute remove subcommands.""" self.config_data["workspaces"]["yoda"]["repositories"] = { "repo-name": self.directory + "/repo-name" } subparser = self.parser.add_subparsers(dest="subcommand") ws_subcmds = WorkspaceSubcommands( "yoda", subparser, self.config ) ws_subcmds.parse() args = self.parser.parse_args(["yoda", "remove", "repo-name"]) ws_subcmds.execute(args) self.assertFalse(os.path.exists(self.directory + "/repo-name")) args = self.parser.parse_args(["yoda", "remove", "1377"]) self.assertRaises(ValueError, lambda: ws_subcmds.execute(args)) def test_sync(self): """Test synchronize workspace.""" subparser = self.parser.add_subparsers(dest="subcommand_test") ws_subcmds = WorkspaceSubcommands( "yoda", subparser, self.config ) ws_subcmds.parse() args = self.parser.parse_args([ "yoda", "sync"]) self.assertEqual("sync", args.action) def test_execute_sync_subcommand(self): """Test execute sync subcommand.""" self.config_data["workspaces"]["yoda"]["repositories"] = { "repo-name": self.directory + "/repo-name" } subparser = self.parser.add_subparsers(dest="subcommand") config = self.config ws_subcmds = WorkspaceSubcommands( "yoda", subparser, config ) ws_subcmds.parse() args = self.parser.parse_args( ["yoda", "sync", "yoda"] ) self.sandbox.mkdir("tmp") self.assertFalse(ws_subcmds.execute(args)) with patch( "yoda.subcommand.workspace.Repository.__init__", return_value=None): ws_subcmds.execute(args)
class TestSubcommandJump(unittest.TestCase): """Jump subcommand test suite.""" config = None sandbox = None parser = None subparser = None jump = None def setUp(self): """Setup test suite.""" self.parser = argparse.ArgumentParser(prog="yoda_test") self.subparser = self.parser.add_subparsers(dest="jump_subcommand") self.sandbox = Sandbox() self.config = Config(self.sandbox.path + "/config") self.jump = Jump() self.jump.setup("jump", self.config, self.subparser) def tearDown(self): """Tear down test suite.""" self.sandbox.destroy() self.parser = None self.jump = None def test_parse_jump(self): """Test jump to workspace.""" self.jump.parse() args = self.parser.parse_args(["jump", "yoda"]) self.assertEqual("jump", args.jump_subcommand) self.assertEqual("yoda", args.name) def test_exec_jump(self): """Test exec jump subcommand.""" args = Mock() args.name = "yoda/baz" self.jump._Jump__jump = Mock() mock_path = {"yoda/baz": "/tmp/yoda/baz"} with patch("yoda.subcommand.jump.find_path", return_value=mock_path) as patch_fp: self.jump.execute(args) patch_fp.assert_called_once_with( "yoda/baz", self.jump.config, True) self.jump._Jump__jump.assert_called_once_with("/tmp/yoda/baz") def test_exec_jump_no_matches(self): """Test exec jump subcommand when no matches.""" args = Mock() args.name = "foo/bar" self.jump.logger = Mock() with patch("yoda.subcommand.jump.find_path", return_value={}): self.assertFalse(self.jump.execute(args)) self.jump.logger.error.assert_called_once_with( "No matches for `foo/bar`") def test_exec_jump_method(self): """Test exec jump subcommand when no matches.""" args = Mock() args.name = "foo/bar" self.jump.logger = Mock() os_system = Mock() with patch("os.system", return_value=os_system): mock_path = {"yoda/baz": "/tmp/yoda/baz"} with patch("yoda.subcommand.jump.find_path", return_value=mock_path): self.jump.execute(args) os_system.assert_called_once calls = [ call("Spawn new shell on `/tmp/yoda/baz`"), call("Use Ctrl-D to exit and go " "back to the previous directory"), call("Shell on `/tmp/yoda/baz` closed.")] assert self.jump.logger.info.mock_calls == calls
class TestSubcommandUpdate(unittest.TestCase): """Update subcommand test suite.""" sandbox = None config = None parser = None subparser = None update = None def setUp(self): """Setup test suite.""" self.parser = argparse.ArgumentParser(prog="yoda_test") self.subparser = self.parser.add_subparsers(dest="subcommand_test") self.update = Update() config_data = { "workspaces": { "yoda": { "path": "/yoda", "repositories": { "yoda": "/project/yoda" } } } } self.sandbox = Sandbox() self.config = Config(self.sandbox.path + "/config") self.config.update(config_data) self.update.setup("update", self.config, self.subparser) def tearDown(self): """Tear down test suite.""" self.sandbox.destroy() self.parser = None self.update = None def test_parse_update(self): """Test parse update subcommand.""" self.update.parse() args = self.parser.parse_args(["update", "ws1/repo1"]) self.assertEqual("update", args.subcommand_test) self.assertEqual("ws1/repo1", args.name) args = self.parser.parse_args(["update", "--all"]) self.assertEqual("update", args.subcommand_test) self.assertEqual(True, args.all) self.assertRaises( SystemExit, self.parser.parse_args, ["update", "--all", "ws1/repo1"] ) def test_exec_update_workspace_only(self): """Test exec update subcommand.""" args = Mock() args.name = "foo/bar" mock_path = {"foo/bar": "/tmp/foo/bar"} self.update.print_update = Mock() with patch("yoda.subcommand.update.find_path", return_value=mock_path) as patch_fp: self.update.execute(args) patch_fp.assert_called_once_with("foo/bar", self.update.config) self.update.print_update.assert_called_once_with( "foo/bar", "/tmp/foo/bar") def test_exec_update_all_workspaces(self): """Test exec with all workspaces.""" args = Mock() args.name = None args.all = True mock_path = {"foo/bar": "/tmp/foo/bar"} self.update.print_update = Mock() with patch("yoda.subcommand.update.find_path", return_value=mock_path): self.update.execute(args) def test_exec_update_no_matches(self): """Test exec update subcommand with no matches.""" args = Mock() args.name = "foobar" self.update.logger = Mock() self.update.print_update = Mock() with patch("yoda.subcommand.update.find_path", return_value={}): self.assertFalse(self.update.execute(args)) self.update.logger.error.assert_called_once_with( "No matches for `foobar`") def test_print_update(self): """Test print_update.""" self.update.logger = Mock() with patch("yoda.subcommand.update.Repository"): self.update.print_update("foo", "bar") self.update.logger.info.assert_has_calls( [call("\033[32m=> [foo] bar\033[0m")])
class TestSubcommandShow(unittest.TestCase): """Show subcommand test suite.""" config = None sandbox = None parser = None subparser = None show = None def setUp(self): """Setup test suite.""" self.parser = argparse.ArgumentParser(prog="yoda_test") self.subparser = self.parser.add_subparsers(dest="show_subcommand") self.sandbox = Sandbox() self.config = Config(self.sandbox.path + "/config") config_data = { "workspaces": { "my_workspace": { "path": "/my_workspace", "repositories": { "repo1": self.sandbox.path + "/my_workspace/repo1" } }, "another_workspace": { "path": "/another_workspace", "repositories": { "repo1": self.sandbox.path + "/another_workspace/repo1" } } } } self.sandbox.mkdir("my_workspace") self.sandbox.mkdir("my_workspace/repo1") self.sandbox.mkdir("another_workspace") self.sandbox.mkdir("another_workspace/repo1") self.config.update(config_data) self.show = Show() self.show.setup("show", self.config, self.subparser) def tearDown(self): """Tear down test suite.""" self.sandbox.destroy() self.parser = None self.show = None def test_parse_show(self): """Test show to workspace.""" self.show.parse() args = self.parser.parse_args(["show", "ws1"]) self.assertEqual("show", args.show_subcommand) self.assertEqual("ws1", args.name) args = self.parser.parse_args(["show", "--all"]) self.assertEqual("show", args.show_subcommand) self.assertTrue(args.all) self.assertRaises( SystemExit, self.parser.parse_args, ["show", "--all", "ws1/repo1"] ) def test_exec_show(self): """Test exec show subcommand.""" args = Mock() args.name = "my_workspace" self.show.show_workspace = Mock() self.show.execute(args) self.show.show_workspace.assert_called_once_with("my_workspace") def test_exec_show_all(self): """Test exec show all workspace details subcommand.""" args = Mock() args.name = None args.all = True self.show.show_workspace = Mock() self.show.execute(args) self.show.show_workspace.assert_has_calls([call("my_workspace")]) self.show.show_workspace.assert_has_calls([call("another_workspace")]) def test_show_workspace_no_matches(self): """Test exec show subcommand when no matches.""" args = Mock() args.name = "not_exists" self.assertRaises(ValueError, self.show.execute, args) def test_show_workspace(self): """Test exec show subcommand with workspaces.""" args = Mock() args.name = "my_workspace" self.show.logger = Mock() self.show.execute(args) calls = [ call("<== \x1b[32mmy_workspace\x1b[0m workspace ==>"), call("\tPath: /my_workspace"), call("\tNumber of repositories: \x1b[33m1\x1b[0m") ] self.show.logger.info.assert_has_calls(calls)