test_describe.py

Last source

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
"""Module holding BDD tests for isshub Namespace code_repository entity as defined in ``describe.feature``."""
from functools import partial
from uuid import uuid4

import pytest
from pytest import mark
from pytest_bdd import given, parsers, scenario, scenarios, then

from isshub.domain.contexts.code_repository.entities.namespace import NamespaceKind
from isshub.domain.utils.testing.validation import (
    FrozenAttributeError,
    check_field,
    check_field_not_nullable,
    check_field_nullable,
    check_field_value,
    string_only,
    uuid4_only,
)

from .fixtures import namespace, namespace_factory


FEATURE_FILE = "../features/describe.feature"
scenario = partial(scenario, FEATURE_FILE)


@mark.parametrize(["value", "exception"], uuid4_only)
@scenario("A namespace identifier is a uuid")
def test_namespace_identifier_is_a_uuid(value, exception):
    pass


@mark.parametrize(["value", "exception"], string_only)
@scenario("A namespace name is a string")
def test_namespace_name_is_a_string(value, exception):
    pass


@mark.parametrize(
    ["value", "exception"],
    [(pytest.lazy_fixture("namespace"), None), ("foo", TypeError), (1, TypeError)],
)
@scenario("A namespace namespace is a namespace")
def test_namespace_namespace_is_a_namespace(value, exception):
    pass


@mark.parametrize(
    ["value", "exception"],
    [(NamespaceKind.GROUP, None), ("foo", TypeError), (1, TypeError)],
)
@scenario("A namespace kind is a NamespaceKind")
def test_namespace_kind_is_a_namespacekind(value, exception):
    pass


@mark.parametrize(["value", "exception"], string_only)
@scenario("A namespace description is a string")
def test_namespace_description_is_a_string(value, exception):
    pass


@given("a namespace", target_fixture="namespace")
def a_namespace(namespace_factory):
    return namespace_factory()


@then(parsers.parse("it must have a field named {field_name:w}"))
def namespace_has_field(namespace, field_name):
    check_field(namespace, field_name)


@then(parsers.parse("its {field_name:w} must be a {field_type}"))
def namespace_field_is_of_a_certain_type(
    namespace_factory,
    field_name,
    field_type,
    # next args are for parametrize
    value,
    exception,
):
    check_field_value(namespace_factory, field_name, value, exception)


@then(parsers.parse("its {field_name:w} is mandatory"))
def namespace_field_is_mandatory(namespace_factory, field_name):
    check_field_not_nullable(namespace_factory, field_name)


@then(parsers.parse("its {field_name:w} is optional"))
def namespace_field_is_optional(namespace_factory, field_name):
    check_field_nullable(namespace_factory, field_name)


@scenario("A namespace identifier cannot be changed")
def test_namespace_identifier_cannot_be_changed():
    pass


@then("its identifier cannot be changed")
def namespace_identifier_cannot_be_changed(namespace):
    with pytest.raises(FrozenAttributeError):
        namespace.identifier = uuid4()


@scenario("A namespace cannot be contained in itself")
def test_namespace_namespace_cannot_be_itself():
    pass


@then("its namespace cannot be itself")
def namespace_namespace_cannot_be_itself(namespace):
    namespace.namespace = namespace
    with pytest.raises(ValueError):
        namespace.validate()


@scenario("A namespace namespace cannot be in a loop")
def test_namespace_namespace_cannot_be_in_a_loop():
    pass


@given("a second namespace", target_fixture="namespace2")
def a_second_namespace(namespace_factory):
    return namespace_factory()


@given("a third namespace", target_fixture="namespace3")
def a_third_namespace(namespace_factory):
    return namespace_factory()


@then("we cannot create a relationships loop with these namespaces")
def namespace_relationships_cannot_create_a_loop(namespace, namespace2, namespace3):
    namespace2.namespace = namespace3
    namespace3.validate()
    namespace2.validate()
    namespace.validate()
    namespace.namespace = namespace2
    namespace3.validate()
    namespace2.validate()
    namespace.validate()
    namespace3.namespace = namespace
    with pytest.raises(ValueError):
        namespace3.validate()
    with pytest.raises(ValueError):
        namespace2.validate()
    with pytest.raises(ValueError):
        namespace.validate()
    namespace3.namespace = None
    namespace3.validate()
    namespace2.validate()
    namespace.validate()


