Skip to content

Commit

Permalink
Updated tests
Browse files Browse the repository at this point in the history
  • Loading branch information
coordt committed Feb 28, 2022
1 parent df365df commit 7c81df5
Show file tree
Hide file tree
Showing 30 changed files with 598 additions and 0 deletions.
Empty file added tests/__init__.py
Empty file.
11 changes: 11 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""Testing configuration."""
from pathlib import Path

import pytest


@pytest.fixture
def fixtures_path() -> Path:
"""Return the path to the testing fixtures."""

return Path(__file__).parent / "fixtures"
6 changes: 6 additions & 0 deletions tests/fixtures/existing.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"number": 1,
"string": "abc",
"list": ["a", 1, "c"],
"dictionary": {"a": 1, "b": [1, 2]}
}
11 changes: 11 additions & 0 deletions tests/fixtures/existing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
number: 1
string: "abc"
list:
- "a"
- 1
- "c"
dictionary:
"a": 1
"b":
- 1
- 2
2 changes: 2 additions & 0 deletions tests/fixtures/gibberish.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- dropdown my_var=pie:
don't parse this
3 changes: 3 additions & 0 deletions tests/fixtures/multi-template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
template: tests/fixtures/template1
---
template: tests/fixtures/template2
6 changes: 6 additions & 0 deletions tests/fixtures/new.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"number": 2,
"string": "def",
"list": ["a", 2],
"dictionary": {"b": [3, 2]}
}
9 changes: 9 additions & 0 deletions tests/fixtures/new.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
number: 2
string: "def"
list:
- "a"
- 2
dictionary:
"b":
- 3
- 2
5 changes: 5 additions & 0 deletions tests/fixtures/rendered1/context.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"project_name": "Test Project",
"repo_name": "testproject",
"_requirements": {"foo": "", "bar": ">=5.0.0"}
}
1 change: 1 addition & 0 deletions tests/fixtures/rendered1/testproject/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# testproject
1 change: 1 addition & 0 deletions tests/fixtures/rendered1/testproject/dontmerge.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"a": 1, "b": 2}
2 changes: 2 additions & 0 deletions tests/fixtures/rendered1/testproject/merge.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
a: 1
b: 2
2 changes: 2 additions & 0 deletions tests/fixtures/rendered1/testproject/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
foo
bar>=5.0.0
5 changes: 5 additions & 0 deletions tests/fixtures/rendered2/context.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"project_name": "Intentionally different name",
"repo_name": "testproject",
"_requirements": {"bar": ">=5.0.0", "baz": ""}
}
1 change: 1 addition & 0 deletions tests/fixtures/rendered2/testproject/ABOUT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Intentionally different name
1 change: 1 addition & 0 deletions tests/fixtures/rendered2/testproject/dontmerge.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"ShouldIMerge": false, "really": true}
2 changes: 2 additions & 0 deletions tests/fixtures/rendered2/testproject/merge.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ShouldIMerge: true
really: true
3 changes: 3 additions & 0 deletions tests/fixtures/rendered2/testproject/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
bar>=5.0.0
baz
foo
1 change: 1 addition & 0 deletions tests/fixtures/single-template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
template: tests/fixtures/template1
5 changes: 5 additions & 0 deletions tests/fixtures/template1/cookiecutter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"project_name": "Fake Project Template",
"repo_name": "{{ cookiecutter.project_name|lower|replace(' ', '-') }}",
"_requirements": {"foo": "", "bar": ">=5.0.0"}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# {{ cookiecutter.repo_name }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{%- for pkg, version in cookiecutter._requirements.items() %}
{{ pkg }}{{ version }}
{%- endfor %}
5 changes: 5 additions & 0 deletions tests/fixtures/template2/cookiecutter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"project_name": "Fake Project Template",
"repo_name": "{{ cookiecutter.project_name|lower|replace(' ', '-') }}",
"_requirements": {"bar": ">=5.0.0", "baz": ""}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# {{ cookiecutter.project_name }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{%- for pkg, version in cookiecutter._requirements.items() %}
{{ pkg }}{{ version }}
{%- endfor %}
49 changes: 49 additions & 0 deletions tests/test_composition.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import pytest

from cookie_composer import composition
from pathlib import Path

from cookie_composer.composition import LayerConfig
from cookie_composer.exceptions import MissingCompositionFileError

# TODO: test bad info in the template composition
# TODO: test missing info in the template composition


def test_multiple_templates(fixtures_path, tmp_path):
filepath = fixtures_path / "multi-template.yaml"
comp = composition.read_composition(filepath, tmp_path)
assert len(comp.layers) == 2
assert comp.layers[0].template == "tests/fixtures/template1"
assert comp.layers[1].template == "tests/fixtures/template2"


def test_single_template(fixtures_path, tmp_path):
filepath = fixtures_path / "single-template.yaml"
comp = composition.read_composition(filepath, tmp_path)
assert len(comp.layers) == 1
assert comp.layers[0].template == "tests/fixtures/template1"


def test_is_composition_file():
assert composition.is_composition_file("single-template.yaml")
assert composition.is_composition_file("single-template.yml")
assert not composition.is_composition_file("single-template.txt")


def test_missing_composition():
with pytest.raises(MissingCompositionFileError):
composition.read_composition("/does/not/exist", "/foo/")


def test_write_composition(tmp_path):
"""Test writing out layers."""
layers = [
LayerConfig(template="tests/fixtures/template1"),
LayerConfig(template="tests/fixtures/template2"),
]
filepath = tmp_path / "composition.yaml"
composition.write_composition(layers, filepath)
comp = composition.read_composition(filepath, tmp_path)
assert comp.layers[0] == layers[0]
assert comp.layers[1] == layers[1]
186 changes: 186 additions & 0 deletions tests/test_layers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
"""Test layer rendering."""
import json
import os
import shutil
from pathlib import Path

from cookie_composer import layers
from cookie_composer.composition import LayerConfig, MergeStrategy, RenderedLayer
from cookie_composer.data_merge import comprehensive_merge


def test_render_layer(fixtures_path, tmp_path):
"""Test rendering a layer."""
layer_conf = LayerConfig(template=str(fixtures_path / "template1"), no_input=True)
rendered_layer = layers.render_layer(layer_conf, tmp_path)
expected_context = json.loads(
Path(fixtures_path / "template1/cookiecutter.json").read_text()
)
expected_context["repo_name"] = "fake-project-template"
expected = RenderedLayer(
layer=layer_conf,
location=tmp_path,
new_context=expected_context,
)
assert rendered_layer == expected
assert len(list(tmp_path.iterdir())) == 1


def test_get_write_strategy_skip_generation(fixtures_path):
"""Files matching a skip generation glob are skipped."""
layer_config = LayerConfig(
template=str(fixtures_path / "template1"),
skip_generation=["README.md"],
skip_if_file_exists=False,
)
rendered_layer = RenderedLayer(
layer=layer_config, location=fixtures_path, new_context={}
)
filepath = fixtures_path / "template1" / "{{cookiecutter.repo_name}}" / "README.md"
assert (
layers.get_write_strategy(filepath, filepath, rendered_layer)
== layers.WriteStrategy.SKIP
)


def test_get_write_strategy_dest_not_exist(tmp_path, fixtures_path):
"""If the destination path doesn't exist, return the write strategy."""

