Skip to content

Commit 8c1c941

Browse files
author
Simon Willison
committed
--singular and --plural options, closes #2
1 parent e9fbba1 commit 8c1c941

File tree

5 files changed

+112
-34
lines changed

5 files changed

+112
-34
lines changed

Diff for: csv_diff/__init__.py

+9-7
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,15 @@ def compare(previous, current):
4343
return result
4444

4545

46-
def human_text(result, key=None):
46+
def human_text(result, key=None, singular=None, plural=None):
47+
singular = singular or "row"
48+
plural = plural or "rows"
4749
title = []
4850
summary = []
4951
show_headers = sum(1 for key in result if result[key]) > 1
5052
if result["changed"]:
51-
fragment = "{} row{} changed".format(
52-
len(result["changed"]), "" if len(result["changed"]) == 1 else "s"
53+
fragment = "{} {} changed".format(
54+
len(result["changed"]), singular if len(result["changed"]) == 1 else plural
5355
)
5456
title.append(fragment)
5557
if show_headers:
@@ -66,8 +68,8 @@ def human_text(result, key=None):
6668
change_blocks.append("\n".join(block))
6769
summary.append("\n".join(change_blocks))
6870
if result["added"]:
69-
fragment = "{} row{} added".format(
70-
len(result["added"]), "" if len(result["added"]) == 1 else "s"
71+
fragment = "{} {} added".format(
72+
len(result["added"]), singular if len(result["added"]) == 1 else plural
7173
)
7274
title.append(fragment)
7375
if show_headers:
@@ -78,8 +80,8 @@ def human_text(result, key=None):
7880
summary.append("\n\n".join(rows))
7981
summary.append("")
8082
if result["removed"]:
81-
fragment = "{} row{} removed".format(
82-
len(result["removed"]), "" if len(result["removed"]) == 1 else "s"
83+
fragment = "{} {} removed".format(
84+
len(result["removed"]), singular if len(result["removed"]) == 1 else plural
8385
)
8486
title.append(fragment)
8587
if show_headers:

Diff for: csv_diff/cli.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,22 @@
1919
@click.option(
2020
"--json", type=bool, default=False, help="Output changes as JSON", is_flag=True
2121
)
22-
def cli(previous, current, key, json):
22+
@click.option(
23+
"--singular",
24+
type=str,
25+
default=None,
26+
help="Singular word to use, e.g. 'tree' for '1 tree'",
27+
)
28+
@click.option(
29+
"--plural",
30+
type=str,
31+
default=None,
32+
help="Plural word to use, e.g. 'trees' for '2 trees'",
33+
)
34+
def cli(previous, current, key, json, singular, plural):
2335
"Diff two CSV files"
2436
diff = compare(load_csv(open(previous), key=key), load_csv(open(current), key=key))
2537
if json:
2638
print(std_json.dumps(diff, indent=4))
2739
else:
28-
print(human_text(diff, key))
40+
print(human_text(diff, key, singular, plural))

Diff for: tests/test_cli.py

+43-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from click.testing import CliRunner
22
from csv_diff import cli
3-
from .test_csv_diff import ONE, TWO, THREE
3+
from .test_csv_diff import ONE, TWO, THREE, FIVE
44
import json
55
from textwrap import dedent
66

@@ -12,12 +12,52 @@ def test_human_cli(tmpdir):
1212
two.write(TWO)
1313
result = CliRunner().invoke(cli.cli, [str(one), str(two), "--key", "id"])
1414
assert 0 == result.exit_code
15-
assert dedent("""
15+
assert (
16+
dedent(
17+
"""
1618
1 row changed
1719
1820
id: 1
1921
age: "4" => "5"
20-
""").strip() == result.output.strip()
22+
"""
23+
).strip()
24+
== result.output.strip()
25+
)
26+
27+
28+
def test_human_cli_alternative_names(tmpdir):
29+
one = tmpdir / "one.csv"
30+
one.write(ONE)
31+
five = tmpdir / "five.csv"
32+
five.write(FIVE)
33+
result = CliRunner().invoke(
34+
cli.cli,
35+
[str(one), str(five), "--key", "id", "--singular", "tree", "--plural", "trees"],
36+
)
37+
assert 0 == result.exit_code, result.output
38+
assert (
39+
dedent(
40+
"""
41+
1 tree changed, 2 trees added
42+
43+
1 tree changed
44+
45+
id: 1
46+
age: "4" => "5"
47+
48+
2 trees added
49+
50+
id: 3
51+
name: Bailey
52+
age: 1
53+
54+
id: 4
55+
name: Carl
56+
age: 7
57+
"""
58+
).strip()
59+
== result.output.strip()
60+
)
2161

2262

2363
def test_human_cli_json(tmpdir):

Diff for: tests/test_csv_diff.py

+10
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@
1717
2,Pancakes,2,
1818
3,Bailey,1"""
1919

20+
FIVE = """id,name,age
21+
1,Cleo,5
22+
2,Pancakes,2,
23+
3,Bailey,1
24+
4,Carl,7"""
25+
26+
SIX = """id,name,age
27+
1,Cleo,5
28+
3,Bailey,1"""
29+
2030

2131
def test_row_changed():
2232
diff = compare(

Diff for: tests/test_human_text.py

+36-22
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,5 @@
11
from csv_diff import load_csv, compare, human_text
2-
from .test_csv_diff import ONE, TWO, THREE, FOUR
3-
4-
FIVE = """id,name,age
5-
1,Cleo,5
6-
2,Pancakes,2,
7-
3,Bailey,1
8-
4,Carl,7"""
9-
10-
SIX = """id,name,age
11-
1,Cleo,5
12-
3,Bailey,1"""
13-
2+
from .test_csv_diff import ONE, TWO, THREE, FOUR, FIVE, SIX
143
from textwrap import dedent
154
import io
165

@@ -19,32 +8,44 @@ def test_row_changed():
198
diff = compare(
209
load_csv(io.StringIO(ONE), key="id"), load_csv(io.StringIO(TWO), key="id")
2110
)
22-
assert dedent("""
11+
assert (
12+
dedent(
13+
"""
2314
1 row changed
2415
2516
id: 1
2617
age: "4" => "5"
27-
""").strip() == human_text(diff, "id")
18+
"""
19+
).strip()
20+
== human_text(diff, "id")
21+
)
2822

2923

3024
def test_row_added():
3125
diff = compare(
3226
load_csv(io.StringIO(THREE), key="id"), load_csv(io.StringIO(TWO), key="id")
3327
)
34-
assert dedent("""
28+
assert (
29+
dedent(
30+
"""
3531
1 row added
3632
3733
id: 2
3834
name: Pancakes
3935
age: 2
40-
""").strip() == human_text(diff, "id")
36+
"""
37+
).strip()
38+
== human_text(diff, "id")
39+
)
4140

4241

4342
def test_rows_added():
4443
diff = compare(
4544
load_csv(io.StringIO(THREE), key="id"), load_csv(io.StringIO(FIVE), key="id")
4645
)
47-
assert dedent("""
46+
assert (
47+
dedent(
48+
"""
4849
3 rows added
4950
5051
id: 2
@@ -58,28 +59,38 @@ def test_rows_added():
5859
id: 4
5960
name: Carl
6061
age: 7
61-
""").strip() == human_text(diff, "id")
62+
"""
63+
).strip()
64+
== human_text(diff, "id")
65+
)
6266

6367

6468
def test_row_removed():
6569
diff = compare(
6670
load_csv(io.StringIO(TWO), key="id"), load_csv(io.StringIO(THREE), key="id")
6771
)
68-
assert dedent("""
72+
assert (
73+
dedent(
74+
"""
6975
1 row removed
7076
7177
id: 2
7278
name: Pancakes
7379
age: 2
74-
""").strip() == human_text(diff, "id")
80+
"""
81+
).strip()
82+
== human_text(diff, "id")
83+
)
7584

7685

7786
def test_row_changed_and_row_added_and_row_deleted():
7887
"Should have headers for each section here"
7988
diff = compare(
8089
load_csv(io.StringIO(ONE), key="id"), load_csv(io.StringIO(SIX), key="id")
8190
)
82-
assert dedent("""
91+
assert (
92+
dedent(
93+
"""
8394
1 row changed, 1 row added, 1 row removed
8495
8596
1 row changed
@@ -98,4 +109,7 @@ def test_row_changed_and_row_added_and_row_deleted():
98109
id: 2
99110
name: Pancakes
100111
age: 2
101-
""").strip() == human_text(diff, "id")
112+
"""
113+
).strip()
114+
== human_text(diff, "id")
115+
)

0 commit comments

Comments
 (0)