# To make pytest-bdd fail if some scenarios are not implemented. KEEP AT THE END
scenarios(FEATURE_FILE)

Changes

feat(repository): Add domain repositories

Commit
Hash

27f013e2a3722926a9bbe300a77a493604f0993c

Date

2020-10-06 17:30:45 +0200

Type

Modified

Stats

+21 -15

@@ -1,4 +1,5 @@
-"""Module holding BDD tests for isshub Namespace code_repository entity."""
+"""Module holding BDD tests for isshub Namespace code_repository entity as defined in ``describe.feature``."""
+from functools import partial
 from uuid import uuid4

 import pytest
@@ -19,14 +20,18 @@ from isshub.domain.utils.testing.validation import (
 from .fixtures import namespace, namespace_factory


+FEATURE_FILE = "../features/describe.feature"
+scenario = partial(scenario, FEATURE_FILE)
+
+
 @mark.parametrize(["value", "exception"], uuid4_only)
-@scenario("../features/describe.feature", "A Namespace identifier is a uuid")
+@scenario("A namespace identifier is a uuid")
 def test_namespace_identifier_is_a_uuid(value, exception):
     pass


 @mark.parametrize(["value", "exception"], string_only)
-@scenario("../features/describe.feature", "A Namespace name is a string")
+@scenario("A namespace name is a string")
 def test_namespace_name_is_a_string(value, exception):
     pass

@@ -35,7 +40,7 @@ def test_namespace_name_is_a_string(value, exception):
     ["value", "exception"],
     [(pytest.lazy_fixture("namespace"), None), ("foo", TypeError), (1, TypeError)],
 )
-@scenario("../features/describe.feature", "A Namespace namespace is a Namespace")
+@scenario("A namespace namespace is a namespace")
 def test_namespace_namespace_is_a_namespace(value, exception):
     pass

@@ -44,21 +49,18 @@ def test_namespace_namespace_is_a_namespace(value, exception):
     ["value", "exception"],
     [(NamespaceKind.GROUP, None), ("foo", TypeError), (1, TypeError)],
 )
-@scenario("../features/describe.feature", "A Namespace kind is a NamespaceKind")
+@scenario("A namespace kind is a NamespaceKind")
 def test_namespace_kind_is_a_namespacekind(value, exception):
     pass


 @mark.parametrize(["value", "exception"], string_only)
-@scenario("../features/describe.feature", "A Namespace description is a string")
+@scenario("A namespace description is a string")
 def test_namespace_description_is_a_string(value, exception):
     pass


-scenarios("../features/describe.feature")
-
-
-@given("a Namespace", target_fixture="namespace")
+@given("a namespace", target_fixture="namespace")
 def a_namespace(namespace_factory):
     return namespace_factory()

@@ -90,7 +92,7 @@ def namespace_field_is_optional(namespace_factory, field_name):
     check_field_nullable(namespace_factory, field_name)


-@scenario("../features/describe.feature", "A Namespace identifier cannot be changed")
+@scenario("A namespace identifier cannot be changed")
 def test_namespace_identifier_cannot_be_changed():
     pass

@@ -101,7 +103,7 @@ def namespace_identifier_cannot_be_changed(namespace):
         namespace.identifier = uuid4()


-@scenario("../features/describe.feature", "A Namespace cannot be contained in itself")
+@scenario("A namespace cannot be contained in itself")
 def test_namespace_namespace_cannot_be_itself():
     pass

@@ -113,17 +115,17 @@ def namespace_namespace_cannot_be_itself(namespace):
         namespace.validate()


-@scenario("../features/describe.feature", "A Namespace namespace cannot be in a loop")
+@scenario("A namespace namespace cannot be in a loop")
 def test_namespace_namespace_cannot_be_in_a_loop():
     pass


-@given("a second Namespace", target_fixture="namespace2")
+@given("a second namespace", target_fixture="namespace2")
 def a_second_namespace(namespace_factory):
     return namespace_factory()


