Beispiel #1
0
 def unnamed_subcollections(self):
     subcoll = Collection()
     named_subcoll = Collection("hello")
     # We're binding to name 'subcoll', but subcoll itself has no .name
     # attribute/value, which is what's being tested. When bug present,
     # that fact will cause serialized() to die on sorted() when
     # comparing to named_subcoll (which has a string name).
     root = Collection(named_subcoll, subcoll=subcoll)
     expected = dict(
         name=None,
         default=None,
         help=None,
         tasks=[],
         collections=[
             # Expect anonymous first since we sort them as if their
             # name was the empty string.
             dict(
                 tasks=[],
                 collections=[],
                 name=None,
                 default=None,
                 help=None,
             ),
             dict(
                 tasks=[],
                 collections=[],
                 name="hello",
                 default=None,
                 help=None,
             ),
         ],
     )
     assert expected == root.serialized()
Beispiel #2
0
 def subcollection_paths_may_be_dotted(self):
     leaf = Collection("leaf", self.task)
     leaf.configure({"key": "leaf-value"})
     middle = Collection("middle", leaf)
     root = Collection("root", middle)
     config = root.configuration("middle.leaf.task")
     assert config == {"key": "leaf-value"}
Beispiel #3
0
 def raises_ValueError_if_collection_without_name(self):
     # Aka non-root collections must either have an explicit name given
     # via kwarg, have a name attribute set, or be a module with
     # __name__ defined.
     root = Collection()
     sub = Collection()
     with raises(ValueError):
         root.add_collection(sub)
Beispiel #4
0
            def percolates_to_subcollection_names(self):
                @task
                def my_task(c):
                    pass

                coll = Collection(inner_coll=Collection(my_task))
                contexts = coll.to_contexts()
                assert contexts[0].name == "inner_coll.my_task"
Beispiel #5
0
 def sibling_subcollections_ignored(self):
     inner = Collection("inner", self.task)
     inner.configure({"foo": "hi there"})
     inner2 = Collection("inner2", Task(_func, name="task2"))
     inner2.configure({"foo": "nope"})
     root = Collection(inner, inner2)
     assert root.configuration("inner.task")["foo"] == "hi there"
     assert root.configuration("inner2.task2")["foo"] == "nope"
Beispiel #6
0
 def invalid_subcollection_paths_result_in_KeyError(self):
     # Straight up invalid
     with raises(KeyError):
         Collection("meh").configuration("nope.task")
     # Exists but wrong level (should be 'root.task', not just
     # 'task')
     inner = Collection("inner", self.task)
     with raises(KeyError):
         Collection("root", inner).configuration("task")
Beispiel #7
0
        def kwargs_act_as_name_args_for_given_objects(self):
            sub = Collection()

            @task
            def task1(c):
                pass

            ns = Collection(loltask=task1, notsub=sub)
            assert ns["loltask"] == task1
            assert ns.collections["notsub"] == sub
Beispiel #8
0
 def returns_unique_Collection_objects_for_same_input_module(self):
     # Ignoring self.c for now, just in case it changes later.
     # First, a module with no root NS
     mod = load("integration")
     c1 = Collection.from_module(mod)
     c2 = Collection.from_module(mod)
     assert c1 is not c2
     # Now one *with* a root NS (which was previously buggy)
     mod2 = load("explicit_root")
     c3 = Collection.from_module(mod2)
     c4 = Collection.from_module(mod2)
     assert c3 is not c4
Beispiel #9
0
 def keys_dont_have_to_exist_in_full_path(self):
     # Kinda duplicates earlier stuff; meh
     # Key only stored on leaf
     leaf = Collection("leaf", self.task)
     leaf.configure({"key": "leaf-value"})
     middle = Collection("middle", leaf)
     root = Collection("root", middle)
     config = root.configuration("middle.leaf.task")
     assert config == {"key": "leaf-value"}
     # Key stored on mid + leaf but not root
     middle.configure({"key": "whoa"})
     assert root.configuration("middle.leaf.task") == {"key": "whoa"}
Beispiel #10
0
            def leading_and_trailing_underscores_are_not_affected(self):
                @task
                def _what_evers_(c):
                    pass

                @task
                def _inner_cooler_(c):
                    pass

                inner = Collection("inner", _inner_cooler_)
                contexts = Collection(_what_evers_, inner).to_contexts()
                expected = {"_what_evers_", "inner._inner_cooler_"}
                assert {x.name for x in contexts} == expected
