diff --git a/packages/polywrap-client-config-builder/poetry.lock b/packages/polywrap-client-config-builder/poetry.lock index 5c7e1f06..4446378c 100644 --- a/packages/polywrap-client-config-builder/poetry.lock +++ b/packages/polywrap-client-config-builder/poetry.lock @@ -1,15 +1,15 @@ -# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. +# This file is automatically @generated by Poetry and should not be changed by hand. [[package]] name = "astroid" -version = "2.15.4" +version = "2.15.5" description = "An abstract syntax tree for Python with inference support." category = "dev" optional = false python-versions = ">=3.7.2" files = [ - {file = "astroid-2.15.4-py3-none-any.whl", hash = "sha256:a1b8543ef9d36ea777194bc9b17f5f8678d2c56ee6a45b2c2f17eec96f242347"}, - {file = "astroid-2.15.4.tar.gz", hash = "sha256:c81e1c7fbac615037744d067a9bb5f9aeb655edf59b63ee8b59585475d6f80d8"}, + {file = "astroid-2.15.5-py3-none-any.whl", hash = "sha256:078e5212f9885fa85fbb0cf0101978a336190aadea6e13305409d099f71b2324"}, + {file = "astroid-2.15.5.tar.gz", hash = "sha256:1039262575027b441137ab4a62a793a9b43defb42c32d5670f38686207cd780f"}, ] [package.dependencies] @@ -20,6 +20,25 @@ wrapt = [ {version = ">=1.14,<2", markers = "python_version >= \"3.11\""}, ] +[[package]] +name = "attrs" +version = "23.1.0" +description = "Classes Without Boilerplate" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, + {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, +] + +[package.extras] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[docs,tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] + [[package]] name = "bandit" version = "1.7.5" @@ -195,6 +214,39 @@ files = [ [package.dependencies] gitdb = ">=4.0.1,<5" +[[package]] +name = "hypothesis" +version = "6.76.0" +description = "A library for property-based testing" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "hypothesis-6.76.0-py3-none-any.whl", hash = "sha256:034f73dd485933b0f4c319d7c3c58230492fdd7b16e821d67d150a78138adb93"}, + {file = "hypothesis-6.76.0.tar.gz", hash = "sha256:526657eb3e4f2076b0383f722b2e6a92fd15d1d42db532decae8c41b14cab801"}, +] + +[package.dependencies] +attrs = ">=19.2.0" +exceptiongroup = {version = ">=1.0.0", markers = "python_version < \"3.11\""} +sortedcontainers = ">=2.1.0,<3.0.0" + +[package.extras] +all = ["backports.zoneinfo (>=0.2.1)", "black (>=19.10b0)", "click (>=7.0)", "django (>=3.2)", "dpcontracts (>=0.4)", "importlib-metadata (>=3.6)", "lark (>=0.10.1)", "libcst (>=0.3.16)", "numpy (>=1.16.0)", "pandas (>=1.1)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "tzdata (>=2023.3)"] +cli = ["black (>=19.10b0)", "click (>=7.0)", "rich (>=9.0.0)"] +codemods = ["libcst (>=0.3.16)"] +dateutil = ["python-dateutil (>=1.4)"] +django = ["django (>=3.2)"] +dpcontracts = ["dpcontracts (>=0.4)"] +ghostwriter = ["black (>=19.10b0)"] +lark = ["lark (>=0.10.1)"] +numpy = ["numpy (>=1.16.0)"] +pandas = ["pandas (>=1.1)"] +pytest = ["pytest (>=4.6)"] +pytz = ["pytz (>=2014.1)"] +redis = ["redis (>=3.0.0)"] +zoneinfo = ["backports.zoneinfo (>=0.2.1)", "tzdata (>=2023.3)"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -407,14 +459,14 @@ files = [ [[package]] name = "nodeenv" -version = "1.7.0" +version = "1.8.0" description = "Node.js virtual environment builder" category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" files = [ - {file = "nodeenv-1.7.0-py2.py3-none-any.whl", hash = "sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e"}, - {file = "nodeenv-1.7.0.tar.gz", hash = "sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b"}, + {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"}, + {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"}, ] [package.dependencies] @@ -458,18 +510,18 @@ files = [ [[package]] name = "platformdirs" -version = "3.5.0" +version = "3.5.1" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-3.5.0-py3-none-any.whl", hash = "sha256:47692bc24c1958e8b0f13dd727307cff1db103fca36399f457da8e05f222fdc4"}, - {file = "platformdirs-3.5.0.tar.gz", hash = "sha256:7954a68d0ba23558d753f73437c55f89027cf8f5108c19844d4b82e5af396335"}, + {file = "platformdirs-3.5.1-py3-none-any.whl", hash = "sha256:e2378146f1964972c03c085bb5662ae80b2b8c06226c54b2ff4aa9483e8a13a5"}, + {file = "platformdirs-3.5.1.tar.gz", hash = "sha256:412dae91f52a6f84830f39a8078cecd0e866cb72294a5c66808e74d5e88d251f"}, ] [package.extras] -docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] +docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.2.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] [[package]] @@ -595,48 +647,48 @@ files = [ [[package]] name = "pydantic" -version = "1.10.7" +version = "1.10.8" description = "Data validation and settings management using python type hints" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e79e999e539872e903767c417c897e729e015872040e56b96e67968c3b918b2d"}, - {file = "pydantic-1.10.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:01aea3a42c13f2602b7ecbbea484a98169fb568ebd9e247593ea05f01b884b2e"}, - {file = "pydantic-1.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:516f1ed9bc2406a0467dd777afc636c7091d71f214d5e413d64fef45174cfc7a"}, - {file = "pydantic-1.10.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae150a63564929c675d7f2303008d88426a0add46efd76c3fc797cd71cb1b46f"}, - {file = "pydantic-1.10.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ecbbc51391248116c0a055899e6c3e7ffbb11fb5e2a4cd6f2d0b93272118a209"}, - {file = "pydantic-1.10.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f4a2b50e2b03d5776e7f21af73e2070e1b5c0d0df255a827e7c632962f8315af"}, - {file = "pydantic-1.10.7-cp310-cp310-win_amd64.whl", hash = "sha256:a7cd2251439988b413cb0a985c4ed82b6c6aac382dbaff53ae03c4b23a70e80a"}, - {file = "pydantic-1.10.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:68792151e174a4aa9e9fc1b4e653e65a354a2fa0fed169f7b3d09902ad2cb6f1"}, - {file = "pydantic-1.10.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe2507b8ef209da71b6fb5f4e597b50c5a34b78d7e857c4f8f3115effaef5fe"}, - {file = "pydantic-1.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10a86d8c8db68086f1e30a530f7d5f83eb0685e632e411dbbcf2d5c0150e8dcd"}, - {file = "pydantic-1.10.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d75ae19d2a3dbb146b6f324031c24f8a3f52ff5d6a9f22f0683694b3afcb16fb"}, - {file = "pydantic-1.10.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:464855a7ff7f2cc2cf537ecc421291b9132aa9c79aef44e917ad711b4a93163b"}, - {file = "pydantic-1.10.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:193924c563fae6ddcb71d3f06fa153866423ac1b793a47936656e806b64e24ca"}, - {file = "pydantic-1.10.7-cp311-cp311-win_amd64.whl", hash = "sha256:b4a849d10f211389502059c33332e91327bc154acc1845f375a99eca3afa802d"}, - {file = "pydantic-1.10.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cc1dde4e50a5fc1336ee0581c1612215bc64ed6d28d2c7c6f25d2fe3e7c3e918"}, - {file = "pydantic-1.10.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0cfe895a504c060e5d36b287ee696e2fdad02d89e0d895f83037245218a87fe"}, - {file = "pydantic-1.10.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:670bb4683ad1e48b0ecb06f0cfe2178dcf74ff27921cdf1606e527d2617a81ee"}, - {file = "pydantic-1.10.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:950ce33857841f9a337ce07ddf46bc84e1c4946d2a3bba18f8280297157a3fd1"}, - {file = "pydantic-1.10.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c15582f9055fbc1bfe50266a19771bbbef33dd28c45e78afbe1996fd70966c2a"}, - {file = "pydantic-1.10.7-cp37-cp37m-win_amd64.whl", hash = "sha256:82dffb306dd20bd5268fd6379bc4bfe75242a9c2b79fec58e1041fbbdb1f7914"}, - {file = "pydantic-1.10.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c7f51861d73e8b9ddcb9916ae7ac39fb52761d9ea0df41128e81e2ba42886cd"}, - {file = "pydantic-1.10.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6434b49c0b03a51021ade5c4daa7d70c98f7a79e95b551201fff682fc1661245"}, - {file = "pydantic-1.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64d34ab766fa056df49013bb6e79921a0265204c071984e75a09cbceacbbdd5d"}, - {file = "pydantic-1.10.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:701daea9ffe9d26f97b52f1d157e0d4121644f0fcf80b443248434958fd03dc3"}, - {file = "pydantic-1.10.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf135c46099ff3f919d2150a948ce94b9ce545598ef2c6c7bf55dca98a304b52"}, - {file = "pydantic-1.10.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b0f85904f73161817b80781cc150f8b906d521fa11e3cdabae19a581c3606209"}, - {file = "pydantic-1.10.7-cp38-cp38-win_amd64.whl", hash = "sha256:9f6f0fd68d73257ad6685419478c5aece46432f4bdd8d32c7345f1986496171e"}, - {file = "pydantic-1.10.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c230c0d8a322276d6e7b88c3f7ce885f9ed16e0910354510e0bae84d54991143"}, - {file = "pydantic-1.10.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:976cae77ba6a49d80f461fd8bba183ff7ba79f44aa5cfa82f1346b5626542f8e"}, - {file = "pydantic-1.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d45fc99d64af9aaf7e308054a0067fdcd87ffe974f2442312372dfa66e1001d"}, - {file = "pydantic-1.10.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d2a5ebb48958754d386195fe9e9c5106f11275867051bf017a8059410e9abf1f"}, - {file = "pydantic-1.10.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:abfb7d4a7cd5cc4e1d1887c43503a7c5dd608eadf8bc615413fc498d3e4645cd"}, - {file = "pydantic-1.10.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:80b1fab4deb08a8292d15e43a6edccdffa5377a36a4597bb545b93e79c5ff0a5"}, - {file = "pydantic-1.10.7-cp39-cp39-win_amd64.whl", hash = "sha256:d71e69699498b020ea198468e2480a2f1e7433e32a3a99760058c6520e2bea7e"}, - {file = "pydantic-1.10.7-py3-none-any.whl", hash = "sha256:0cd181f1d0b1d00e2b705f1bf1ac7799a2d938cce3376b8007df62b29be3c2c6"}, - {file = "pydantic-1.10.7.tar.gz", hash = "sha256:cfc83c0678b6ba51b0532bea66860617c4cd4251ecf76e9846fa5a9f3454e97e"}, + {file = "pydantic-1.10.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1243d28e9b05003a89d72e7915fdb26ffd1d39bdd39b00b7dbe4afae4b557f9d"}, + {file = "pydantic-1.10.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c0ab53b609c11dfc0c060d94335993cc2b95b2150e25583bec37a49b2d6c6c3f"}, + {file = "pydantic-1.10.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9613fadad06b4f3bc5db2653ce2f22e0de84a7c6c293909b48f6ed37b83c61f"}, + {file = "pydantic-1.10.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df7800cb1984d8f6e249351139667a8c50a379009271ee6236138a22a0c0f319"}, + {file = "pydantic-1.10.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0c6fafa0965b539d7aab0a673a046466d23b86e4b0e8019d25fd53f4df62c277"}, + {file = "pydantic-1.10.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e82d4566fcd527eae8b244fa952d99f2ca3172b7e97add0b43e2d97ee77f81ab"}, + {file = "pydantic-1.10.8-cp310-cp310-win_amd64.whl", hash = "sha256:ab523c31e22943713d80d8d342d23b6f6ac4b792a1e54064a8d0cf78fd64e800"}, + {file = "pydantic-1.10.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:666bdf6066bf6dbc107b30d034615d2627e2121506c555f73f90b54a463d1f33"}, + {file = "pydantic-1.10.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:35db5301b82e8661fa9c505c800d0990bc14e9f36f98932bb1d248c0ac5cada5"}, + {file = "pydantic-1.10.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f90c1e29f447557e9e26afb1c4dbf8768a10cc676e3781b6a577841ade126b85"}, + {file = "pydantic-1.10.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93e766b4a8226e0708ef243e843105bf124e21331694367f95f4e3b4a92bbb3f"}, + {file = "pydantic-1.10.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:88f195f582851e8db960b4a94c3e3ad25692c1c1539e2552f3df7a9e972ef60e"}, + {file = "pydantic-1.10.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:34d327c81e68a1ecb52fe9c8d50c8a9b3e90d3c8ad991bfc8f953fb477d42fb4"}, + {file = "pydantic-1.10.8-cp311-cp311-win_amd64.whl", hash = "sha256:d532bf00f381bd6bc62cabc7d1372096b75a33bc197a312b03f5838b4fb84edd"}, + {file = "pydantic-1.10.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7d5b8641c24886d764a74ec541d2fc2c7fb19f6da2a4001e6d580ba4a38f7878"}, + {file = "pydantic-1.10.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b1f6cb446470b7ddf86c2e57cd119a24959af2b01e552f60705910663af09a4"}, + {file = "pydantic-1.10.8-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c33b60054b2136aef8cf190cd4c52a3daa20b2263917c49adad20eaf381e823b"}, + {file = "pydantic-1.10.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1952526ba40b220b912cdc43c1c32bcf4a58e3f192fa313ee665916b26befb68"}, + {file = "pydantic-1.10.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bb14388ec45a7a0dc429e87def6396f9e73c8c77818c927b6a60706603d5f2ea"}, + {file = "pydantic-1.10.8-cp37-cp37m-win_amd64.whl", hash = "sha256:16f8c3e33af1e9bb16c7a91fc7d5fa9fe27298e9f299cff6cb744d89d573d62c"}, + {file = "pydantic-1.10.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1ced8375969673929809d7f36ad322934c35de4af3b5e5b09ec967c21f9f7887"}, + {file = "pydantic-1.10.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:93e6bcfccbd831894a6a434b0aeb1947f9e70b7468f274154d03d71fabb1d7c6"}, + {file = "pydantic-1.10.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:191ba419b605f897ede9892f6c56fb182f40a15d309ef0142212200a10af4c18"}, + {file = "pydantic-1.10.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:052d8654cb65174d6f9490cc9b9a200083a82cf5c3c5d3985db765757eb3b375"}, + {file = "pydantic-1.10.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ceb6a23bf1ba4b837d0cfe378329ad3f351b5897c8d4914ce95b85fba96da5a1"}, + {file = "pydantic-1.10.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f2e754d5566f050954727c77f094e01793bcb5725b663bf628fa6743a5a9108"}, + {file = "pydantic-1.10.8-cp38-cp38-win_amd64.whl", hash = "sha256:6a82d6cda82258efca32b40040228ecf43a548671cb174a1e81477195ed3ed56"}, + {file = "pydantic-1.10.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e59417ba8a17265e632af99cc5f35ec309de5980c440c255ab1ca3ae96a3e0e"}, + {file = "pydantic-1.10.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:84d80219c3f8d4cad44575e18404099c76851bc924ce5ab1c4c8bb5e2a2227d0"}, + {file = "pydantic-1.10.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e4148e635994d57d834be1182a44bdb07dd867fa3c2d1b37002000646cc5459"}, + {file = "pydantic-1.10.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12f7b0bf8553e310e530e9f3a2f5734c68699f42218bf3568ef49cd9b0e44df4"}, + {file = "pydantic-1.10.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:42aa0c4b5c3025483240a25b09f3c09a189481ddda2ea3a831a9d25f444e03c1"}, + {file = "pydantic-1.10.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:17aef11cc1b997f9d574b91909fed40761e13fac438d72b81f902226a69dac01"}, + {file = "pydantic-1.10.8-cp39-cp39-win_amd64.whl", hash = "sha256:66a703d1983c675a6e0fed8953b0971c44dba48a929a2000a493c3772eb61a5a"}, + {file = "pydantic-1.10.8-py3-none-any.whl", hash = "sha256:7456eb22ed9aaa24ff3e7b4757da20d9e5ce2a81018c1b3ebd81a0b88a18f3b2"}, + {file = "pydantic-1.10.8.tar.gz", hash = "sha256:1410275520dfa70effadf4c21811d755e7ef9bb1f1d077a21958153a92c8d9ca"}, ] [package.dependencies] @@ -710,14 +762,14 @@ testutils = ["gitpython (>3)"] [[package]] name = "pyright" -version = "1.1.306" +version = "1.1.311" description = "Command line wrapper for pyright" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pyright-1.1.306-py3-none-any.whl", hash = "sha256:008eb2a29584ae274a154d749cf81476a3073fb562a462eac8d43a753378b9db"}, - {file = "pyright-1.1.306.tar.gz", hash = "sha256:16d5d198be64de497d5f9002000a271176c381e21b977ca5566cf779b643c9ed"}, + {file = "pyright-1.1.311-py3-none-any.whl", hash = "sha256:04df30c6b31d05068effe5563411291c876f5e4221d0af225a267b61dce1ca85"}, + {file = "pyright-1.1.311.tar.gz", hash = "sha256:554b555d3f770e8da2e76d6bb94e2ac63b3edc7dcd5fb8de202f9dd53e36689a"}, ] [package.dependencies] @@ -820,14 +872,14 @@ files = [ [[package]] name = "rich" -version = "13.3.5" +version = "13.4.1" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" category = "dev" optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.3.5-py3-none-any.whl", hash = "sha256:69cdf53799e63f38b95b9bf9c875f8c90e78dd62b2f00c13a911c7a3b9fa4704"}, - {file = "rich-13.3.5.tar.gz", hash = "sha256:2d11b9b8dd03868f09b4fffadc84a6a8cda574e40dc90821bd845720ebb8e89c"}, + {file = "rich-13.4.1-py3-none-any.whl", hash = "sha256:d204aadb50b936bf6b1a695385429d192bc1fdaf3e8b907e8e26f4c4e4b5bf75"}, + {file = "rich-13.4.1.tar.gz", hash = "sha256:76f6b65ea7e5c5d924ba80e322231d7cb5b5981aa60bfc1e694f1bc097fe6fe1"}, ] [package.dependencies] @@ -839,19 +891,19 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "setuptools" -version = "67.7.2" +version = "67.8.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "setuptools-67.7.2-py3-none-any.whl", hash = "sha256:23aaf86b85ca52ceb801d32703f12d77517b2556af839621c641fca11287952b"}, - {file = "setuptools-67.7.2.tar.gz", hash = "sha256:f104fa03692a2602fa0fec6c6a9e63b6c8a968de13e17c026957dd1f53d80990"}, + {file = "setuptools-67.8.0-py3-none-any.whl", hash = "sha256:5df61bf30bb10c6f756eb19e7c9f3b473051f48db77fddbe06ff2ca307df9a6f"}, + {file = "setuptools-67.8.0.tar.gz", hash = "sha256:62642358adc77ffa87233bc4d2354c4b2682d214048f500964dbe760ccedf102"}, ] [package.extras] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] @@ -890,16 +942,28 @@ files = [ {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] +[[package]] +name = "sortedcontainers" +version = "2.4.0" +description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, + {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, +] + [[package]] name = "stevedore" -version = "5.0.0" +version = "5.1.0" description = "Manage dynamic plugins for Python applications" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "stevedore-5.0.0-py3-none-any.whl", hash = "sha256:bd5a71ff5e5e5f5ea983880e4a1dd1bb47f8feebbb3d95b592398e2f02194771"}, - {file = "stevedore-5.0.0.tar.gz", hash = "sha256:2c428d2338976279e8eb2196f7a94910960d9f7ba2f41f3988511e95ca447021"}, + {file = "stevedore-5.1.0-py3-none-any.whl", hash = "sha256:8cc040628f3cea5d7128f2e76cf486b2251a4e543c7b938f58d9a377f6694a2d"}, + {file = "stevedore-5.1.0.tar.gz", hash = "sha256:a54534acf9b89bc7ed264807013b505bf07f74dbe4bcfa37d32bd063870b087c"}, ] [package.dependencies] @@ -989,14 +1053,14 @@ test = ["coverage", "pycodestyle", "pylint", "pytest"] [[package]] name = "typing-extensions" -version = "4.5.0" +version = "4.6.3" description = "Backported and Experimental Type Hints for Python 3.7+" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, - {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, + {file = "typing_extensions-4.6.3-py3-none-any.whl", hash = "sha256:88a4153d8505aabbb4e13aacb7c486c2b4a33ca3b3f807914a9b4c844c471c26"}, + {file = "typing_extensions-4.6.3.tar.gz", hash = "sha256:d91d5919357fe7f681a9f2b5b4cb2a5f1ef0a1e9f59c4d8ff0d3491e05c0ffd5"}, ] [[package]] @@ -1150,4 +1214,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "af1d9b727002057dee7ece1fa89fbeb5810309387c53f9fdc3ef38f778755dee" +content-hash = "4c83da528593354cc45f8379300b60bdd5322f1507ce0e1d8c4a8c3329e003c2" diff --git a/packages/polywrap-client-config-builder/polywrap_client_config_builder/configures/env_configure.py b/packages/polywrap-client-config-builder/polywrap_client_config_builder/configures/env_configure.py index 1a1d1297..6157c3c0 100644 --- a/packages/polywrap-client-config-builder/polywrap_client_config_builder/configures/env_configure.py +++ b/packages/polywrap-client-config-builder/polywrap_client_config_builder/configures/env_configure.py @@ -1,6 +1,6 @@ """This module contains the env configure class for the client config builder.""" from abc import ABC -from typing import Any, Dict, List, Union +from typing import Any, Dict, List, Union, cast from polywrap_core import Uri @@ -35,9 +35,9 @@ def add_env(self, uri: Uri, env: Any) -> ClientConfigBuilder: If an Any is already associated with the uri, it is modified. """ - if self.config.envs.get(uri): - for key in self.config.envs[uri]: - self.config.envs[uri][key] = env[key] + if old_env := self.config.envs.get(uri): + new_env = self._merge_envs(old_env, env) + self.config.envs[uri] = new_env else: self.config.envs[uri] = env return self @@ -58,3 +58,19 @@ def remove_envs(self, uris: List[Uri]) -> ClientConfigBuilder: for uri in uris: self.remove_env(uri) return self + + @staticmethod + def _merge_envs(env1: Dict[str, Any], env2: Dict[str, Any]) -> Dict[str, Any]: + for key, val in env2.items(): + if key not in env1: + env1[key] = val + continue + + if isinstance(val, dict): + old_val = cast(Dict[str, Any], env1[key]) + new_val = cast(Dict[str, Any], val) + + EnvConfigure._merge_envs(old_val, new_val) + else: + env1[key] = val + return env1 diff --git a/packages/polywrap-client-config-builder/polywrap_client_config_builder/configures/interface_configure.py b/packages/polywrap-client-config-builder/polywrap_client_config_builder/configures/interface_configure.py index 26fc60d3..7fb81ebb 100644 --- a/packages/polywrap-client-config-builder/polywrap_client_config_builder/configures/interface_configure.py +++ b/packages/polywrap-client-config-builder/polywrap_client_config_builder/configures/interface_configure.py @@ -26,7 +26,10 @@ def add_interface_implementations( ) -> ClientConfigBuilder: """Add a list of implementation URIs for the given interface URI to the builder's config.""" if interface_uri in self.config.interfaces.keys(): - self.config.interfaces[interface_uri].extend(implementations_uris) + existing_implementations = set(self.config.interfaces[interface_uri]) + for implementation_uri in implementations_uris: + if implementation_uri not in existing_implementations: + self.config.interfaces[interface_uri].append(implementation_uri) else: self.config.interfaces[interface_uri] = implementations_uris return self diff --git a/packages/polywrap-client-config-builder/polywrap_client_config_builder/polywrap_client_config_builder.py b/packages/polywrap-client-config-builder/polywrap_client_config_builder/polywrap_client_config_builder.py index 7fcdaca6..d392c0fc 100644 --- a/packages/polywrap-client-config-builder/polywrap_client_config_builder/polywrap_client_config_builder.py +++ b/packages/polywrap-client-config-builder/polywrap_client_config_builder/polywrap_client_config_builder.py @@ -54,13 +54,7 @@ def __init__(self): def build(self, options: Optional[BuildOptions] = None) -> ClientConfig: """Build the ClientConfig object from the builder's config.""" - static_resolver_like = cast(StaticResolverLike, self.config.redirects) - - for uri, wrapper in self.config.wrappers.items(): - static_resolver_like[uri] = UriWrapper(uri=uri, wrapper=wrapper) - - for uri, package in self.config.packages.items(): - static_resolver_like[uri] = UriPackage(uri=uri, package=package) + static_resolver_like = self._build_static_resolver_like() resolver = ( options.resolver @@ -87,5 +81,16 @@ def build(self, options: Optional[BuildOptions] = None) -> ClientConfig: resolver=resolver, ) + def _build_static_resolver_like(self) -> StaticResolverLike: + static_resolver_like = cast(StaticResolverLike, self.config.redirects) + + for uri, wrapper in self.config.wrappers.items(): + static_resolver_like[uri] = UriWrapper(uri=uri, wrapper=wrapper) + + for uri, package in self.config.packages.items(): + static_resolver_like[uri] = UriPackage(uri=uri, package=package) + + return static_resolver_like + __all__ = ["PolywrapClientConfigBuilder"] diff --git a/packages/polywrap-client-config-builder/polywrap_client_config_builder/types/builder_config.py b/packages/polywrap-client-config-builder/polywrap_client_config_builder/types/builder_config.py index 2e60f279..d94ac526 100644 --- a/packages/polywrap-client-config-builder/polywrap_client_config_builder/types/builder_config.py +++ b/packages/polywrap-client-config-builder/polywrap_client_config_builder/types/builder_config.py @@ -1,5 +1,5 @@ """This module contains the BuilderConfig class.""" -from dataclasses import dataclass +from dataclasses import dataclass, field from typing import Any, Dict, List from polywrap_core import Uri, UriResolver, WrapPackage, Wrapper @@ -18,12 +18,12 @@ class BuilderConfig: redirects (Dict[Uri, Uri]): The URI redirects. """ - envs: Dict[Uri, Any] - interfaces: Dict[Uri, List[Uri]] - wrappers: Dict[Uri, Wrapper] - packages: Dict[Uri, WrapPackage] - resolvers: List[UriResolver] - redirects: Dict[Uri, Uri] + envs: Dict[Uri, Any] = field(default_factory=dict) + interfaces: Dict[Uri, List[Uri]] = field(default_factory=dict) + wrappers: Dict[Uri, Wrapper] = field(default_factory=dict) + packages: Dict[Uri, WrapPackage] = field(default_factory=dict) + resolvers: List[UriResolver] = field(default_factory=list) + redirects: Dict[Uri, Uri] = field(default_factory=dict) __all__ = ["BuilderConfig"] diff --git a/packages/polywrap-client-config-builder/pyproject.toml b/packages/polywrap-client-config-builder/pyproject.toml index 26f33b82..59bbc3d0 100644 --- a/packages/polywrap-client-config-builder/pyproject.toml +++ b/packages/polywrap-client-config-builder/pyproject.toml @@ -25,6 +25,9 @@ isort = "^5.10.1" pyright = "^1.1.275" pydocstyle = "^6.1.1" +[tool.poetry.group.dev.dependencies] +hypothesis = "^6.76.0" + [tool.bandit] exclude_dirs = ["tests"] diff --git a/packages/polywrap-client-config-builder/tests/.gitignore b/packages/polywrap-client-config-builder/tests/.gitignore new file mode 100644 index 00000000..becd6eb0 --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/.gitignore @@ -0,0 +1 @@ +!env/ \ No newline at end of file diff --git a/packages/polywrap-client-config-builder/tests/__init__.py b/packages/polywrap-client-config-builder/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/packages/polywrap-client-config-builder/tests/consts.py b/packages/polywrap-client-config-builder/tests/consts.py new file mode 100644 index 00000000..24e79cc8 --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/consts.py @@ -0,0 +1,2 @@ +C_LONG_MIN = -9223372036854775808 +C_LONG_MAX = 9223372036854775807 diff --git a/packages/polywrap-client-config-builder/tests/env/__init__.py b/packages/polywrap-client-config-builder/tests/env/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/packages/polywrap-client-config-builder/tests/env/test_add_env.py b/packages/polywrap-client-config-builder/tests/env/test_add_env.py new file mode 100644 index 00000000..05b91dd1 --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/env/test_add_env.py @@ -0,0 +1,27 @@ +from typing import Any +from hypothesis import given, settings + +from polywrap_client_config_builder import ( + ClientConfigBuilder, + PolywrapClientConfigBuilder, +) +from polywrap_core import Uri + +from ..strategies import uri_strategy, env_strategy + + +@settings(max_examples=100) +@given(uri=uri_strategy, old_env=env_strategy, new_env=env_strategy) +def test_add_env(uri: Uri, old_env: Any, new_env: Any): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.envs = {uri: {"common": old_env, "unique_1": "unique_env_1"}} + + builder.add_env(uri, {"common": new_env, "unique_2": "unique_env_2"}) + + updated_env = {**old_env, **new_env} + + assert builder.config.envs[uri] == { + "common": updated_env, + "unique_1": "unique_env_1", + "unique_2": "unique_env_2", + } diff --git a/packages/polywrap-client-config-builder/tests/env/test_get_env.py b/packages/polywrap-client-config-builder/tests/env/test_get_env.py new file mode 100644 index 00000000..ffd0f8ad --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/env/test_get_env.py @@ -0,0 +1,40 @@ +from typing import Any, Dict +from hypothesis import given, settings + +from polywrap_client_config_builder import ( + ClientConfigBuilder, + PolywrapClientConfigBuilder, +) +from polywrap_core import Uri + +from ..strategies import envs_strategy + + +@settings(max_examples=100) +@given(envs=envs_strategy) +def test_get_env_exists( + envs: Dict[Uri, Any] +): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.envs = envs + + for uri in envs: + assert builder.get_env(uri) == envs[uri] + assert builder.get_env(Uri.from_str("test/not-exists")) is None + + +def test_get_env_not_exists(): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + assert builder.get_env(Uri.from_str("test/not-exists")) is None + + +@settings(max_examples=100) +@given(envs=envs_strategy) +def test_get_envs( + envs: Dict[Uri, Any] +): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + assert builder.get_envs() == {} + + builder.config.envs = envs + assert builder.get_envs() == envs diff --git a/packages/polywrap-client-config-builder/tests/env/test_remove_env.py b/packages/polywrap-client-config-builder/tests/env/test_remove_env.py new file mode 100644 index 00000000..75d074e3 --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/env/test_remove_env.py @@ -0,0 +1,59 @@ +from typing import Any, Dict +from random import randint +from hypothesis import assume, event, given, settings + +from polywrap_client_config_builder import ( + ClientConfigBuilder, + PolywrapClientConfigBuilder, +) +from polywrap_core import Uri + +from ..strategies import envs_strategy + + +@settings(max_examples=100) +@given(envs=envs_strategy) +def test_remove_env(envs: Dict[Uri, Any]): + assume(envs) + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.envs = {**envs} + + uris = list(envs.keys()) + uri_index = randint(0, len(uris) - 1) + remove_uri = uris[uri_index] + event(f"Uri to remove: {remove_uri}") + + builder.remove_env(remove_uri) + assert len(builder.config.envs) == len(envs) - 1 + assert remove_uri not in builder.config.envs + + +@settings(max_examples=100) +@given(envs=envs_strategy) +def test_remove_non_existent_env(envs: Dict[Uri, Any]): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.envs = {**envs} + + builder.remove_env(Uri("test", "non-existent")) + assert builder.config.envs == envs + + +@settings(max_examples=100) +@given(envs=envs_strategy) +def test_remove_envs(envs: Dict[Uri, Any]): + assume(envs) + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.envs = {**envs} + + uris = list(envs.keys()) + uri_indices = [ + randint(0, len(uris) - 1) for _ in range(randint(0, len(uris) - 1)) + ] + remove_uris = list({uris[uri_index] for uri_index in uri_indices}) + event(f"Uris to remove: {remove_uris}") + + builder.remove_envs(remove_uris) + assert len(builder.config.envs) == len(envs) - len(remove_uris) + assert set(remove_uris) & set(builder.config.envs.keys()) == set() + + diff --git a/packages/polywrap-client-config-builder/tests/env/test_set_env.py b/packages/polywrap-client-config-builder/tests/env/test_set_env.py new file mode 100644 index 00000000..f6753550 --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/env/test_set_env.py @@ -0,0 +1,50 @@ +from typing import Any, Dict +from hypothesis import assume, given, settings + +from polywrap_client_config_builder import ( + ClientConfigBuilder, + PolywrapClientConfigBuilder, +) +from polywrap_core import Uri + +from ..strategies import envs_strategy, uri_strategy, env_strategy + + +@settings(max_examples=100) +@given(envs=envs_strategy, new_uri=uri_strategy, new_env=env_strategy) +def test_set_env(envs: Dict[Uri, Any], new_uri: Uri, new_env: Any): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.envs = {**envs} + + existing_uris = set(builder.config.envs.keys()) + assume(new_uri not in existing_uris) + + builder.set_env(new_uri, new_env) + + assert len(builder.config.envs) == len(existing_uris) + 1 + assert builder.config.envs[new_uri] == new_env + + +@settings(max_examples=100) +@given(uri=uri_strategy, old_env=env_strategy, new_env=env_strategy) +def test_set_env_overwrite(uri: Uri, old_env: Any, new_env: Any): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.envs = {uri: old_env} + + builder.set_env(uri, new_env) + + assert builder.config.envs == {uri: new_env} + + +@settings(max_examples=100) +@given(initial_envs=envs_strategy, new_envs=envs_strategy) +def test_set_envs( + initial_envs: Dict[Uri, Any], + new_envs: Dict[Uri, Any], +): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.envs = {**initial_envs} + + builder.set_envs(new_envs) + + assert len(builder.config.envs) <= len(initial_envs) + len(new_envs) diff --git a/packages/polywrap-client-config-builder/tests/interface/__init__.py b/packages/polywrap-client-config-builder/tests/interface/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/packages/polywrap-client-config-builder/tests/interface/test_add_interface.py b/packages/polywrap-client-config-builder/tests/interface/test_add_interface.py new file mode 100644 index 00000000..23662e8b --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/interface/test_add_interface.py @@ -0,0 +1,25 @@ +from typing import List +from hypothesis import given, settings, strategies as st + +from polywrap_client_config_builder import ( + ClientConfigBuilder, + PolywrapClientConfigBuilder, +) +from polywrap_core import Uri + +from ..strategies import uri_strategy + + +@settings(max_examples=100) +@given(uri=uri_strategy, old_impls=st.lists(uri_strategy), new_impls=st.lists(uri_strategy)) +def test_add_implementations_to_existing_interface(uri: Uri, old_impls: List[Uri], new_impls: List[Uri]): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.interfaces = {uri: old_impls} + + builder.add_interface_implementations(uri, new_impls) + + updated_impls = {*old_impls, *new_impls} + + assert set(builder.config.interfaces[uri]) == updated_impls + + diff --git a/packages/polywrap-client-config-builder/tests/interface/test_get_interface.py b/packages/polywrap-client-config-builder/tests/interface/test_get_interface.py new file mode 100644 index 00000000..325e3dbe --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/interface/test_get_interface.py @@ -0,0 +1,40 @@ +from typing import Any, Dict, List +from hypothesis import given, settings + +from polywrap_client_config_builder import ( + ClientConfigBuilder, + PolywrapClientConfigBuilder, +) +from polywrap_core import Uri + +from ..strategies import interfaces_strategy + + +@settings(max_examples=100) +@given(interfaces=interfaces_strategy) +def test_get_interface_implementations( + interfaces: Dict[Uri, List[Uri]] +): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.interfaces = interfaces + + for uri in interfaces: + assert builder.get_interface_implementations(uri) == interfaces[uri] + assert builder.get_interface_implementations(Uri.from_str("test/not-exists")) is None + + +def test_get_implementations_not_exists(): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + assert builder.get_interface_implementations(Uri.from_str("test/not-exists")) is None + + +@settings(max_examples=100) +@given(interfaces=interfaces_strategy) +def test_get_interfaces( + interfaces: Dict[Uri, List[Uri]] +): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + assert builder.get_interfaces() == {} + + builder.config.interfaces = interfaces + assert builder.get_interfaces() == interfaces diff --git a/packages/polywrap-client-config-builder/tests/interface/test_remove_interface.py b/packages/polywrap-client-config-builder/tests/interface/test_remove_interface.py new file mode 100644 index 00000000..74e91e1c --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/interface/test_remove_interface.py @@ -0,0 +1,61 @@ +from typing import Any, Dict, List +from random import randint +from hypothesis import assume, event, given, settings + +from polywrap_client_config_builder import ( + ClientConfigBuilder, + PolywrapClientConfigBuilder, +) +from polywrap_core import Uri + +from ..strategies import interfaces_strategy, non_empty_interfaces_strategy + + +@settings(max_examples=50) +@given(interfaces=non_empty_interfaces_strategy) +def test_remove_interface(interfaces: Dict[Uri, List[Uri]]): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.interfaces = {**interfaces} + + uris = list(interfaces.keys()) + uri_index = randint(0, len(uris) - 1) + remove_uri = uris[uri_index] + event(f"Uri to remove: {remove_uri}") + + builder.remove_interface(remove_uri) + assert len(builder.config.interfaces) == len(interfaces) - 1 + assert remove_uri not in builder.config.interfaces + + +@settings(max_examples=50) +@given(interfaces=interfaces_strategy) +def test_remove_non_existent_interface(interfaces: Dict[Uri, List[Uri]]): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.interfaces = {**interfaces} + + builder.remove_interface(Uri("test", "non-existent")) + assert builder.config.interfaces == interfaces + + +@settings(max_examples=50) +@given(interfaces=non_empty_interfaces_strategy) +def test_remove_interface_implementations(interfaces: Dict[Uri, List[Uri]]): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.interfaces = {**interfaces} + + uris = list(interfaces.keys()) + uri_index = randint(0, len(uris) - 1) + remove_interface_uri = uris[uri_index] + event(f"Interface Uri to remove: {remove_interface_uri}") + + impls_uris = list(interfaces[remove_interface_uri]) + impl_uri_indices = [ + randint(0, len(impls_uris) - 1) for _ in range(randint(0, len(impls_uris) - 1)) + ] + remove_uris = list({impls_uris[uri_index] for uri_index in impl_uri_indices}) + event(f"Implementations Uri to remove: {remove_uris}") + + builder.remove_interface_implementations(remove_interface_uri, remove_uris) + assert ( + set(remove_uris) & set(builder.config.interfaces[remove_interface_uri]) == set() + ) diff --git a/packages/polywrap-client-config-builder/tests/package/__init__.py b/packages/polywrap-client-config-builder/tests/package/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/packages/polywrap-client-config-builder/tests/package/test_get_package.py b/packages/polywrap-client-config-builder/tests/package/test_get_package.py new file mode 100644 index 00000000..26b7b993 --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/package/test_get_package.py @@ -0,0 +1,40 @@ +from typing import Any, Dict +from hypothesis import given, settings + +from polywrap_client_config_builder import ( + ClientConfigBuilder, + PolywrapClientConfigBuilder, +) +from polywrap_core import Uri + +from ..strategies import packages_strategy + + +@settings(max_examples=100) +@given(packages=packages_strategy) +def test_get_package_exists( + packages: Dict[Uri, Any] +): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.packages = packages + + for uri in packages: + assert builder.get_package(uri) == packages[uri] + assert builder.get_package(Uri.from_str("test/not-exists")) is None + + +def test_get_package_not_exists(): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + assert builder.get_package(Uri.from_str("test/not-exists")) is None + + +@settings(max_examples=100) +@given(packages=packages_strategy) +def test_get_packages( + packages: Dict[Uri, Any] +): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + assert builder.get_packages() == {} + + builder.config.packages = packages + assert builder.get_packages() == packages diff --git a/packages/polywrap-client-config-builder/tests/package/test_remove_package.py b/packages/polywrap-client-config-builder/tests/package/test_remove_package.py new file mode 100644 index 00000000..341f6368 --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/package/test_remove_package.py @@ -0,0 +1,59 @@ +from typing import Any, Dict +from random import randint +from hypothesis import assume, event, given, settings + +from polywrap_client_config_builder import ( + ClientConfigBuilder, + PolywrapClientConfigBuilder, +) +from polywrap_core import Uri + +from ..strategies import packages_strategy + + +@settings(max_examples=100) +@given(packages=packages_strategy) +def test_remove_package(packages: Dict[Uri, Any]): + assume(packages) + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.packages = {**packages} + + uris = list(packages.keys()) + uri_index = randint(0, len(uris) - 1) + remove_uri = uris[uri_index] + event(f"Uri to remove: {remove_uri}") + + builder.remove_package(remove_uri) + assert len(builder.config.packages) == len(packages) - 1 + assert remove_uri not in builder.config.packages + + +@settings(max_examples=100) +@given(packages=packages_strategy) +def test_remove_non_existent_package(packages: Dict[Uri, Any]): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.packages = {**packages} + + builder.remove_package(Uri("test", "non-existent")) + assert builder.config.packages == packages + + +@settings(max_examples=100) +@given(packages=packages_strategy) +def test_remove_packages(packages: Dict[Uri, Any]): + assume(packages) + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.packages = {**packages} + + uris = list(packages.keys()) + uri_indices = [ + randint(0, len(uris) - 1) for _ in range(randint(0, len(uris) - 1)) + ] + remove_uris = list({uris[uri_index] for uri_index in uri_indices}) + event(f"Uris to remove: {remove_uris}") + + builder.remove_packages(remove_uris) + assert len(builder.config.packages) == len(packages) - len(remove_uris) + assert set(remove_uris) & set(builder.config.packages.keys()) == set() + + diff --git a/packages/polywrap-client-config-builder/tests/package/test_set_package.py b/packages/polywrap-client-config-builder/tests/package/test_set_package.py new file mode 100644 index 00000000..1e9161e7 --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/package/test_set_package.py @@ -0,0 +1,50 @@ +from typing import Any, Dict +from hypothesis import assume, given, settings + +from polywrap_client_config_builder import ( + ClientConfigBuilder, + PolywrapClientConfigBuilder, +) +from polywrap_core import Uri + +from ..strategies import packages_strategy, uri_strategy, package_strategy + + +@settings(max_examples=100) +@given(packages=packages_strategy, new_uri=uri_strategy, new_package=package_strategy) +def test_set_package(packages: Dict[Uri, Any], new_uri: Uri, new_package: Any): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.packages = {**packages} + + existing_uris = set(builder.config.packages.keys()) + assume(new_uri not in existing_uris) + + builder.set_package(new_uri, new_package) + + assert len(builder.config.packages) == len(existing_uris) + 1 + assert builder.config.packages[new_uri] == new_package + + +@settings(max_examples=100) +@given(uri=uri_strategy, old_package=package_strategy, new_package=package_strategy) +def test_set_env_overwrite(uri: Uri, old_package: Any, new_package: Any): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.packages = {uri: old_package} + + builder.set_package(uri, new_package) + + assert builder.config.packages == {uri: new_package} + + +@settings(max_examples=100) +@given(initial_packages=packages_strategy, new_packages=packages_strategy) +def test_set_packages( + initial_packages: Dict[Uri, Any], + new_packages: Dict[Uri, Any], +): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.packages = {**initial_packages} + + builder.set_packages(new_packages) + + assert len(builder.config.envs) <= len(initial_packages) + len(new_packages) diff --git a/packages/polywrap-client-config-builder/tests/redirect/__init__.py b/packages/polywrap-client-config-builder/tests/redirect/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/packages/polywrap-client-config-builder/tests/redirect/test_get_redirect.py b/packages/polywrap-client-config-builder/tests/redirect/test_get_redirect.py new file mode 100644 index 00000000..5a07cd7e --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/redirect/test_get_redirect.py @@ -0,0 +1,40 @@ +from typing import Any, Dict +from hypothesis import given, settings + +from polywrap_client_config_builder import ( + ClientConfigBuilder, + PolywrapClientConfigBuilder, +) +from polywrap_core import Uri + +from ..strategies import redirects_strategy + + +@settings(max_examples=100) +@given(redirects=redirects_strategy) +def test_get_redirect_exists( + redirects: Dict[Uri, Any] +): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.redirects = redirects + + for uri in redirects: + assert builder.get_redirect(uri) == redirects[uri] + assert builder.get_redirect(Uri.from_str("test/not-exists")) is None + + +def test_get_redirect_not_exists(): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + assert builder.get_redirect(Uri.from_str("test/not-exists")) is None + + +@settings(max_examples=100) +@given(redirects=redirects_strategy) +def test_get_redirects( + redirects: Dict[Uri, Any] +): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + assert builder.get_redirects() == {} + + builder.config.redirects = redirects + assert builder.get_redirects() == redirects diff --git a/packages/polywrap-client-config-builder/tests/redirect/test_remove_redirect.py b/packages/polywrap-client-config-builder/tests/redirect/test_remove_redirect.py new file mode 100644 index 00000000..045f48cd --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/redirect/test_remove_redirect.py @@ -0,0 +1,59 @@ +from typing import Any, Dict +from random import randint +from hypothesis import assume, event, given, settings + +from polywrap_client_config_builder import ( + ClientConfigBuilder, + PolywrapClientConfigBuilder, +) +from polywrap_core import Uri + +from ..strategies import redirects_strategy + + +@settings(max_examples=100) +@given(redirects=redirects_strategy) +def test_remove_redirect(redirects: Dict[Uri, Any]): + assume(redirects) + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.redirects = {**redirects} + + uris = list(redirects.keys()) + uri_index = randint(0, len(uris) - 1) + remove_uri = uris[uri_index] + event(f"Uri to remove: {remove_uri}") + + builder.remove_redirect(remove_uri) + assert len(builder.config.redirects) == len(redirects) - 1 + assert remove_uri not in builder.config.redirects + + +@settings(max_examples=100) +@given(redirects=redirects_strategy) +def test_remove_non_existent_redirect(redirects: Dict[Uri, Any]): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.redirects = {**redirects} + + builder.remove_redirect(Uri("test", "non-existent")) + assert builder.config.redirects == redirects + + +@settings(max_examples=100) +@given(redirects=redirects_strategy) +def test_remove_redirects(redirects: Dict[Uri, Any]): + assume(redirects) + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.redirects = {**redirects} + + uris = list(redirects.keys()) + uri_indices = [ + randint(0, len(uris) - 1) for _ in range(randint(0, len(uris) - 1)) + ] + remove_uris = list({uris[uri_index] for uri_index in uri_indices}) + event(f"Uris to remove: {remove_uris}") + + builder.remove_redirects(remove_uris) + assert len(builder.config.redirects) == len(redirects) - len(remove_uris) + assert set(remove_uris) & set(builder.config.redirects.keys()) == set() + + diff --git a/packages/polywrap-client-config-builder/tests/redirect/test_set_redirect.py b/packages/polywrap-client-config-builder/tests/redirect/test_set_redirect.py new file mode 100644 index 00000000..4eed5de9 --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/redirect/test_set_redirect.py @@ -0,0 +1,50 @@ +from typing import Any, Dict +from hypothesis import assume, given, settings + +from polywrap_client_config_builder import ( + ClientConfigBuilder, + PolywrapClientConfigBuilder, +) +from polywrap_core import Uri + +from ..strategies import redirects_strategy, uri_strategy + + +@settings(max_examples=100) +@given(redirects=redirects_strategy, new_uri=uri_strategy, new_redirect=uri_strategy) +def test_set_redirect(redirects: Dict[Uri, Any], new_uri: Uri, new_redirect: Any): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.redirects = {**redirects} + + existing_uris = set(builder.config.redirects.keys()) + assume(new_uri not in existing_uris) + + builder.set_redirect(new_uri, new_redirect) + + assert len(builder.config.redirects) == len(existing_uris) + 1 + assert builder.config.redirects[new_uri] == new_redirect + + +@settings(max_examples=100) +@given(uri=uri_strategy, old_redirect=uri_strategy, new_redirect=uri_strategy) +def test_set_env_overwrite(uri: Uri, old_redirect: Any, new_redirect: Any): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.redirects = {uri: old_redirect} + + builder.set_redirect(uri, new_redirect) + + assert builder.config.redirects == {uri: new_redirect} + + +@settings(max_examples=100) +@given(initial_redirects=redirects_strategy, new_redirects=redirects_strategy) +def test_set_redirects( + initial_redirects: Dict[Uri, Any], + new_redirects: Dict[Uri, Any], +): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.redirects = {**initial_redirects} + + builder.set_redirects(new_redirects) + + assert len(builder.config.envs) <= len(initial_redirects) + len(new_redirects) diff --git a/packages/polywrap-client-config-builder/tests/resolver/__init__.py b/packages/polywrap-client-config-builder/tests/resolver/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/packages/polywrap-client-config-builder/tests/resolver/test_add_resolvers.py b/packages/polywrap-client-config-builder/tests/resolver/test_add_resolvers.py new file mode 100644 index 00000000..eba6062d --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/resolver/test_add_resolvers.py @@ -0,0 +1,35 @@ +from typing import Any, List +from hypothesis import given, settings + +from polywrap_client_config_builder import ( + ClientConfigBuilder, + PolywrapClientConfigBuilder, +) +from polywrap_core import UriResolver + +from ..strategies import resolvers_strategy, resolver_strategy + + +@settings(max_examples=100) +@given(resolvers=resolvers_strategy, new_resolver=resolver_strategy) +def test_add_resolver(resolvers: List[UriResolver], new_resolver: Any): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.resolvers = [*resolvers] + builder.add_resolver(new_resolver) + + assert len(builder.config.resolvers) == len(resolvers) + 1 + assert builder.config.resolvers[-1] == new_resolver + + +@settings(max_examples=100) +@given(initial_resolvers=resolvers_strategy, new_resolvers=resolvers_strategy) +def test_add_resolvers( + initial_resolvers: List[UriResolver], + new_resolvers: List[UriResolver], +): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.resolvers = [*initial_resolvers] + + builder.add_resolvers(new_resolvers) + + assert len(builder.config.resolvers) == len(initial_resolvers) + len(new_resolvers) diff --git a/packages/polywrap-client-config-builder/tests/resolver/test_get_resolvers.py b/packages/polywrap-client-config-builder/tests/resolver/test_get_resolvers.py new file mode 100644 index 00000000..eb78c419 --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/resolver/test_get_resolvers.py @@ -0,0 +1,22 @@ +from typing import Any, Dict, List +from hypothesis import given, settings + +from polywrap_client_config_builder import ( + ClientConfigBuilder, + PolywrapClientConfigBuilder, +) +from polywrap_core import UriResolver + +from ..strategies import resolvers_strategy + + +@settings(max_examples=100) +@given(resolvers=resolvers_strategy) +def test_get_resolvers( + resolvers: List[UriResolver] +): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + assert builder.get_resolvers() == [] + + builder.config.resolvers = resolvers + assert builder.get_resolvers() == resolvers diff --git a/packages/polywrap-client-config-builder/tests/strategies.py b/packages/polywrap-client-config-builder/tests/strategies.py new file mode 100644 index 00000000..7f27463b --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/strategies.py @@ -0,0 +1,70 @@ +from polywrap_core import Uri, UriResolver, WrapPackage, Wrapper +from hypothesis import strategies as st +from unittest.mock import Mock + +from polywrap_client_config_builder import BuilderConfig + +from .consts import C_LONG_MAX, C_LONG_MIN + +# List of Mock resolvers +MockResolvers = [Mock(UriResolver, name=f"MockResolver{i}") for i in range(10)] + +# List of Mock wrappers +MockWrappers = [Mock(Wrapper, name=f"MockWrapper{i}") for i in range(10)] + +# List of Mock packages +MockPackages = [Mock(WrapPackage, name=f"MockPackage{i}") for i in range(10)] + +# Scalars +scalar_st_list = [ + st.none(), + st.booleans(), + st.integers(min_value=C_LONG_MIN, max_value=C_LONG_MAX), + st.floats(allow_nan=False), + st.text(), + st.binary(), +] + +# Uri +uri_safe_chars_strategy = st.text( + alphabet=st.characters(whitelist_categories="L", whitelist_characters="-._~") +) +uri_strategy = st.builds(Uri, uri_safe_chars_strategy, uri_safe_chars_strategy) + +# Env +env_strategy = st.dictionaries(st.text(), st.one_of(scalar_st_list), max_size=10) +envs_strategy = st.dictionaries( + uri_strategy, env_strategy, max_size=10 +) + +# Interface Implementations +interfaces_strategy = st.dictionaries(uri_strategy, st.lists(uri_strategy, max_size=10), max_size=10) + +# Non-empty Interface Implementations +non_empty_interfaces_strategy = st.dictionaries(uri_strategy, st.lists(uri_strategy, min_size=1, max_size=10), min_size=1, max_size=10) + +# URI Redirects +redirects_strategy = st.dictionaries(uri_strategy, uri_strategy, max_size=10) + +# Resolver +resolver_strategy = st.sampled_from(MockResolvers) +resolvers_strategy = st.lists(resolver_strategy, max_size=10) + +# Wrapper +wrapper_strategy = st.sampled_from(MockWrappers) +wrappers_strategy = st.dictionaries(uri_strategy, wrapper_strategy, max_size=10) + +# Packages +package_strategy = st.sampled_from(MockPackages) +packages_strategy = st.dictionaries(uri_strategy, package_strategy, max_size=10) + +# builder config +builder_config_strategy = st.builds( + BuilderConfig, + envs=envs_strategy, + interfaces=interfaces_strategy, + wrappers=wrappers_strategy, + packages=packages_strategy, + resolvers=resolvers_strategy, + redirects=redirects_strategy, +) diff --git a/packages/polywrap-client-config-builder/tests/test_add.py b/packages/polywrap-client-config-builder/tests/test_add.py new file mode 100644 index 00000000..d0ca5951 --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/test_add.py @@ -0,0 +1,61 @@ +from typing import List +from hypothesis import given, settings, strategies as st + +from polywrap_client_config_builder import ( + BuilderConfig, + ClientConfigBuilder, + PolywrapClientConfigBuilder, +) + +from .strategies import builder_config_strategy + + +@settings(max_examples=100) +@given(config=builder_config_strategy) +def test_add_builder_config( + config: BuilderConfig, +): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder = builder.add(config) + assert builder.config.envs == config.envs + assert builder.config.interfaces == config.interfaces + assert builder.config.redirects == config.redirects + assert builder.config.resolvers == config.resolvers + assert builder.config.wrappers == config.wrappers + assert builder.config.packages == config.packages + + +@settings(max_examples=10) +@given(configs=st.lists(builder_config_strategy, max_size=10)) +def test_add_multiple_builder_config(configs: List[BuilderConfig]): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + expected_config = BuilderConfig() + + for config in configs: + builder = builder.add(config) + expected_config.envs.update(config.envs) + expected_config.interfaces.update(config.interfaces) + expected_config.packages.update(config.packages) + expected_config.wrappers.update(config.wrappers) + expected_config.redirects.update(config.redirects) + expected_config.resolvers.extend(config.resolvers) + + assert builder.config == expected_config + + assert builder.config == expected_config + + +@settings(max_examples=100) +@given(config=builder_config_strategy) +def test_add_builder_config_with_duplicate_data( + config: BuilderConfig, +): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder = builder.add(config) + builder = builder.add(config) + assert builder.config.envs == config.envs + assert builder.config.interfaces == config.interfaces + assert builder.config.redirects == config.redirects + assert len(builder.config.resolvers) == 2 * len(config.resolvers) + assert builder.config.wrappers == config.wrappers + assert builder.config.packages == config.packages diff --git a/packages/polywrap-client-config-builder/tests/test_build.py b/packages/polywrap-client-config-builder/tests/test_build.py new file mode 100644 index 00000000..783848ca --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/test_build.py @@ -0,0 +1,121 @@ +from typing import Dict, cast +from unittest.mock import patch +from polywrap_uri_resolvers import ( + PackageResolver, + RecursiveResolver, + StaticResolver, + UriResolverAggregator, + ResolutionResultCacheResolver, + ExtendableUriResolver, + InMemoryResolutionResultCache, +) +from polywrap_client_config_builder import ( + BuildOptions, + PolywrapClientConfigBuilder, +) +from polywrap_core import Uri, UriPackage, UriWrapper, WrapPackage, Wrapper +import pytest + + +@pytest.fixture +def builder() -> PolywrapClientConfigBuilder: + """Return a PolywrapClientConfigBuilder with a default config.""" + return PolywrapClientConfigBuilder() + + +def test_build_resolver_order(builder: PolywrapClientConfigBuilder): + """Test the order of resolvers in UriResolverAggregator.""" + redirects: Dict[Uri, Uri] = {Uri.from_str("test/1"): Uri.from_str("test/2")} + builder.config.redirects = redirects + + config = builder.build() + + isinstance(config.resolver, RecursiveResolver) + recursive_resolver = cast(RecursiveResolver, config.resolver) + + isinstance(recursive_resolver.resolver, ResolutionResultCacheResolver) + cache_resolver = cast(ResolutionResultCacheResolver, recursive_resolver.resolver) + + isinstance(cache_resolver.resolver_to_cache, UriResolverAggregator) + aggregator_resolver = cast(UriResolverAggregator, cache_resolver.resolver_to_cache) + + aggregated_resolvers = aggregator_resolver._resolvers # type: ignore + assert isinstance(aggregated_resolvers[0], StaticResolver) + assert isinstance(aggregated_resolvers[1], ExtendableUriResolver) + + +def test_no_build_options(builder: PolywrapClientConfigBuilder): + """Test the absence of resolver in BuildOptions.""" + config = builder.build() + assert isinstance(config.resolver, RecursiveResolver) + + +def test_build_options_resolver(builder: PolywrapClientConfigBuilder): + """Test the presence of resolver in BuildOptions overrides the default one.""" + redirects: Dict[Uri, Uri] = {Uri.from_str("test/1"): Uri.from_str("test/2")} + builder.config.redirects = redirects + + config = builder.build( + BuildOptions( + resolver=PackageResolver( + uri=Uri.from_str("test/package"), package=NotImplemented + ) + ) + ) + + assert isinstance(config.resolver, PackageResolver) + + +def test_build_options_cache(builder: PolywrapClientConfigBuilder): + """Test the presence of cache in BuildOptions overrides the default one.""" + custom_cache = InMemoryResolutionResultCache() + config = builder.build(BuildOptions(resolution_result_cache=custom_cache)) + assert isinstance(config.resolver, RecursiveResolver) + assert isinstance(config.resolver.resolver, ResolutionResultCacheResolver) + + assert config.resolver.resolver.cache is custom_cache + + +def test_build_static_resolver_like(builder: PolywrapClientConfigBuilder): + """Test the composition of StaticResolverLike.""" + redirects: Dict[Uri, Uri] = {Uri.from_str("test/from"): Uri.from_str("test/to")} + builder.config.redirects = redirects + + with patch("polywrap_core.types.wrapper.Wrapper") as MockWrapper, patch( + "polywrap_core.types.wrap_package.WrapPackage" + ) as MockPackage: + + wrappers: Dict[Uri, Wrapper] = {Uri.from_str("test/wrapper"): MockWrapper} + builder.config.wrappers = wrappers + + packages: Dict[Uri, WrapPackage] = {Uri.from_str("test/package"): MockPackage} + builder.config.packages = packages + + static_resolver_like = builder._build_static_resolver_like() # type: ignore + + assert static_resolver_like[Uri.from_str("test/from")] == Uri.from_str( + "test/to" + ) + assert static_resolver_like[Uri.from_str("test/wrapper")] == UriWrapper( + uri=Uri.from_str("test/wrapper"), wrapper=MockWrapper + ) + assert static_resolver_like[Uri.from_str("test/package")] == UriPackage( + uri=Uri.from_str("test/package"), package=MockPackage + ) + + +def test_build_client_config_attributes(builder: PolywrapClientConfigBuilder): + """Test the attributes of ClientConfig.""" + envs = {Uri("test", "env1"): "test", Uri("test", "env2"): "test"} + builder.config.envs = envs + + interfaces = { + Uri("test", "interface1"): [Uri("test", "impl1"), Uri("test", "impl2")], + Uri("test", "interface2"): [Uri("test", "impl3")], + } + builder.config.interfaces = interfaces + + config = builder.build() + + assert config.envs is envs + assert config.interfaces is interfaces diff --git a/packages/polywrap-client-config-builder/tests/test_client_config_builder.py b/packages/polywrap-client-config-builder/tests/test_client_config_builder.py index 9c8ae684..e8b2f4a3 100644 --- a/packages/polywrap-client-config-builder/tests/test_client_config_builder.py +++ b/packages/polywrap-client-config-builder/tests/test_client_config_builder.py @@ -1,3 +1,7 @@ +# TODO: ccb test -> post-cd fix -> release -> plugin update -> default ccb + + + # """ # Polywrap Python Client. diff --git a/packages/polywrap-client-config-builder/tests/wrapper/__init__.py b/packages/polywrap-client-config-builder/tests/wrapper/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/packages/polywrap-client-config-builder/tests/wrapper/test_get_wrapper.py b/packages/polywrap-client-config-builder/tests/wrapper/test_get_wrapper.py new file mode 100644 index 00000000..2203892b --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/wrapper/test_get_wrapper.py @@ -0,0 +1,40 @@ +from typing import Any, Dict +from hypothesis import given, settings + +from polywrap_client_config_builder import ( + ClientConfigBuilder, + PolywrapClientConfigBuilder, +) +from polywrap_core import Uri + +from ..strategies import wrappers_strategy + + +@settings(max_examples=100) +@given(wrappers=wrappers_strategy) +def test_get_wrapper_exists( + wrappers: Dict[Uri, Any] +): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.wrappers = wrappers + + for uri in wrappers: + assert builder.get_wrapper(uri) == wrappers[uri] + assert builder.get_wrapper(Uri.from_str("test/not-exists")) is None + + +def test_get_wrapper_not_exists(): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + assert builder.get_wrapper(Uri.from_str("test/not-exists")) is None + + +@settings(max_examples=100) +@given(wrappers=wrappers_strategy) +def test_get_wrappers( + wrappers: Dict[Uri, Any] +): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + assert builder.get_wrappers() == {} + + builder.config.wrappers = wrappers + assert builder.get_wrappers() == wrappers diff --git a/packages/polywrap-client-config-builder/tests/wrapper/test_remove_wrapper.py b/packages/polywrap-client-config-builder/tests/wrapper/test_remove_wrapper.py new file mode 100644 index 00000000..0a54eae4 --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/wrapper/test_remove_wrapper.py @@ -0,0 +1,59 @@ +from typing import Any, Dict +from random import randint +from hypothesis import assume, event, given, settings + +from polywrap_client_config_builder import ( + ClientConfigBuilder, + PolywrapClientConfigBuilder, +) +from polywrap_core import Uri + +from ..strategies import wrappers_strategy + + +@settings(max_examples=100) +@given(wrappers=wrappers_strategy) +def test_remove_wrapper(wrappers: Dict[Uri, Any]): + assume(wrappers) + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.wrappers = {**wrappers} + + uris = list(wrappers.keys()) + uri_index = randint(0, len(uris) - 1) + remove_uri = uris[uri_index] + event(f"Uri to remove: {remove_uri}") + + builder.remove_wrapper(remove_uri) + assert len(builder.config.wrappers) == len(wrappers) - 1 + assert remove_uri not in builder.config.wrappers + + +@settings(max_examples=100) +@given(wrappers=wrappers_strategy) +def test_remove_non_existent_wrapper(wrappers: Dict[Uri, Any]): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.wrappers = {**wrappers} + + builder.remove_wrapper(Uri("test", "non-existent")) + assert builder.config.wrappers == wrappers + + +@settings(max_examples=100) +@given(wrappers=wrappers_strategy) +def test_remove_wrappers(wrappers: Dict[Uri, Any]): + assume(wrappers) + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.wrappers = {**wrappers} + + uris = list(wrappers.keys()) + uri_indices = [ + randint(0, len(uris) - 1) for _ in range(randint(0, len(uris) - 1)) + ] + remove_uris = list({uris[uri_index] for uri_index in uri_indices}) + event(f"Uris to remove: {remove_uris}") + + builder.remove_wrappers(remove_uris) + assert len(builder.config.wrappers) == len(wrappers) - len(remove_uris) + assert set(remove_uris) & set(builder.config.wrappers.keys()) == set() + + diff --git a/packages/polywrap-client-config-builder/tests/wrapper/test_set_wrapper.py b/packages/polywrap-client-config-builder/tests/wrapper/test_set_wrapper.py new file mode 100644 index 00000000..da05a52b --- /dev/null +++ b/packages/polywrap-client-config-builder/tests/wrapper/test_set_wrapper.py @@ -0,0 +1,50 @@ +from typing import Any, Dict +from hypothesis import assume, given, settings + +from polywrap_client_config_builder import ( + ClientConfigBuilder, + PolywrapClientConfigBuilder, +) +from polywrap_core import Uri + +from ..strategies import wrappers_strategy, uri_strategy, wrapper_strategy + + +@settings(max_examples=100) +@given(wrappers=wrappers_strategy, new_uri=uri_strategy, new_wrapper=wrapper_strategy) +def test_set_wrapper(wrappers: Dict[Uri, Any], new_uri: Uri, new_wrapper: Any): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.wrappers = {**wrappers} + + existing_uris = set(builder.config.wrappers.keys()) + assume(new_uri not in existing_uris) + + builder.set_wrapper(new_uri, new_wrapper) + + assert len(builder.config.wrappers) == len(existing_uris) + 1 + assert builder.config.wrappers[new_uri] == new_wrapper + + +@settings(max_examples=100) +@given(uri=uri_strategy, old_wrapper=wrapper_strategy, new_wrapper=wrapper_strategy) +def test_set_env_overwrite(uri: Uri, old_wrapper: Any, new_wrapper: Any): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.wrappers = {uri: old_wrapper} + + builder.set_wrapper(uri, new_wrapper) + + assert builder.config.wrappers == {uri: new_wrapper} + + +@settings(max_examples=100) +@given(initial_wrappers=wrappers_strategy, new_wrappers=wrappers_strategy) +def test_set_wrappers( + initial_wrappers: Dict[Uri, Any], + new_wrappers: Dict[Uri, Any], +): + builder: ClientConfigBuilder = PolywrapClientConfigBuilder() + builder.config.wrappers = {**initial_wrappers} + + builder.set_wrappers(new_wrappers) + + assert len(builder.config.envs) <= len(initial_wrappers) + len(new_wrappers) diff --git a/packages/polywrap-uri-resolvers/polywrap_uri_resolvers/resolvers/package/package_resolver.py b/packages/polywrap-uri-resolvers/polywrap_uri_resolvers/resolvers/package/package_resolver.py index c25623c0..496aa659 100644 --- a/packages/polywrap-uri-resolvers/polywrap_uri_resolvers/resolvers/package/package_resolver.py +++ b/packages/polywrap-uri-resolvers/polywrap_uri_resolvers/resolvers/package/package_resolver.py @@ -19,15 +19,15 @@ class PackageResolver(ResolverWithHistory): uri: Uri package: WrapPackage - def __init__(self, uri: Uri, wrap_package: WrapPackage): + def __init__(self, uri: Uri, package: WrapPackage): """Initialize a new PackageResolver instance. Args: uri (Uri): The uri to resolve. - wrap_package (WrapPackage): The wrap package to return. + package (WrapPackage): The wrap package to return. """ self.uri = uri - self.package = wrap_package + self.package = package super().__init__() def get_step_description(self) -> str: