Skip to content

Commit

Permalink
--singular and --plural options, closes #2
Browse files Browse the repository at this point in the history
  • Loading branch information
Simon Willison committed Apr 12, 2019
1 parent e9fbba1 commit 8c1c941
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 34 deletions.
16 changes: 9 additions & 7 deletions csv_diff/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,15 @@ def compare(previous, current):
return result


def human_text(result, key=None):
def human_text(result, key=None, singular=None, plural=None):
singular = singular or "row"
plural = plural or "rows"
title = []
summary = []
show_headers = sum(1 for key in result if result[key]) > 1
if result["changed"]:
fragment = "{} row{} changed".format(
len(result["changed"]), "" if len(result["changed"]) == 1 else "s"
fragment = "{} {} changed".format(
len(result["changed"]), singular if len(result["changed"]) == 1 else plural
)
title.append(fragment)
if show_headers:
Expand All @@ -66,8 +68,8 @@ def human_text(result, key=None):
change_blocks.append("\n".join(block))
summary.append("\n".join(change_blocks))
if result["added"]:
fragment = "{} row{} added".format(
len(result["added"]), "" if len(result["added"]) == 1 else "s"
fragment = "{} {} added".format(
len(result["added"]), singular if len(result["added"]) == 1 else plural
)
title.append(fragment)
if show_headers:
Expand All @@ -78,8 +80,8 @@ def human_text(result, key=None):
summary.append("\n\n".join(rows))
summary.append("")
if result["removed"]:
fragment = "{} row{} removed".format(
len(result["removed"]), "" if len(result["removed"]) == 1 else "s"
fragment = "{} {} removed".format(
len(result["removed"]), singular if len(result["removed"]) == 1 else plural
)
title.append(fragment)
if show_headers:
Expand Down
16 changes: 14 additions & 2 deletions csv_diff/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,22 @@
@click.option(
"--json", type=bool, default=False, help="Output changes as JSON", is_flag=True
)
def cli(previous, current, key, json):
@click.option(
"--singular",
type=str,
default=None,
help="Singular word to use, e.g. 'tree' for '1 tree'",
)
@click.option(
"--plural",
type=str,
default=None,
help="Plural word to use, e.g. 'trees' for '2 trees'",
)
def cli(previous, current, key, json, singular, plural):
"Diff two CSV files"
diff = compare(load_csv(open(previous), key=key), load_csv(open(current), key=key))
if json:
print(std_json.dumps(diff, indent=4))
else:
print(human_text(diff, key))
print(human_text(diff, key, singular, plural))
46 changes: 43 additions & 3 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from click.testing import CliRunner
from csv_diff import cli
from .test_csv_diff import ONE, TWO, THREE
from .test_csv_diff import ONE, TWO, THREE, FIVE
import json
from textwrap import dedent

Expand All @@ -12,12 +12,52 @@ def test_human_cli(tmpdir):
two.write(TWO)
result = CliRunner().invoke(cli.cli, [str(one), str(two), "--key", "id"])
assert 0 == result.exit_code
assert dedent("""
assert (
dedent(
"""
1 row changed
id: 1
age: "4" => "5"
""").strip() == result.output.strip()
"""
).strip()
== result.output.strip()
)


def test_human_cli_alternative_names(tmpdir):
one = tmpdir / "one.csv"
one.write(ONE)
five = tmpdir / "five.csv"
five.write(FIVE)
result = CliRunner().invoke(
cli.cli,
[str(one), str(five), "--key", "id", "--singular", "tree", "--plural", "trees"],
)
assert 0 == result.exit_code, result.output
assert (
dedent(
"""
1 tree changed, 2 trees added
1 tree changed
id: 1
age: "4" => "5"
2 trees added
id: 3
name: Bailey
age: 1
id: 4
name: Carl
age: 7
"""
).strip()
== result.output.strip()
)


def test_human_cli_json(tmpdir):
Expand Down
10 changes: 10 additions & 0 deletions tests/test_csv_diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@
2,Pancakes,2,
3,Bailey,1"""

FIVE = """id,name,age
1,Cleo,5
2,Pancakes,2,
3,Bailey,1
4,Carl,7"""

SIX = """id,name,age
1,Cleo,5
3,Bailey,1"""


def test_row_changed():
diff = compare(
Expand Down
58 changes: 36 additions & 22 deletions tests/test_human_text.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
from csv_diff import load_csv, compare, human_text
from .test_csv_diff import ONE, TWO, THREE, FOUR

FIVE = """id,name,age
1,Cleo,5
2,Pancakes,2,
3,Bailey,1
4,Carl,7"""

SIX = """id,name,age
1,Cleo,5
3,Bailey,1"""

from .test_csv_diff import ONE, TWO, THREE, FOUR, FIVE, SIX
from textwrap import dedent
import io

Expand All @@ -19,32 +8,44 @@ def test_row_changed():
diff = compare(
load_csv(io.StringIO(ONE), key="id"), load_csv(io.StringIO(TWO), key="id")
)
assert dedent("""
assert (
dedent(
"""
1 row changed
id: 1
age: "4" => "5"
""").strip() == human_text(diff, "id")
"""
).strip()
== human_text(diff, "id")
)


def test_row_added():
diff = compare(
load_csv(io.StringIO(THREE), key="id"), load_csv(io.StringIO(TWO), key="id")
)
assert dedent("""
assert (
dedent(
"""
1 row added
id: 2
name: Pancakes
age: 2
""").strip() == human_text(diff, "id")
"""
).strip()
== human_text(diff, "id")
)


def test_rows_added():
diff = compare(
load_csv(io.StringIO(THREE), key="id"), load_csv(io.StringIO(FIVE), key="id")
)
assert dedent("""
assert (
dedent(
"""
3 rows added
id: 2
Expand All @@ -58,28 +59,38 @@ def test_rows_added():
id: 4
name: Carl
age: 7
""").strip() == human_text(diff, "id")
"""
).strip()
== human_text(diff, "id")
)


def test_row_removed():
diff = compare(
load_csv(io.StringIO(TWO), key="id"), load_csv(io.StringIO(THREE), key="id")
)
assert dedent("""
assert (
dedent(
"""
1 row removed
id: 2
name: Pancakes
age: 2
""").strip() == human_text(diff, "id")
"""
).strip()
== human_text(diff, "id")
)


def test_row_changed_and_row_added_and_row_deleted():
"Should have headers for each section here"
diff = compare(
load_csv(io.StringIO(ONE), key="id"), load_csv(io.StringIO(SIX), key="id")
)
assert dedent("""
assert (
dedent(
"""
1 row changed, 1 row added, 1 row removed
1 row changed
Expand All @@ -98,4 +109,7 @@ def test_row_changed_and_row_added_and_row_deleted():
id: 2
name: Pancakes
age: 2
""").strip() == human_text(diff, "id")
"""
).strip()
== human_text(diff, "id")
)

0 comments on commit 8c1c941

Please sign in to comment.