Beispiel #11
0
            def percolates_to_subcollection_tasks(self):
                @task
                def outer_task(c):
                    pass

                @task
                def inner_task(c):
                    pass

                coll = Collection(outer_task, inner=Collection(inner_task))
                contexts = coll.to_contexts()
                expected = {"outer_task", "inner.inner_task"}
                assert {x.name for x in contexts} == expected
Beispiel #12
0
        def _meh(self):
            @task
            def task1(c):
                pass

            @task
            def task2(c):
                pass

            @task
            def task3(c):
                pass

            submeh = Collection("submeh", task3)
            return Collection("meh", task1, task2, submeh)
Beispiel #13
0
        def name_docstring_default_and_tasks(self):
            expected = dict(
                name="deploy",
                help="How to deploy our code and configs.",
                tasks=[
                    dict(
                        name="db",
                        help="Deploy to our database servers.",
                        aliases=["db_servers"],
                    ),
                    dict(
                        name="everywhere",
                        help="Deploy to all targets.",
                        aliases=[],
                    ),
                    dict(
                        name="web",
                        help="Update and bounce the webservers.",
                        aliases=[],
                    ),
                ],
                default="everywhere",
                collections=[],
            )
            with support_path():
                from tree import deploy

                coll = Collection.from_module(deploy)
            assert expected == coll.serialized()
Beispiel #14
0
            def _nested_underscores(self, auto_dash_names=None):
                @task(aliases=["other_name"])
                def my_task(c):
                    pass

                @task(aliases=["other_inner"])
                def inner_task(c):
                    pass

                # NOTE: explicitly not giving kwarg to subcollection; this
                # tests that the top_level namespace performs the inverse
                # transformation when necessary.
                sub = Collection("inner_coll", inner_task)
                return Collection(my_task,
                                  sub,
                                  auto_dash_names=auto_dash_names)
Beispiel #15
0
 def empty_named_collection(self):
     expected = dict(name="foo",
                     help=None,
                     tasks=[],
                     default=None,
                     collections=[])
     assert expected == Collection("foo").serialized()
Beispiel #16
0
            def aliases_are_dashed_too(self):
                @task(aliases=["hi_im_underscored"])
                def whatever(c):
                    pass

                contexts = Collection(whatever).to_contexts()
                assert "hi_im_underscored" in contexts[0].aliases
Beispiel #17
0
            def context_names_automatically_become_dashed(self):
                @task
                def my_task(c):
                    pass

                contexts = Collection(my_task).to_contexts()
                assert contexts[0].name == "my_task"
Beispiel #18
0
 def honors_subcollection_default_tasks_on_subcollection_name(self):
     sub = Collection.from_module(load("decorators"))
     self.c.add_collection(sub)
     # Sanity
     assert self.c["decorators.biz"] is sub["biz"]
     # Real test
     assert self.c["decorators"] is self.c["decorators.biz"]
Beispiel #19
0
 def submodule_names_are_stripped_to_last_chunk(self):
     with support_path():
         from package import module
     c = Collection.from_module(module)
     assert module.__name__ == "package.module"
     assert c.name == "module"
     assert "mytask" in c  # Sanity
Beispiel #20
0
        def name_docstring_default_tasks_and_collections(self):
            docs = dict(
                name="docs",
                help="Tasks for managing Sphinx docs.",
                tasks=[
                    dict(name="all", help="Build all doc formats.",
                         aliases=[]),
                    dict(name="html",
                         help="Build HTML output only.",
                         aliases=[]),
                    dict(name="pdf", help="Build PDF output only.",
                         aliases=[]),
                ],
                default="all",
                collections=[],
            )
            python = dict(
                name="python",
                help="PyPI/etc distribution artifacts.",
                tasks=[
                    dict(
                        name="all",
                        help="Build all Python packages.",
                        aliases=[],
                    ),
                    dict(
                        name="sdist",
                        help="Build classic style tar.gz.",
                        aliases=[],
                    ),
                    dict(name="wheel", help="Build a wheel.", aliases=[]),
                ],
                default="all",
                collections=[],
            )
            expected = dict(
                name="build",
                help="Tasks for compiling static code and assets.",
                tasks=[
                    dict(
                        name="all",
                        help="Build all necessary artifacts.",
                        aliases=["everything"],
                    ),
                    dict(
                        name="c_ext",
                        help="Build our internal C extension.",
                        aliases=["ext"],
                    ),
                    dict(name="zap", help="A silly way to clean.", aliases=[]),
                ],
                default="all",
                collections=[docs, python],
            )
            with support_path():
                from tree import build

                coll = Collection.from_module(build)
            assert expected == coll.serialized()
