Skip to content

Commit e505ebb

Browse files
[grocery-shopping] Improve verify logic (#232)
# Exercise Review ## Exercise Discussion Fixes #225 ## Checklist - [ ] If you require a new remote repository on the `Git-Mastery` organization, have you [created a request](https://github.com/git-mastery/exercises/issues/new?template=request_exercise_repository.yaml) for it? - [x] Have you written unit tests using [`repo-smith`](https://github.com/git-mastery/repo-smith) to validate the exercise grading scheme? - [x] Have you tested your changes using the instructions posted? - [x] Have you verified that this exercise does not already exist or is not currently in review? - [ ] Did you introduce a new grading mechanism that should belong to [`git-autograder`](https://github.com/git-mastery/git-autograder)? - [ ] Did you introduce a new dependency that should belong to [`app`](https://github.com/git-mastery/app)?
1 parent d213a26 commit e505ebb

2 files changed

Lines changed: 87 additions & 51 deletions

File tree

grocery_shopping/test_verify.py

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@
1010
from git_autograder import GitAutograderStatus
1111
from repo_smith.repo_smith import RepoSmith
1212

13-
from .verify import EMPTY_COMMITS, NO_ADD, NO_REMOVE, WRONG_FILE, verify
13+
from .verify import (
14+
ADD_NOT_COMMITTED,
15+
NO_ADD,
16+
NO_REMOVE,
17+
REMOVE_NOT_COMMITTED,
18+
SHOPPING_LIST_FILE_MISSING,
19+
verify
20+
)
1421

1522
REPOSITORY_NAME = "grocery-shopping"
1623

@@ -20,7 +27,6 @@
2027
@contextmanager
2128
def base_setup() -> Iterator[Tuple[GitAutograderTest, RepoSmith]]:
2229
with loader.start() as (test, rs):
23-
rs.files.create_or_update("README.md", "Hello world")
2430
rs.files.create_or_update(
2531
"shopping-list.txt",
2632
"""
@@ -31,7 +37,7 @@ def base_setup() -> Iterator[Tuple[GitAutograderTest, RepoSmith]]:
3137
- Ham
3238
""",
3339
)
34-
rs.git.add(["README.md", "shopping-list.txt"])
40+
rs.git.add(["shopping-list.txt"])
3541
rs.git.commit(message="Initial commit")
3642
rs.helper(GitMasteryHelper).create_start_tag()
3743

@@ -40,23 +46,35 @@ def base_setup() -> Iterator[Tuple[GitAutograderTest, RepoSmith]]:
4046

4147
def test_no_changes():
4248
with base_setup() as (test, rs):
43-
rs.git.commit(message="Commit", allow_empty=True)
49+
output = test.run()
50+
assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [NO_ADD, NO_REMOVE])
51+
52+
53+
def test_add_new_file():
54+
with base_setup() as (test, rs):
55+
rs.files.create_or_update("new-file.txt", "New file content")
4456

4557
output = test.run()
46-
assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [EMPTY_COMMITS])
58+
assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [NO_ADD, NO_REMOVE])
4759

4860

49-
def test_wrong_file():
61+
def test_delete_file():
5062
with base_setup() as (test, rs):
51-
rs.files.create_or_update("README.md", "Goodbye")
52-
rs.git.add(all=True)
53-
rs.git.commit(message="Update README.md")
63+
rs.files.delete("shopping-list.txt")
5464

5565
output = test.run()
56-
assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [WRONG_FILE])
66+
assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [SHOPPING_LIST_FILE_MISSING])
5767

5868

59-
def test_only_edit():
69+
def test_add_only():
70+
with base_setup() as (test, rs):
71+
rs.files.append("shopping-list.txt", "- Chicken\n",)
72+
73+
output = test.run()
74+
assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [NO_REMOVE])
75+
76+
77+
def test_remove_only():
6078
with base_setup() as (test, rs):
6179
rs.files.create_or_update(
6280
"shopping-list.txt",
@@ -65,27 +83,14 @@ def test_only_edit():
6583
- Eggs
6684
- Bread
6785
- Apples
68-
- Ham1
6986
""",
7087
)
71-
rs.git.add(all=True)
72-
rs.git.commit(message="Update shopping list")
73-
74-
output = test.run()
75-
assert_output(output, GitAutograderStatus.SUCCESSFUL)
76-
77-
78-
def test_no_add():
79-
with base_setup() as (test, rs):
80-
rs.files.create_or_update("shopping-list.txt", "- Milk")
81-
rs.git.add(all=True)
82-
rs.git.commit(message="Update shopping list")
8388

8489
output = test.run()
8590
assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [NO_ADD])
8691

8792

88-
def test_no_remove():
93+
def test_changes_not_committed():
8994
with base_setup() as (test, rs):
9095
rs.files.create_or_update(
9196
"shopping-list.txt",
@@ -94,19 +99,20 @@ def test_no_remove():
9499
- Eggs
95100
- Bread
96101
- Apples
97-
- Ham
98102
- Chicken
99103
""",
100104
)
101-
rs.git.add(all=True)
102-
rs.git.commit(message="Update shopping list")
103105

104106
output = test.run()
105-
assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [NO_REMOVE])
107+
assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [ADD_NOT_COMMITTED, REMOVE_NOT_COMMITTED])
106108

107109