layer_config = LayerConfig(
template=str(fixtures_path / "template1"),
skip_if_file_exists=True,
)
rendered_layer = RenderedLayer(
layer=layer_config, location=fixtures_path, new_context={}
)
filepath = fixtures_path / "template1" / "{{cookiecutter.repo_name}}" / "README.md"
dest_path = tmp_path / "foo" / "README.md"
assert (
layers.get_write_strategy(filepath, dest_path, rendered_layer)
== layers.WriteStrategy.WRITE
)


def test_get_write_strategy_merge_strategy(fixtures_path):
"""Return the correct write strategy for mergable files."""

layer_config = LayerConfig(
template=str(fixtures_path / "template1"),
merge_strategies={
"*.yml": MergeStrategy.OVERWRITE,
"*.yaml": MergeStrategy.OVERWRITE,
"*.json": MergeStrategy.DO_NOT_MERGE,
},
skip_if_file_exists=True,
)
rendered_layer = RenderedLayer(
layer=layer_config, location=fixtures_path, new_context={}
)
filepath = fixtures_path / "existing.yaml"
assert (
layers.get_write_strategy(filepath, filepath, rendered_layer)
== layers.WriteStrategy.MERGE
)
filepath = fixtures_path / "existing.json"
assert (
layers.get_write_strategy(filepath, filepath, rendered_layer)
== layers.WriteStrategy.SKIP
)


