diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml new file mode 100644 index 0000000..9d93237 --- /dev/null +++ b/.github/workflows/python-package.yml @@ -0,0 +1,40 @@ +# This workflow will install Python dependencies, run tests and lint with a variety of Python versions +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python + +name: Python package + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ["3.9", "3.10", "3.11"] + + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python -m pip install flake8 pytest + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: Lint with flake8 + run: | + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Test with pytest + run: | + pytest --import-mode=importlib diff --git a/README.md b/README.md index 5914044..583abab 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,18 @@ It will enclose the expansion of sub-queries in parentheses while expanding, in In order to use one query inside another, use the sub-query's name in brackets inside the outer query. See sample.json for an example. +Sample input: + + { + "home": "{go_to} next {corner}", + "go_to": "See you", + "corner": "Saturday" + } + +Sample output: + + (See you) next (Saturday) + ## How Many Do I Need? The minecraft/hmdin script is basically a counting formatter that can help you keep track of large item quantities in Minecraft. By default, it will print a human-readable listing of all nonzero "units of quantity" necessary to amass the specified amount of items. @@ -69,6 +81,9 @@ You can specify a nonstandard stack size (e.g. 16 for eggs or similar) using `-- The actual helper/split functions are: - hmdin(count, stack_size=64, container_size=27) # will return the tuple of , , - pretty_print(chests, stacks, items) # will format the list of items as human readable (without prefix), e.g. "3 chests and 14 items" - csv_print(chests, stacks, items, separator=",") #will format the list of all three items for CSV output, e.g. comma-separated \ No newline at end of file + # will return the tuple of , , + hmdin(count, stack_size=64, container_size=27) + # will format the list of items as human readable (without prefix), e.g. "3 chests and 14 items" + pretty_print(chests, stacks, items) + #will format the list of all three items for CSV output, e.g. comma-separated + csv_print(chests, stacks, items, separator=",") \ No newline at end of file diff --git a/jqlcomposer/sample.json b/jqlcomposer/sample.json deleted file mode 100644 index 3d6094d..0000000 --- a/jqlcomposer/sample.json +++ /dev/null @@ -1,5 +0,0 @@ -{ -"home": "{go_to} next {corner}", -"go_to": "See you", -"corner": "Saturday" -} \ No newline at end of file diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/jqlcomposer/jqlcomposer.py b/src/jqlcomposer.py similarity index 100% rename from jqlcomposer/jqlcomposer.py rename to src/jqlcomposer.py diff --git a/lsconvert/lsconvert.py b/src/lsconvert.py similarity index 100% rename from lsconvert/lsconvert.py rename to src/lsconvert.py diff --git a/src/minecraft/__init__.py b/src/minecraft/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/minecraft/hmdin.py b/src/minecraft/hmdin.py similarity index 100% rename from minecraft/hmdin.py rename to src/minecraft/hmdin.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/expect1.txt b/tests/expect1.txt new file mode 100644 index 0000000..8d4ab79 --- /dev/null +++ b/tests/expect1.txt @@ -0,0 +1 @@ +("month IN (June, July, August)") AND (temperature > 20) \ No newline at end of file diff --git a/tests/pytest.ini b/tests/pytest.ini new file mode 100644 index 0000000..b893048 --- /dev/null +++ b/tests/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +pythonpath = src \ No newline at end of file diff --git a/tests/test1.json b/tests/test1.json new file mode 100644 index 0000000..b1f0e02 --- /dev/null +++ b/tests/test1.json @@ -0,0 +1,5 @@ +{ + "summer": "{month_in_long_day_territory} AND {temperature_above_lukewarm}", + "month_in_long_day_territory": "month IN (June, July, August)", + "temperature_above_lukewarm": "temperature > 20" +} \ No newline at end of file diff --git a/tests/test_jqlcomposer.py b/tests/test_jqlcomposer.py new file mode 100644 index 0000000..d112bc4 --- /dev/null +++ b/tests/test_jqlcomposer.py @@ -0,0 +1,57 @@ +import subprocess +import filecmp +import jqlcomposer +import contextlib + +TEST_TERMS=["summer"] + +def test_jqlcomposer_main_asfile(): + for i in range(len(TEST_TERMS)): + idx = i+1 + with open(f"tests/testout{idx}.txt", "w") as outfile: + subprocess.run(["python", "src/jqlcomposer.py", TEST_TERMS[i], "--filename", f"tests/test{idx}.json"], stdout=outfile) + assert 0 == filecmp.cmp(f"tests/testout{idx}.txt", f"tests/expect{idx}.txt") + +def test_jqlcomposer_main_astext(): + for i in range(len(TEST_TERMS)): + idx = i+1 + json_contents = "" + with open(f"tests/test{idx}.json", "r") as infile: + json_contents = infile.read() + with open(f"tests/testout{idx}.txt", "w") as outfile: + subprocess.run(["python", "src/jqlcomposer.py", TEST_TERMS[i], f'"{json_contents}"'], stdout=outfile) + assert 0 == filecmp.cmp(f"tests/testout{idx}.txt", f"tests/expect{idx}.txt") + +def test_jqlcomposer_compose_from_file(): + for i in range(len(TEST_TERMS)): + idx = i+1 + with open(f"tests/testout{idx}.txt", "w") as outfile: + with contextlib.redirect_stdout(outfile): + jqlcomposer.create_from_file(f"tests/test{idx}.json", TEST_TERMS[i]) + assert 0 == filecmp.cmp(f"tests/testout{idx}.txt", f"tests/expect{idx}.txt") + +def test_jqlcomposer_compose_from_string(): + for i in range(len(TEST_TERMS)): + idx = i+1 + json_contents = "" + with open(f"tests/test{idx}.json", "r") as infile: + json_contents = infile.read() + with open(f"tests/testout{idx}.txt", "w") as outfile: + with contextlib.redirect_stdout(outfile): + jqlcomposer.create_from_string(json_contents, TEST_TERMS[i]) + assert 0 == filecmp.cmp(f"tests/testout{idx}.txt", f"tests/expect{idx}.txt") + +def test_cut_next(): + is_token, next_slice, remainder = jqlcomposer.cut_next("if in {doubt}, flail about") + assert not is_token + assert next_slice == "if in " + assert remainder == "{doubt}, flail about" + is_token, next_slice, remainder = jqlcomposer.cut_next("{doubt} leads to hostility") + assert is_token + assert next_slice == "doubt" + assert remainder == " leads to hostility" + is_token, next_slice, remainder = jqlcomposer.cut_next("nothing to cut here") + assert not is_token + assert next_slice == "nothing to cut here" + assert remainder == "" + \ No newline at end of file