108-
def test_one_shot():
110+
def test_add_committed_only():
109111
with base_setup() as (test, rs):
112+
rs.files.append("shopping-list.txt", "- Chicken\n",)
113+
rs.git.add(all=True)
114+
rs.git.commit(message="Add Chicken to shopping list")
115+
110116
rs.files.create_or_update(
111117
"shopping-list.txt",
112118
"""
@@ -115,16 +121,14 @@ def test_one_shot():
115121
- Bread
116122
- Apples
117123
- Chicken
118-
""",
124+
"""
119125
)
120-
rs.git.add(all=True)
121-
rs.git.commit(message="Update shopping list")
122126

123127
output = test.run()
124-
assert_output(output, GitAutograderStatus.SUCCESSFUL)
128+
assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [REMOVE_NOT_COMMITTED])
125129

126130

127-
def test_complex():
131+
def test_remove_committed_only():
128132
with base_setup() as (test, rs):
129133
rs.files.create_or_update(
130134
"shopping-list.txt",
@@ -133,11 +137,19 @@ def test_complex():
133137
- Eggs
134138
- Bread
135139
- Apples
136-
""",
140+
"""
137141
)
138142
rs.git.add(all=True)
139-
rs.git.commit(message="Delete item")
143+
rs.git.commit(message="Add Chicken to shopping list")
144+
145+
rs.files.append("shopping-list.txt", "- Chicken\n",)
140146

147+
output = test.run()
148+
assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [ADD_NOT_COMMITTED])
149+
150+
151+
def test_successful_change():
152+
with base_setup() as (test, rs):
141153
rs.files.create_or_update(
142154
"shopping-list.txt",
143155
"""
@@ -149,7 +161,7 @@ def test_complex():
149161
""",
150162
)
151163
rs.git.add(all=True)
152-
rs.git.commit(message="Add item")
164+
rs.git.commit(message="Update shopping list")
153165

154166
output = test.run()
155167
assert_output(output, GitAutograderStatus.SUCCESSFUL)

grocery_shopping/verify.py

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12
from typing import List
23

34
from git_autograder import (
@@ -6,33 +7,56 @@
67
GitAutograderStatus,
78
)
89

9-
EMPTY_COMMITS = "All commits are empty."
10-
NO_DIFF = "There are no changes made to shopping-list.txt."
1110
NO_ADD = "There are no new grocery list items added to the shopping list."
1211
NO_REMOVE = "There are no grocery list items removed from the shopping list."
13-
WRONG_FILE = "You haven't edited shopping-list.txt."
12+
SHOPPING_LIST_FILE_MISSING = "The shopping-list.txt file should not be deleted."
13+
ADD_NOT_COMMITTED = "New grocery list items added to shopping-list.txt are not committed."
14+
REMOVE_NOT_COMMITTED = "Grocery list items removed from shopping-list.txt are not committed."
1415

1516
ORIGINAL_SHOPPING_LIST = {"Milk", "Eggs", "Bread", "Apples", "Ham"}
1617

1718

1819
def verify(exercise: GitAutograderExercise) -> GitAutograderOutput:
1920
comments: List[str] = []
21+
repo_root = exercise.exercise_path
22+
repo_folder = exercise.config.exercise_repo.repo_name
23+
work_dir = os.path.join(repo_root, repo_folder)
2024

21-
main_branch = exercise.repo.branches.branch("main")
25+
shopping_list_file_path = os.path.join(work_dir, "shopping-list.txt")
26+
if not os.path.exists(shopping_list_file_path):
27+
raise exercise.wrong_answer([SHOPPING_LIST_FILE_MISSING])
28+
29+
with open(shopping_list_file_path, "r", encoding="utf-8") as f:
30+
content = f.read()
31+
32+
current_shopping_list = {
33+
line[2:].strip()
34+
for line in content.splitlines()
35+
if line.startswith("- ")
36+
}
37+
38+
added_items = current_shopping_list.difference(ORIGINAL_SHOPPING_LIST)
39+
deleted_items = ORIGINAL_SHOPPING_LIST.difference(current_shopping_list)
40+
41+
if not added_items:
42+
comments.append(NO_ADD)
2243

23-
# Verify that not all commits are empty
24-
if not main_branch.has_non_empty_commits():
25-
raise exercise.wrong_answer([EMPTY_COMMITS])
44+
if not deleted_items:
45+
comments.append(NO_REMOVE)
2646

27-
# Check if they edited the shopping-list.md at least once
28-
if not main_branch.has_edited_file("shopping-list.txt"):
29-
raise exercise.wrong_answer([WRONG_FILE])
47+
if comments:
48+
raise exercise.wrong_answer(comments)
49+
50+
main_branch = exercise.repo.branches.branch("main")
51+
52+
if not main_branch.user_commits:
53+
raise exercise.wrong_answer([ADD_NOT_COMMITTED, REMOVE_NOT_COMMITTED])
3054

3155
shopping_list_blob = (
3256
main_branch.latest_user_commit.commit.tree / "shopping-list.txt"
3357
)
3458
current_shopping_list = {
35-
line[2:]
59+
line[2:].strip()
3660
for line in shopping_list_blob.data_stream.read().decode().split("\n")
3761
if line.startswith("- ")
3862
}
@@ -41,10 +65,10 @@ def verify(exercise: GitAutograderExercise) -> GitAutograderOutput:
4165
deleted_items = ORIGINAL_SHOPPING_LIST.difference(current_shopping_list)
4266

4367
if not added_items:
44-
comments.append(NO_ADD)
68+
comments.append(ADD_NOT_COMMITTED)
4569

4670
if not deleted_items:
47-
comments.append(NO_REMOVE)
71+
comments.append(REMOVE_NOT_COMMITTED)
4872

4973
if comments:
5074
raise exercise.wrong_answer(comments)

0 commit comments

Comments
 (0)