def test_get_write_strategy_overwrite_exclude(fixtures_path):
"""Return SKIP if the file matches an overwrite_exclude pattern."""

layer_config = LayerConfig(
template=str(fixtures_path / "template1"),
overwrite_exclude=["*.yaml"],
skip_if_file_exists=True,
)
rendered_layer = RenderedLayer(
layer=layer_config, location=fixtures_path, new_context={}
)
filepath = fixtures_path / "existing.yaml"
assert (
layers.get_write_strategy(filepath, filepath, rendered_layer)
== layers.WriteStrategy.SKIP
)


def test_get_write_strategy_overwrite(fixtures_path):
"""Return WRITE if the file matches an overwrite pattern."""

layer_config = LayerConfig(
template=str(fixtures_path / "template1"),
overwrite=["*.yaml"],
skip_if_file_exists=True,
)
rendered_layer = RenderedLayer(
layer=layer_config, location=fixtures_path, new_context={}
)
filepath = fixtures_path / "existing.yaml"
assert (
layers.get_write_strategy(filepath, filepath, rendered_layer)
== layers.WriteStrategy.WRITE
)


def test_get_write_strategy_skip_if_file_exists(fixtures_path):
"""Return SKIP or WRITE based on the skip_if_file_exists setting."""

layer_config = LayerConfig(
template=str(fixtures_path / "template1"),
skip_if_file_exists=True,
)
rendered_layer = RenderedLayer(
layer=layer_config, location=fixtures_path, new_context={}
)
filepath = fixtures_path / "existing.yaml"
assert (
layers.get_write_strategy(filepath, filepath, rendered_layer)
== layers.WriteStrategy.SKIP
)

rendered_layer.layer.skip_if_file_exists = False
assert (
layers.get_write_strategy(filepath, filepath, rendered_layer)
== layers.WriteStrategy.WRITE
)


def test_merge_layers(tmp_path, fixtures_path):
"""Test merging layers together."""
# copy rendered1 layer to temp dir
rendered1 = fixtures_path / "rendered1"
rendered_layer_path = shutil.copytree(rendered1, tmp_path, dirs_exist_ok=True)
context1 = json.loads((rendered1 / "context.json").read_text())

# create a rendered layer object for rendered2
layer_config = LayerConfig(
template=str(fixtures_path / "template2"),
skip_if_file_exists=False,
merge_strategies={
"*.json": MergeStrategy.DO_NOT_MERGE,
"*.yaml": MergeStrategy.OVERWRITE,
},
)
context2 = json.loads((fixtures_path / "rendered2" / "context.json").read_text())
full_context = comprehensive_merge(context1, context2)
rendered2_config = RenderedLayer(
layer=layer_config,
location=fixtures_path / "rendered2",
new_context=full_context,
)
# merge the layers
layers.merge_layers(rendered_layer_path, rendered2_config)

# check the merged layers in the temp dir are accurate
readme_content = (rendered_layer_path / "testproject/README.md").read_text()
assert readme_content == "# testproject\n"

about_content = (rendered_layer_path / "testproject/ABOUT.md").read_text()
assert about_content == "# Intentionally different name\n"

requirements_content = (
rendered_layer_path / "testproject/requirements.txt"
).read_text()
assert requirements_content == "bar>=5.0.0\nbaz\nfoo\n"
Loading

0 comments on commit 7c81df5

Please sign in to comment.