Beispiel #21
0
 def invalid_path(self):
     # This is really just testing Lexicon/dict behavior but w/e, good
     # to be explicit, esp if we ever want this to become Exit or
     # another custom exception. (For now most/all callers manually
     # catch KeyError and raise Exit just to keep most Exit use high up
     # in the stack...)
     with raises(KeyError):
         collection = Collection.from_module(load("tree"))
         collection.subcollection_from_path("lol.whatever.man")
Beispiel #22
0
 def parents_overwrite_children_in_path(self):
     inner = Collection("inner", self.task)
     inner.configure({"foo": "inner"})
     self.root.add_collection(inner)
     # Before updating root collection's config, reflects inner
     assert self.root.configuration("inner.task")["foo"] == "inner"
     self.root.configure({"foo": "outer"})
     # After, reflects outer (since that now overrides)
     assert self.root.configuration("inner.task")["foo"] == "outer"
Beispiel #23
0
        def initial_string_arg_meshes_with_varargs_and_kwargs(self):
            @task
            def task1(c):
                pass

            @task
            def task2(c):
                pass

            sub = Collection("sub")
            ns = Collection("root", task1, sub, sometask=task2)
            for x, y in (
                (ns.name, "root"),
                (ns["task1"], task1),
                (ns.collections["sub"], sub),
                (ns["sometask"], task2),
            ):
                assert x == y
Beispiel #24
0
        def positional_arglist_preserves_order_given(self):
            @task(positional=("second", "first"))
            def mytask(c, first, second, third):
                pass

            coll = Collection()
            coll.add_task(mytask)
            c = coll.to_contexts()[0]
            expected = [c.args["second"], c.args["first"]]
            assert c.positional_args == expected
Beispiel #25
0
 def access_merges_from_subcollections(self):
     inner = Collection("inner", self.task)
     inner.configure({"foo": "bar"})
     self.root.configure({"biz": "baz"})
     # With no inner collection
     assert set(self.root.configuration().keys()) == {"biz"}
     # With inner collection
     self.root.add_collection(inner)
     keys = set(self.root.configuration("inner.task").keys())
     assert keys == {"foo", "biz"}
Beispiel #26
0
        def returns_list_of_help_tuples(self):
            # Walks own list of flags/args, ensures resulting map to help_for()
            # TODO: consider redoing help_for to be more flexible on input --
            # arg value or flag; or even Argument objects. ?
            @task(help={"otherarg": "other help"})
            def mytask(c, myarg, otherarg):
                pass

            c = Collection(mytask).to_contexts()[0]
            expected = [c.help_for("--myarg"), c.help_for("--otherarg")]
            assert c.help_tuples() == expected
Beispiel #27
0
        def setup(self):
            @task
            def mytask(c, text, boolean=False, number=5):
                print(text)

            @task(aliases=["mytask27"])
            def mytask2(c):
                pass

            @task(aliases=["othertask"], default=True)
            def subtask(c):
                pass

            sub = Collection("sub", subtask)
            self.c = Collection(mytask, mytask2, sub)
            self.contexts = self.c.to_contexts()
            alias_tups = [list(x.aliases) for x in self.contexts]
            self.aliases = reduce(operator.add, alias_tups, [])
            # Focus on 'mytask' as it has the more interesting sig
            self.context = [x for x in self.contexts if x.name == "mytask"][0]
Beispiel #28
0
 def empty_named_docstringed_collection(self):
     expected = dict(
         name="foo",
         help="Hi doc",
         tasks=[],
         default=None,
         collections=[],
     )
     coll = Collection("foo")
     coll.__doc__ = "Hi doc"
     assert expected == coll.serialized()
Beispiel #29
0
 def setup(self):
     mod = load("explicit_root")
     mod.ns.configure({
         "key": "builtin",
         "otherkey": "yup",
         "subconfig": {
             "mykey": "myvalue"
         },
     })
     mod.ns.name = "builtin_name"
     self.unchanged = Collection.from_module(mod)
     self.changed = Collection.from_module(
         mod,
         name="override_name",
         config={
             "key": "override",
             "subconfig": {
                 "myotherkey": "myothervalue"
             },
         },
     )
Beispiel #30
0
        def setup(self):
            # Normal, non-task/collection related Context
            self.vanilla = Context(
                args=(Argument("foo"), Argument("bar", help="bar the baz"))
            )
            # Task/Collection generated Context
            # (will expose flags n such)
            @task(help={"otherarg": "other help"}, optional=["optval"])
            def mytask(c, myarg, otherarg, optval, intval=5):
                pass

            col = Collection(mytask)
            self.tasked = col.to_contexts()[0]