Skip to content

Commit

Permalink
Merge pull request #84 from hugovk/copy-single-search-results
Browse files Browse the repository at this point in the history
  • Loading branch information
hugovk authored Mar 4, 2022
2 parents 3561ec7 + 3729f0c commit d65a1a0
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 30 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-20.04

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/labels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: micnncim/action-label-syncer@v1
with:
prune: false
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ jobs:
runs-on: ubuntu-20.04

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
- uses: pre-commit/[email protected]
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- { codecov-flag: GHA_Windows, os: windows-latest }

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
Expand Down
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,33 @@ Emoji can be also searched by both categories and aspects.

Let's serve some delicious cake:

<!-- [[[cog
from scripts.run_command import run
run("em sparkles shortcake sparkles")
]]] -->

```console
$ em sparkles shortcake sparkles
Copied! ✨🍰
Copied! ✨ 🍰
```

<!-- [[[end]]] -->

Let's skip the copying (for scripts):

<!-- [[[cog run("em 'chocolate bar' --no-copy") ]]] -->

```console
$ em 'chocolate bar' --no-copy
🍫
```

<!-- [[[end]]] -->

Let's find some emoji, by color:

<!-- [[[cog run("em -s yellow") ]]] -->

```console
$ em -s yellow
💛 yellow_heart
Expand All @@ -46,6 +59,19 @@ $ em -s yellow
🟨 yellow_square
```

<!-- [[[end]]] -->

If there's only a single search result, it's copied:

<!-- [[[cog run("em -s ukraine") ]]] -->

```console
$ em -s ukraine
Copied! 🇺🇦 flag_ukraine
```

<!-- [[[end]]] -->

## Installation

At this time, **em** requires Python and pip:
Expand Down
8 changes: 7 additions & 1 deletion em/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,13 @@ def cli():
for (name, emoji) in found:
# Some registered emoji have no value.
try:
print(f"{emoji} {name}")
# Copy the results (and say so!) to the clipboard.
if copier and not no_copy and len(found) == 1:
copier.copy(emoji)
print(f"Copied! {emoji} {name}")
else:
print(f"{emoji} {name}")

# Sometimes, an emoji will have no value.
except TypeError:
pass
Expand Down
19 changes: 19 additions & 0 deletions scripts/run_command.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import shlex
import subprocess


def run(command: str, with_console: bool = True, line_limit: int = None) -> None:
output = subprocess.run(shlex.split(command), capture_output=True, text=True)
print()
if with_console:
print("```console")
print(f"$ {command}")

output = output.stdout.strip()
if line_limit:
output = "".join(output.splitlines(keepends=True)[:line_limit]) + "..."
print(output)

if with_console:
print("```")
print()
69 changes: 47 additions & 22 deletions tests/test_em.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,63 +16,64 @@
],
)
@patch("em.argparse.ArgumentParser.parse_args")
@patch("em.sys.exit")
@patch("builtins.print")
def test_star(mock_print, mock_exit, mock_argparse, test_name):
def test_star(mock_print, mock_argparse, test_name):
# Arrange
mock_argparse.return_value = argparse.Namespace(
name=[test_name], no_copy=None, search=None
)

# Act
cli()
with pytest.raises(SystemExit) as e:
cli()

# Assert
if copier:
mock_print.assert_called_once_with("Copied! ⭐")
else:
mock_print.assert_called_once_with("⭐")
mock_exit.assert_called_with(0)
assert e.type == SystemExit
assert e.value.code == 0


@patch("em.argparse.ArgumentParser.parse_args")
@patch("em.sys.exit")
@patch("builtins.print")
def test_not_found(mock_print, mock_exit, mock_argparse):
def test_not_found(mock_print, mock_argparse):
# Arrange
mock_argparse.return_value = argparse.Namespace(
name=["xxx"], no_copy=None, search=None
)

# Act
cli()
with pytest.raises(SystemExit) as e:
cli()

# Assert
mock_print.assert_called_once_with("")
mock_exit.assert_called_with(1)
assert e.type == SystemExit
assert e.value.code == 1


@patch("em.argparse.ArgumentParser.parse_args")
@patch("em.sys.exit")
@patch("builtins.print")
def test_no_copy(mock_print, mock_exit, mock_argparse):
def test_no_copy(mock_print, mock_argparse):
# Arrange
mock_argparse.return_value = argparse.Namespace(
name=["star"], no_copy=True, search=None
)

# Act
cli()
with pytest.raises(SystemExit) as e:
cli()

# Assert
mock_print.assert_called_once_with("⭐")
mock_exit.assert_called_with(0)
assert e.type == SystemExit
assert e.value.code == 0


@patch("em.argparse.ArgumentParser.parse_args")
@patch("em.sys.exit")
@patch("builtins.print")
def test_search_star(mock_print, mock_exit, mock_argparse):
def test_search_star(mock_print, mock_argparse):
# Arrange
mock_argparse.return_value = argparse.Namespace(
name=["star"], no_copy=None, search=True
Expand All @@ -84,26 +85,50 @@ def test_search_star(mock_print, mock_exit, mock_argparse):
)

# Act
cli()
with pytest.raises(SystemExit) as e:
cli()

# Assert
for arg in expected:
assert call(arg) in mock_print.call_args_list
mock_exit.assert_called_with(0)
assert e.type == SystemExit
assert e.value.code == 0


@patch("em.argparse.ArgumentParser.parse_args")
@patch("em.sys.exit")
@patch("builtins.print")
def test_search_not_found(mock_print, mock_exit, mock_argparse):
def test_search_single_result_is_copied(mock_print, mock_argparse):
# Arrange
mock_argparse.return_value = argparse.Namespace(
name=["ukraine"], no_copy=None, search=True
)

# Act
with pytest.raises(SystemExit) as e:
cli()

# Assert
if copier:
mock_print.assert_called_once_with("Copied! 🇺🇦 flag_ukraine")
else:
mock_print.assert_called_once_with("🇺🇦 flag_ukraine")
assert e.type == SystemExit
assert e.value.code == 0


@patch("em.argparse.ArgumentParser.parse_args")
@patch("builtins.print")
def test_search_not_found(mock_print, mock_argparse):
# Arrange
mock_argparse.return_value = argparse.Namespace(
name=["twenty_o_clock"], no_copy=None, search=True
)

# Act
cli()
with pytest.raises(SystemExit) as e:
cli()

# Assert
mock_print.assert_called_once_with("")
mock_exit.assert_called_with(1)
mock_print.assert_not_called()
assert e.type == SystemExit
assert e.value.code == 1
10 changes: 8 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ envlist =
extras =
tests
commands =
{envpython} -m pytest --cov em --cov tests --cov-report term {posargs}
{envpython} -m coverage xml
{envpython} -m pytest --cov em --cov tests --cov-report html --cov-report term --cov-report xml {posargs}

[testenv:cli]
commands =
Expand All @@ -25,3 +24,10 @@ deps =
pre-commit
commands =
pre-commit run --all-files --show-diff-on-failure

[testenv:cog]
skip_install = true
deps =
cogapp
commands =
cog -Pr README.md

0 comments on commit d65a1a0

Please sign in to comment.