-@given("a third Namespace", target_fixture="namespace3")
+@given("a third namespace", target_fixture="namespace3")
 def a_third_namespace(namespace_factory):
     return namespace_factory()

@@ -149,3 +151,7 @@ def namespace_relationships_cannot_create_a_loop(namespace, namespace2, namespac
     namespace3.validate()
     namespace2.validate()
     namespace.validate()
+
+
+# To make pytest-bdd fail if some scenarios are not implemented. KEEP AT THE END
+scenarios(FEATURE_FILE)

fix(entity): id changed from int to uuid4, renamed to identifier

Commit
Hash

79f704bde4575a9ddeb623d67d8965a62138adc9

Date

2020-10-05 10:51:49 +0200

Type

Modified

Stats

+10 -9

@@ -1,4 +1,5 @@
 """Module holding BDD tests for isshub Namespace code_repository entity."""
+from uuid import uuid4

 import pytest
 from pytest import mark
@@ -11,16 +12,16 @@ from isshub.domain.utils.testing.validation import (
     check_field_not_nullable,
     check_field_nullable,
     check_field_value,
-    positive_integer_only,
     string_only,
+    uuid4_only,
 )

 from .fixtures import namespace, namespace_factory


-@mark.parametrize(["value", "exception"], positive_integer_only)
-@scenario("../features/describe.feature", "A Namespace id is a positive integer")
-def test_namespace_id_is_a_positive_integer(value, exception):
+@mark.parametrize(["value", "exception"], uuid4_only)
+@scenario("../features/describe.feature", "A Namespace identifier is a uuid")
+def test_namespace_identifier_is_a_uuid(value, exception):
     pass


@@ -89,15 +90,15 @@ def namespace_field_is_optional(namespace_factory, field_name):
     check_field_nullable(namespace_factory, field_name)


-@scenario("../features/describe.feature", "A Namespace id cannot be changed")
-def test_namespace_id_cannot_be_changed():
+@scenario("../features/describe.feature", "A Namespace identifier cannot be changed")
+def test_namespace_identifier_cannot_be_changed():
     pass


-@then("its id cannot be changed")
-def namespace_id_cannot_be_changed(namespace):
+@then("its identifier cannot be changed")
+def namespace_identifier_cannot_be_changed(namespace):
     with pytest.raises(FrozenAttributeError):
-        namespace.id = namespace.id + 1
+        namespace.identifier = uuid4()


 @scenario("../features/describe.feature", "A Namespace cannot be contained in itself")

fix(entities): Entities id field are frozen once set

Commit
Hash

ef8edc20b6a674bfc98c79028684279bcc9ed324

Date

2020-09-27 09:56:59 +0200

Type

Modified

Stats

+12 -0

@@ -6,6 +6,7 @@ from pytest_bdd import given, parsers, scenario, scenarios, then

 from isshub.domain.contexts.code_repository.entities.namespace import NamespaceKind
 from isshub.domain.utils.testing.validation import (
+    FrozenAttributeError,
     check_field,
     check_field_not_nullable,
     check_field_nullable,
@@ -88,6 +89,17 @@ def namespace_field_is_optional(namespace_factory, field_name):
     check_field_nullable(namespace_factory, field_name)


+@scenario("../features/describe.feature", "A Namespace id cannot be changed")
+def test_namespace_id_cannot_be_changed():
+    pass
+
+
+@then("its id cannot be changed")
+def namespace_id_cannot_be_changed(namespace):
+    with pytest.raises(FrozenAttributeError):
+        namespace.id = namespace.id + 1
+
+
 @scenario("../features/describe.feature", "A Namespace cannot be contained in itself")
 def test_namespace_namespace_cannot_be_itself():
     pass

fix(namespace): Namespaces relationships should not create a loop

Commit
Hash

afeb5f86809b05cf3ef131a59de1ed9235d59a8d

Date

2020-09-26 22:38:26 +0200

Type

Modified

Stats

+50 -0

@@ -86,3 +86,53 @@ def namespace_field_is_mandatory(namespace_factory, field_name):
 @then(parsers.parse("its {field_name:w} is optional"))
 def namespace_field_is_optional(namespace_factory, field_name):
     check_field_nullable(namespace_factory, field_name)
+
+
+@scenario("../features/describe.feature", "A Namespace cannot be contained in itself")
+def test_namespace_namespace_cannot_be_itself():
+    pass
+
+
+@then("its namespace cannot be itself")
+def namespace_namespace_cannot_be_itself(namespace):
+    namespace.namespace = namespace
+    with pytest.raises(ValueError):
+        namespace.validate()
+
+
+@scenario("../features/describe.feature", "A Namespace namespace cannot be in a loop")
+def test_namespace_namespace_cannot_be_in_a_loop():
+    pass
+
+
+@given("a second Namespace", target_fixture="namespace2")
+def a_second_namespace(namespace_factory):
+    return namespace_factory()
+
+
+@given("a third Namespace", target_fixture="namespace3")
+def a_third_namespace(namespace_factory):
+    return namespace_factory()
+
+
+@then("we cannot create a relationships loop with these namespaces")
+def namespace_relationships_cannot_create_a_loop(namespace, namespace2, namespace3):
+    namespace2.namespace = namespace3
+    namespace3.validate()
+    namespace2.validate()
+    namespace.validate()
+    namespace.namespace = namespace2
+    namespace3.validate()
+    namespace2.validate()
+    namespace.validate()
+    namespace3.namespace = namespace
+    with pytest.raises(ValueError):
+        namespace3.validate()
+    with pytest.raises(ValueError):
+        namespace2.validate()
+    with pytest.raises(ValueError):
+        namespace.validate()
+    namespace3.namespace = None
+    namespace3.validate()
+    namespace2.validate()
+    namespace.validate()

fix(bdd): Rename “can/cannot be none” describing scenarios

Commit
Hash

cf1ea754ee276b16ddce53692a59174b2b583369

Date

2020-09-26 17:13:51 +0200

Type

Modified

Stats

+4 -4

@@ -78,11 +78,11 @@ def namespace_field_is_of_a_certain_type(
     check_field_value(namespace_factory, field_name, value, exception)


-@then(parsers.parse("its {field_name:w} cannot be none"))
-def namespace_field_cannot_be_none(namespace_factory, field_name):
+@then(parsers.parse("its {field_name:w} is mandatory"))
+def namespace_field_is_mandatory(namespace_factory, field_name):
     check_field_not_nullable(namespace_factory, field_name)


-@then(parsers.parse("its {field_name:w} can be none"))
-def namespace_field_can_be_none(namespace_factory, field_name):
+@then(parsers.parse("its {field_name:w} is optional"))
+def namespace_field_is_optional(namespace_factory, field_name):
     check_field_nullable(namespace_factory, field_name)

chore: Fix breaking changes from updated dependencies

Commit
Hash

7c6dfe01ac4ffbaac21d5d3836d5fda9c8391cf7

Date

2020-09-25 22:54:00 +0200

Type

Modified

Stats

+2 -2

@@ -56,8 +56,8 @@ def test_namespace_description_is_a_string(value, exception):
 scenarios("../features/describe.feature")


-@given("a Namespace")
-def namespace(namespace_factory):
+@given("a Namespace", target_fixture="namespace")
+def a_namespace(namespace_factory):
     return namespace_factory()

refactor(core): Rename core domain context to code_repository

Commit
Hash

07e279b370c0924f2b2cf32aea016b307001dfa0

Date

2019-08-15 23:31:33 +0200

Type

Renamed

Old path

isshub/domain/contexts/core/entities/namespace/tests/test_describe.py

Stats

+2 -2

@@ -1,10 +1,10 @@
-"""Module holding BDD tests for isshub Namespace core entity."""
+"""Module holding BDD tests for isshub Namespace code_repository entity."""

 import pytest
 from pytest import mark
 from pytest_bdd import given, parsers, scenario, scenarios, then

-from isshub.domain.contexts.core.entities.namespace import NamespaceKind
+from isshub.domain.contexts.code_repository.entities.namespace import NamespaceKind
 from isshub.domain.utils.testing.validation import (
     check_field,
     check_field_not_nullable,