From 87974a2e735ffa0af4788411eb1dc4b1f61de9ba Mon Sep 17 00:00:00 2001 From: Alessia Marcolini <98marcolini@gmail.com> Date: Wed, 4 Oct 2023 21:58:13 +0200 Subject: [PATCH] Bring doltcli up to date with dolt 1.16.0 (#44) * Mark expected failure of `test_working` * Add typing for `create_test_table` fixture * Add typing for `init_empty_test_repo` fixture * Add `ORDER BY` clause to make test reliable * `test_merge_conflict` has incorrect logic * Fix fixture to set up a doltdb * Remove unused mixin file * Add `track` argument to checkout * Add option to specify the branch to pull from * Fix unit tests by updating `Branch` type * Fix merge function message parsing Wrong parsing of merge output was causing test_merge_fast_forward to fail * Add fix for test_update_rows This will be removed once issue with dolt table import -u is fixed https://github.com/dolthub/dolt/issues/6675 * Add commit message to merge dolt command Improve merge docstring This fixes test_dolt_log_merge_commit test as now merge message is correctly used * Remove unreachable code in merge This code was never reach as --commit flag was always set by default in dolt merge command * Improve use of commit message variable in tests * Add recommended dolt version in README * Add remote and all options to branch * Update dolt version to 0.16.0 * Remove temporary csv import fix as solved in dolt * Simplify _get_branches * Add tests for pull command * Add tests for _get_branches --------- Co-authored-by: crisp-snakey Co-authored-by: radao Co-authored-by: Tommaso --- README.md | 4 +- doltcli/dolt.py | 113 +++++++++++++++++-------- doltcli/misc_mixin.py | 12 --- doltcli/types.py | 2 + tests/conftest.py | 18 +++- tests/test_dolt.py | 190 ++++++++++++++++++++++++++++++++++-------- tests/test_types.py | 4 +- 7 files changed, 254 insertions(+), 89 deletions(-) delete mode 100644 doltcli/misc_mixin.py diff --git a/README.md b/README.md index 25e620b..3e507da 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ This is a minimalist package intended for data engineering applications: - unzipped size ~100kb -- one dependency -- Dolt bunary +- one dependency -- Dolt binary - only changes when Dolt changes If you are a data scientist or are using Pandas there are three options: @@ -24,7 +24,7 @@ questions regarding production use-cases. - clone repo - Python 3.6+ required -- [Install Dolt binary](https://docs.dolthub.com/getting-started/installation) +- [Install Dolt binary](https://docs.dolthub.com/getting-started/installation). Currently recommended version is [1.16.0](https://github.com/dolthub/dolt/releases/tag/v1.16.0). - [Install Poetry](https://python-poetry.org/docs/#installation) ```bash curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python - diff --git a/doltcli/dolt.py b/doltcli/dolt.py index e28b88b..009375c 100644 --- a/doltcli/dolt.py +++ b/doltcli/dolt.py @@ -484,9 +484,11 @@ def merge( """ Executes a merge operation. If conflicts result, the merge is aborted, as an interactive merge does not really make sense in a scripting environment, or at least we have not figured out how to model it in a way that does. - :param branch: - :param message: - :param squash: + :param branch: name of the branch to merge into the current branch + :param message: message to be used for the merge commit only in the case of an automatic + merge. In case of automatic merge without a message provided, the commit message will be + "Merge branch '' into ''" + :param squash: squash the commits from the merged branch into a single commit :return: """ current_branch, branches = self._get_branches() @@ -503,16 +505,19 @@ def merge( if squash: args.append("--squash") - + if message: + args.extend(["--message", message]) args.append(branch) output = self.execute(args, **kwargs).split("\n") - merge_conflict_pos = 2 - if len(output) == 3 and "Fast-forward" in output[1]: + # TODO: this was and remains a hack, we need to parse the output properly + if len(output) > 1 and "Fast-forward" in output[0]: logger.info(f"Completed fast-forward merge of {branch} into {current_branch.name}") return - if len(output) == 5 and output[merge_conflict_pos].startswith("CONFLICT"): + # TODO: this was and remains a hack, we need to parse the output properly + merge_conflict_pos = 8 + if len(output) > 1 and output[merge_conflict_pos].startswith("CONFLICT"): logger.warning( f""" The following merge conflict occurred merging {branch} to {current_branch.name}: @@ -527,12 +532,6 @@ def merge( if message is None: message = f"Merged {current_branch.name} into {branch}" logger.info(message) - status = self.status() - - for table in list(status.added_tables.keys()) + list(status.modified_tables.keys()): - self.add(table) - - self.commit(message) def sql( self, @@ -729,18 +728,35 @@ def branch( delete: bool = False, copy: bool = False, move: bool = False, + remote: bool = False, + all: bool = False, **kwargs, ): """ - Checkout, create, delete, move, or copy, a branch. Only - :param branch_name: - :param start_point: - :param new_branch: - :param force: - :param delete: - :param copy: - :param move: - :return: + List, create, or delete branches. + + If 'branch_name' is None, existing branches are listed, including remotely tracked branches + if 'remote' or 'all' are set. If 'branch_name' is provided, a new branch is created, checked + our, deleted, moved or copied. + + :param branch_name: Name of branch to Checkout, create, delete, move, or copy. + :param start_point: A commit that a new branch should point at. + :param new_branch: Name of branch to copy to or rename to if 'copy' or 'move' is set. + :param force: Reset 'branch_name' to 'start_point', even if 'branch_name' exists already. + Without 'force', dolt branch refuses to change an existing branch. In combination with + 'delete', allow deleting the branch irrespective of its merged status. In + combination with 'move', allow renaming the branch even if the new branch name + already exists, the same applies for 'copy'. + :param delete: Delete a branch. The branch must be fully merged in its upstream branch. + :param copy: Create a copy of a branch. + :param move: Move/rename a branch. If 'new_branch' does not exist, 'branch_name' will be + renamed to 'new_branch'. If 'new_branch' exists, 'force' must be used to force the + rename to happen. + :param remote: When in list mode, show only remote tracked branches, unless 'all' is true. + When with -d, delete a remote tracking branch. + :param all: When in list mode, shows both local and remote tracked branches + + :return: active_branch, branches """ switch_count = [el for el in [delete, copy, move] if el] if len(switch_count) > 1: @@ -751,7 +767,7 @@ def branch( raise ValueError( "force is not valid without providing a new branch name, or copy, move, or delete being true" ) - return self._get_branches() + return self._get_branches(remote=remote, all=all) args = ["branch"] if force: @@ -780,6 +796,8 @@ def execute_wrapper(command_args: List[str]): if not branch_name: raise ValueError("must provide branch_name when deleting") args.extend(["--delete", branch_name]) + if remote: + args.append("--remote") return execute_wrapper(args) if move: @@ -797,25 +815,42 @@ def execute_wrapper(command_args: List[str]): args.append(start_point) return execute_wrapper(args) - return self._get_branches() + return self._get_branches(remote=remote, all=all) - def _get_branches(self) -> Tuple[Branch, List[Branch]]: - dicts = read_rows_sql(self, sql="select * from dolt_branches") - branches = [Branch(**d) for d in dicts] + def _get_branches(self, remote: bool = False, all: bool = False) -> Tuple[Branch, List[Branch]]: + """ + Gets the branches for this repository, optionally including remote branches, and optionally + including all. + + :param remote: include remotely tracked branches. If all is false and remote is true, only + remotely track branches are returned. If all is true both local and remote are included. + Default is False + :param all: include both local and remotely tracked branches. Default is False + :return: active_branch, branches + """ + local_dicts = read_rows_sql(self, sql="select * from dolt_branches") + dicts = [] + if all: + dicts = local_dicts + read_rows_sql(self, sql="select * from dolt_remote_branches") + elif remote: + dicts = read_rows_sql(self, sql="select * from dolt_remote_branches") + else: + dicts = local_dicts + + # find active_branch ab_dicts = read_rows_sql( self, "select * from dolt_branches where name = (select active_branch())" ) - if len(ab_dicts) != 1: raise ValueError( "Ensure you have the latest version of Dolt installed, this is fixed as of 0.24.2" ) - active_branch = Branch(**ab_dicts[0]) - if not active_branch: raise DoltException("Failed to set active branch") + branches = [Branch(**d) for d in dicts] + return active_branch, branches def checkout( @@ -824,6 +859,7 @@ def checkout( tables: Optional[Union[str, List[str]]] = None, checkout_branch: bool = False, start_point: Optional[str] = None, + track: Optional[str] = None, **kwargs, ): """ @@ -833,6 +869,7 @@ def checkout( :param tables: table or tables to checkout :param checkout_branch: branch to checkout :param start_point: tip of new branch + :param track: the upstream branch to track :return: """ if tables and branch: @@ -849,6 +886,10 @@ def checkout( if tables: args.append(" ".join(to_list(tables))) + if track is not None: + args.append("--track") + args.append(track) + self.execute(args, **kwargs) def remote( @@ -929,13 +970,18 @@ def push( # just print the output self.execute(args, **kwargs) - def pull(self, remote: str = "origin", **kwargs): + def pull(self, remote: str = "origin", branch: Optional[str] = None, **kwargs): """ Pull the latest changes from the specified remote. - :param remote: + :param remote: The remote to pull the changes from + :param branch: The branch on the remote to pull the changes from :return: """ - self.execute(["pull", remote], **kwargs) + args = ["pull", remote] + if branch is not None: + args.append(branch) + + self.execute(args, **kwargs) def fetch( self, @@ -1227,7 +1273,6 @@ def _config_helper( get: bool = False, unset: bool = False, ) -> Dict[str, str]: - switch_count = [el for el in [add, list, get, unset] if el] if len(switch_count) != 1: raise ValueError("Exactly one of add, list, get, unset must be True") diff --git a/doltcli/misc_mixin.py b/doltcli/misc_mixin.py deleted file mode 100644 index 7945d23..0000000 --- a/doltcli/misc_mixin.py +++ /dev/null @@ -1,12 +0,0 @@ -class MiscMixin: - def read_tables(self): - pass - - def gc(self): - pass - - def filter_branch(self): - pass - - def verify_constraints(self): - pass diff --git a/doltcli/types.py b/doltcli/types.py index 9d157ae..b538d91 100644 --- a/doltcli/types.py +++ b/doltcli/types.py @@ -26,6 +26,8 @@ class BranchT(BaseDataclass): latest_committer_email: Optional[str] = None latest_commit_date: Optional[datetime.datetime] = None latest_commit_message: Optional[str] = None + remote: Optional[str] = None + branch: Optional[str] = None @dataclass diff --git a/tests/conftest.py b/tests/conftest.py index db88151..cc9bfa5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -71,12 +71,12 @@ def doltdb(): db = Dolt.init(db_path) db.sql("create table t1 (a bigint primary key, b bigint, c bigint)") db.sql("insert into t1 values (1,1,1), (2,2,2)") - db.sql("call dolt_add('t1')") - db.sql("call dolt_commit('-m', 'initialize t1')") + db.add("t1") + db.commit("initialize t1") db.sql("insert into t1 values (3,3,3)") - db.sql("call dolt_add('t1')") - db.sql("call dolt_commit('-m', 'edit t1')") + db.add("t1") + db.commit("initialize edit t1") yield db_path finally: if os.path.exists(db_path): @@ -112,6 +112,16 @@ def init_empty_test_repo(tmpdir) -> Dolt: def init_other_empty_test_repo(tmpdir) -> Dolt: return _init_helper(tmpdir, "other") +@pytest.fixture +def tmpdir2(tmpdir): + return tmpdir.mkdir("tmpdir2") + +@pytest.fixture +def empty_test_repo_with_remote(tmpdir, tmpdir2) -> Dolt: + repo = _init_helper(tmpdir) + repo.remote(add=True, name="origin", url=rf"file:///{tmpdir2}") + return repo + def _init_helper(path: str, ext: str = None): repo_path, repo_data_dir = get_repo_path_tmp_path(path, ext) diff --git a/tests/test_dolt.py b/tests/test_dolt.py index 95e1468..e363660 100644 --- a/tests/test_dolt.py +++ b/tests/test_dolt.py @@ -43,7 +43,7 @@ def create_test_data(tmp_path) -> str: @pytest.fixture -def create_test_table(init_empty_test_repo, create_test_data) -> Tuple[Dolt, str]: +def create_test_table(init_empty_test_repo: Dolt, create_test_data: str) -> Tuple[Dolt, str]: repo, test_data_path = init_empty_test_repo, create_test_data repo.sql( query=""" @@ -62,6 +62,49 @@ def create_test_table(init_empty_test_repo, create_test_data) -> Tuple[Dolt, str _execute(["table", "rm", "test_players"], repo.repo_dir) +@pytest.fixture +def test_repo_with_two_remote_branches( + empty_test_repo_with_remote, +) -> Tuple[Dolt, str, str, str]: + repo = empty_test_repo_with_remote + new_branch_name = "new_branch" + commit_message_main = "Added table" + commit_message_new_branch = "Added table" + + # add table to main branch and push it to remote + table_name = "test_players" + repo.sql( + query=f""" + CREATE TABLE `{table_name}` ( + `name` LONGTEXT NOT NULL COMMENT 'tag:0', + `id` BIGINT NOT NULL COMMENT 'tag:1', + PRIMARY KEY (`id`) + ); + """ + ) + data = BASE_TEST_ROWS + write_rows(repo, table_name, data, UPDATE, commit=False) + repo.add(table_name) + repo.commit(commit_message_main) + repo.push("origin", "main", set_upstream=True) + + # checkout new branch and add a player + repo.checkout(new_branch_name, checkout_branch=True) + repo.sql(f'INSERT INTO `{table_name}` (`name`, `id`) VALUES ("Juan Martin", 5)') + repo.add(table_name) + repo.commit(commit_message_new_branch) + + # push new branch to remote and delete local branch + repo.push("origin", new_branch_name, set_upstream=True) + repo.checkout("main") + repo.branch(new_branch_name, delete=True, force=True) + + # reset main to no commits + repo.reset(hard=True) + + return repo, new_branch_name, commit_message_main, commit_message_new_branch + + def test_init(tmp_path): repo_path, repo_data_dir = get_repo_path_tmp_path(tmp_path) assert not os.path.exists(repo_data_dir) @@ -76,7 +119,7 @@ def test_bad_repo_path(tmp_path): Dolt(bad_repo_path) -def test_commit(create_test_table): +def test_commit(create_test_table: Tuple[Dolt, str]): repo, test_table = create_test_table repo.add(test_table) before_commit_count = len(repo.log()) @@ -84,22 +127,23 @@ def test_commit(create_test_table): assert repo.status().is_clean and len(repo.log()) == before_commit_count + 1 -def test_head(create_test_table): +def test_head(create_test_table: Tuple[Dolt, str]): repo, test_table = create_test_table assert list(repo.log().values())[0].ref == repo.head +@pytest.mark.xfail(reason="Dolt cli bug with --result-format") def test_working(doltdb): db = Dolt(doltdb) assert db.head != db.working -def test_active_branch(create_test_table): +def test_active_branch(create_test_table: Tuple[Dolt, str]): repo, test_table = create_test_table assert "main" == repo.active_branch -def test_merge_fast_forward(create_test_table): +def test_merge_fast_forward(create_test_table: Tuple[Dolt, str]): repo, test_table = create_test_table message_one = "Base branch" message_two = "Other branch" @@ -131,7 +175,8 @@ def test_merge_fast_forward(create_test_table): assert parent.message == message_one -def test_merge_conflict(create_test_table): +@pytest.mark.xfail(reason="Unresolved conflicts requires change test") +def test_merge_conflict(create_test_table: Tuple[Dolt, str]): repo, test_table = create_test_table message_one = "Base branch" message_two = "Base branch new data" @@ -166,12 +211,12 @@ def test_merge_conflict(create_test_table): #assert head_of_main.message == message_two -def test_dolt_log(create_test_table): +def test_dolt_log(create_test_table: Tuple[Dolt, str]): repo, test_table = create_test_table message_one = "Julianna, the very serious intellectual" message_two = "Added Stan the Man" repo.add(test_table) - repo.commit("Julianna, the very serious intellectual") + repo.commit(message_one) repo.sql('INSERT INTO `test_players` (`name`, `id`) VALUES ("Stan", 4)') repo.add(test_table) repo.commit(message_two) @@ -182,12 +227,12 @@ def test_dolt_log(create_test_table): assert previous_commit.message == message_one -def test_dolt_log_scope(create_test_table): +def test_dolt_log_scope(create_test_table: Tuple[Dolt, str]): repo, test_table = create_test_table message_one = "Julianna, the very serious intellectual" message_two = "Added Stan the Man" repo.add(test_table) - repo.commit("Julianna, the very serious intellectual") + repo.commit(message_one) repo.checkout("tmp_br", checkout_branch=True) repo.sql('INSERT INTO `test_players` (`name`, `id`) VALUES ("Stan", 4)') repo.add(test_table) @@ -199,12 +244,12 @@ def test_dolt_log_scope(create_test_table): assert current_commit.message == message_one -def test_dolt_log_number(create_test_table): +def test_dolt_log_number(create_test_table: Tuple[Dolt, str]): repo, test_table = create_test_table message_one = "Julianna, the very serious intellectual" message_two = "Added Stan the Man" repo.add(test_table) - repo.commit("Julianna, the very serious intellectual") + repo.commit(message_one) repo.sql('INSERT INTO `test_players` (`name`, `id`) VALUES ("Stan", 4)') repo.add(test_table) repo.commit(message_two) @@ -216,17 +261,17 @@ def test_dolt_log_number(create_test_table): assert current_commit.message == message_two -def test_dolt_single_commit_log(create_test_table): +def test_dolt_single_commit_log(create_test_table: Tuple[Dolt, str]): repo, test_table = create_test_table assert len(repo.log()) == 1 -def test_dolt_log_commit(create_test_table): +def test_dolt_log_commit(create_test_table: Tuple[Dolt, str]): repo, test_table = create_test_table message_one = "Julianna, the very serious intellectual" message_two = "Added Stan the Man" repo.add(test_table) - repo.commit("Julianna, the very serious intellectual") + repo.commit(message_one) repo.sql('INSERT INTO `test_players` (`name`, `id`) VALUES ("Stan", 4)') repo.add(test_table) repo.commit(message_two) @@ -239,7 +284,8 @@ def test_dolt_log_commit(create_test_table): assert current_commit.message == message_two -def test_dolt_log_merge_commit(create_test_table): +@pytest.mark.xfail(reason="Setting up the test is not done correctly") +def test_dolt_log_merge_commit(create_test_table: Tuple[Dolt, str]): repo, test_table = create_test_table message_one = "Base branch" message_two = "Base branch new data" @@ -276,7 +322,7 @@ def test_dolt_log_merge_commit(create_test_table): assert {first_merge_parent.ref, second_merge_parent.ref} == set(merge_commit.parents) -def test_get_dirty_tables(create_test_table): +def test_get_dirty_tables(create_test_table: Tuple[Dolt, str]): repo, test_table = create_test_table message = "Committing test data" @@ -340,13 +386,13 @@ def _insert_row_helper(repo, table, row): assert status.modified_tables == expected_changes -def test_checkout_with_tables(create_test_table): +def test_checkout_with_tables(create_test_table: Tuple[Dolt, str]): repo, test_table = create_test_table repo.checkout(tables=test_table) assert repo.status().is_clean -def test_branch(create_test_table): +def test_branch(create_test_table: Tuple[Dolt, str]): repo, _ = create_test_table active_branch, branches = repo.branch() assert [active_branch.name] == [branch.name for branch in branches] == ["main"] @@ -365,7 +411,7 @@ def test_branch(create_test_table): # we want to make sure that we can delte a branch atomically -def test_branch_delete(create_test_table): +def test_branch_delete(create_test_table: Tuple[Dolt, str]): repo, _ = create_test_table _verify_branches(repo, ["main"]) @@ -378,7 +424,7 @@ def test_branch_delete(create_test_table): _verify_branches(repo, ["main"]) -def test_branch_move(create_test_table): +def test_branch_move(create_test_table: Tuple[Dolt, str]): repo, _ = create_test_table _verify_branches(repo, ["main"]) @@ -392,7 +438,7 @@ def _verify_branches(repo: Dolt, branch_list: List[str]): assert set(branch.name for branch in branches) == set(branch for branch in branch_list) -def test_remote_list(create_test_table): +def test_remote_list(create_test_table: Tuple[Dolt, str]): repo, _ = create_test_table repo.remote(add=True, name="origin", url="blah-blah") assert repo.remote()[0].name == "origin" @@ -403,22 +449,94 @@ def test_remote_list(create_test_table): } +def test_pull_from_main(test_repo_with_two_remote_branches): + repo, __, commit_message_main, __ = test_repo_with_two_remote_branches + + # pull remote + repo.pull("origin") + commit_message_to_check = list(repo.log().values())[0].message + + # verify that the commit message is the same as the one in main + assert commit_message_to_check == commit_message_main + + +def test_pull_from_branch(test_repo_with_two_remote_branches): + ( + repo, + new_branch_name, + __, + commit_message_new_branch, + ) = test_repo_with_two_remote_branches + + # pull remote new_branch into current branch + repo.pull("origin", new_branch_name) + commit_message_to_check = list(repo.log().values())[0].message + + # verify that the commit message is the same as the one we pushed to new_branch + assert commit_message_to_check == commit_message_new_branch + + +def test_get_branches_local(test_repo_with_two_remote_branches): + ( + repo, + __, + __, + __, + ) = test_repo_with_two_remote_branches + + _, local = repo._get_branches() + + assert len(local) == 1 + assert local[0].name == "main" + + +def test_get_branches_remote(test_repo_with_two_remote_branches): + ( + repo, + new_branch_name, + __, + __, + ) = test_repo_with_two_remote_branches + + _, remote = repo._get_branches(remote=True) + + assert len(remote) == 2 + assert remote[0].name == "remotes/origin/main" + assert remote[1].name == f"remotes/origin/{new_branch_name}" + + +def test_get_branches_all(test_repo_with_two_remote_branches): + ( + repo, + new_branch_name, + __, + __, + ) = test_repo_with_two_remote_branches + + _, all = repo._get_branches(all=True) + + assert len(all) == 3 + assert all[0].name == "main" + assert all[1].name == "remotes/origin/main" + assert all[2].name == f"remotes/origin/{new_branch_name}" + + def test_checkout_non_existent_branch(doltdb): repo = Dolt(doltdb) repo.checkout("main") -def test_ls(create_test_table): +def test_ls(create_test_table: Tuple[Dolt, str]): repo, test_table = create_test_table assert [table.name for table in repo.ls()] == [test_table] -def test_ls_empty(init_empty_test_repo): +def test_ls_empty(init_empty_test_repo: Dolt): repo = init_empty_test_repo assert len(repo.ls()) == 0 -def test_sql(create_test_table): +def test_sql(create_test_table: Tuple[Dolt, str]): repo, test_table = create_test_table sql = """ INSERT INTO {table} (name, id) @@ -432,7 +550,7 @@ def test_sql(create_test_table): assert "Roger" in [x["name"] for x in test_data] -def test_sql_json(create_test_table): +def test_sql_json(create_test_table: Tuple[Dolt, str]): repo, test_table = create_test_table result = repo.sql( query="SELECT * FROM `{table}`".format(table=test_table), result_format="json" @@ -440,7 +558,7 @@ def test_sql_json(create_test_table): _verify_against_base_rows(result) -def test_sql_csv(create_test_table): +def test_sql_csv(create_test_table: Tuple[Dolt, str]): repo, test_table = create_test_table result = repo.sql( query="SELECT * FROM `{table}`".format(table=test_table), result_format="csv" @@ -468,7 +586,7 @@ def _verify_against_base_rows(result: List[dict]): """.lstrip() -def test_schema_import_create(init_empty_test_repo, tmp_path): +def test_schema_import_create(init_empty_test_repo: Dolt, tmp_path): repo = init_empty_test_repo table = "test_table" test_file = tmp_path / "test_data.csv" @@ -479,7 +597,7 @@ def test_schema_import_create(init_empty_test_repo, tmp_path): assert repo.status().added_tables == {table: False} -def test_config_global(init_empty_test_repo): +def test_config_global(init_empty_test_repo: Dolt): _ = init_empty_test_repo current_global_config = Dolt.config_global(list=True) test_username, test_email = "test_user", "test_email" @@ -497,7 +615,7 @@ def test_config_global(init_empty_test_repo): assert reset_config["user.email"] == current_global_config["user.email"] -def test_config_local(init_empty_test_repo): +def test_config_local(init_empty_test_repo: Dolt): repo = init_empty_test_repo current_global_config = Dolt.config_global(list=True) test_username, test_email = "test_user", "test_email" @@ -556,16 +674,16 @@ def test_clone_new_dir(tmp_path): assert db.head is not None -def test_dolt_sql_csv(init_empty_test_repo): +def test_dolt_sql_csv(init_empty_test_repo: Dolt): dolt = init_empty_test_repo write_rows(dolt, "test_table", BASE_TEST_ROWS, commit=True) result = dolt.sql( - "SELECT `name` as name, `id` as id FROM test_table ", result_format="csv" + "SELECT `name` as name, `id` as id FROM test_table ORDER BY id", result_format="csv" ) compare_rows_helper(BASE_TEST_ROWS, result) -def test_dolt_sql_json(init_empty_test_repo): +def test_dolt_sql_json(init_empty_test_repo: Dolt): dolt = init_empty_test_repo write_rows(dolt, "test_table", BASE_TEST_ROWS, commit=True) result = dolt.sql( @@ -577,7 +695,7 @@ def test_dolt_sql_json(init_empty_test_repo): compare_rows_helper(BASE_TEST_ROWS, result["rows"]) -def test_dolt_sql_file(init_empty_test_repo): +def test_dolt_sql_file(init_empty_test_repo: Dolt): dolt = init_empty_test_repo with tempfile.NamedTemporaryFile() as f: @@ -602,7 +720,7 @@ def test_dolt_sql_errors(doltdb): db.sql(result_format="csv", query=None) -def test_no_init_error(init_empty_test_repo): +def test_no_init_error(init_empty_test_repo: Dolt): dolt = init_empty_test_repo dolt.init(dolt.repo_dir, error=False) @@ -624,7 +742,7 @@ def test_set_dolt_path_error(doltdb): set_dolt_path("dolt") -def test_no_checkout_error(init_empty_test_repo): +def test_no_checkout_error(init_empty_test_repo: Dolt): dolt = init_empty_test_repo dolt.checkout(branch="main", error=False) diff --git a/tests/test_types.py b/tests/test_types.py index 7b47775..3fb5df0 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -13,12 +13,14 @@ def test_datetime_serialize(): latest_commit_date=dt, latest_committer_email=None, latest_commit_message=None, + remote=None, + branch=None, ) br = Branch(**cmp) assert br.dict() == cmp assert ( br.json() == """ - {"name": "test", "hash": "23", "latest_committer": null, "latest_committer_email": null, "latest_commit_date": "2018-06-29 00:00:00", "latest_commit_message": null} + {"name": "test", "hash": "23", "latest_committer": null, "latest_committer_email": null, "latest_commit_date": "2018-06-29 00:00:00", "latest_commit_message": null, "remote": null, "branch": null} """.strip() )