def test_schemaless_apply_changes(): cat = {"name": "Gordon"} types = {"name": str, "age": int, "color": str} permitted = types.keys() changeset = Changeset((cat, types)).cast({"color": "brown", "age": 14}, permitted) assert changeset.apply_changes() == {"name": "Gordon", "age": 14, "color": "brown"}
def test_validate_change_only_validates_if_field_is_changed(): changeset = ( Changeset(Person()) .cast({"name": "Richard"}, ["name"]) .validate_change("age", is_30) ) assert changeset.is_valid
def test_cast_type_check(key, val, valid, error): changeset = Changeset(Book()).cast({key: val}, [key]) if valid: assert changeset.is_valid assert changeset.changes[key] == val else: assert changeset.errors[key] == [error]
def test_put_change(): assert ( Changeset(Book()) .cast({"title": "The Idiot"}, ["title"]) .put_change("isbn", "01234567890") .changes["isbn"] ) == "01234567890"
def test_put_assoc_with_dict_data_is_invalid(): user = User(id=1, name="Bear") with pytest.raises(ValueError): ( Changeset(({}, {})) .cast({"name": "Big Blue House"}, ["name"]) .put_assoc("owner", user) )
def test_put_assoc(): user = User(id=1, name="Bear") changeset = ( Changeset(Home()) .cast({"name": "Big Blue House"}, ["name"]) .put_assoc("owner", user) ) assert changeset.changes == {"owner_id": 1, "name": "Big Blue House"}
def test_schemaless_invalid(): cat = {"name": "Gordon"} types = {"name": str, "age": int, "color": str} permitted = types.keys() changeset = Changeset((cat, types)).cast( {"color": "brown", "age": "fourteen"}, permitted ) assert changeset.errors == {"age": ["Not a valid integer."]}
def test_change_allows_one_to_add_invalid_changes(): changeset = ( Changeset(Person()) .cast({"name": "Richard"}, ["name"]) .validate_change("age", is_30) .change({"id": "foo"}) ) assert changeset.changes["id"] == "foo"
def cast_changeset(model_or_changeset: Union[Model, Changeset]) -> Changeset: if isinstance(model_or_changeset, Model): changes = model_or_changeset.attributes empty_model = type(model_or_changeset)() return Changeset(empty_model).cast(changes, list(changes.keys())) elif isinstance(model_or_changeset, Changeset): return model_or_changeset else: raise ValueError("Must be Model instance or Changeset.")
def test_validate_exclusion_valid(): assert ( Changeset(Person()) .cast( {"name": "Richard", "age": 30, "favorite_animal": "weasel"}, ["name", "age", "favorite_animal"], ) .validate_exclusion("favorite_animal", ["spider"]) ).is_valid
def test_validate_change(): changeset = ( Changeset(Person()) .cast({"name": "Richard", "age": 31}, ["name", "age"]) .validate_change("age", is_30) ) assert changeset.errors == { "age": ["not 30"], }
def test_cast_custom_empty_values(): empty_value = "this is actually empty" not_empty_value = "" assert ( Changeset(Book()).cast( {"title": empty_value, "slug": not_empty_value}, ["title", "slug"], empty_values=[empty_value], ) ).changes == {"slug": not_empty_value}
def test_validate_inclusion_invalid(): changeset = ( Changeset(Person()) .cast( {"name": "Richard", "age": 30, "favorite_animal": "bat"}, ["name", "age", "favorite_animal"], ) .validate_inclusion("favorite_animal", ["weasel"], "not a weasel") ) assert changeset.errors == {"favorite_animal": ["not a weasel"]}
def test_on_changed_when_changing_value_to_none(): params = { "title": None, "publication_date": date(1866, 1, 1), } changeset = ( Changeset(Book(title="Crime and Punishment")) .cast(params, ["title", "publication_date"]) .on_changed("title", lambda cs, v: cs.put_change("slug", "slug-removed")) ) assert changeset.changes.get("slug") == "slug-removed"
def test_validate_exclusion_invalid(): changeset = ( Changeset(Person()) .cast( {"name": "Richard", "age": 30, "favorite_animal": "spider"}, ["name", "age", "favorite_animal"], ) .validate_exclusion( "favorite_animal", ["spider"], "def not your favorite animal" ) ) assert changeset.errors == {"favorite_animal": ["def not your favorite animal"]}
def test_on_changed_with_no_change(): def _slugify(changeset, title): return changeset.put_change("slug", title.lower().replace(" ", "-")) params = { "publication_date": date(1866, 1, 1), } changeset = ( Changeset(Book(title="Crime and Punishment")) .cast(params, ["title", "publication_date"]) .on_changed("title", _slugify) ) assert changeset.changes.get("slug") is None
def test_on_changed(): def _slugify(changeset, title): return changeset.put_change("slug", title.lower().replace(" ", "-")) params = { "title": "Crime and Punishment", "publication_date": date(1866, 1, 1), } book = ( Changeset(Book()) .cast(params, ["title", "publication_date"]) .on_changed("title", _slugify) .apply_changes() ) assert book.slug == "crime-and-punishment"
async def update(self, changeset: Changeset) -> Model: """ Update a record in the database. Examples:: user = await repo.get(User, 1) changeset = Changeset(user).cast({"name": "Fred"}, params=["name"]) await repo.update(changeset) """ if not changeset.is_valid: raise InvalidChangesetError(action="update", changeset=changeset) record = changeset.data query = record.to_query() sql = query.to_update_sql().values(changeset.changes) await self.database.execute(sql) return changeset.apply_changes()
def _put_foo(changeset: Changeset) -> Changeset: return changeset.put_change("foo", "bar")
def test_validate_length_no_params(): assert ( Changeset(Book()).cast({"isbn": "123456789"}, ["isbn"]).validate_length("isbn") ).is_valid
def test_cast_default_empty_values(): params = {"title": "", "slug": "not-empty", "pages": None} assert (Changeset(Book()).cast(params, ["title", "slug", "pages"])).changes == { "slug": "not-empty", }
def test_cast_unknown_type(): changeset = Changeset(User()).cast({"unknown": 1}, ["unknown"]) assert changeset.changes == {}
def test_cast_param_same_as_data(): assert ( Changeset(Book(title="Great Expectations")).cast( {"title": "Great Expectations"}, ["title"] ) ).changes == {}
def test_cast_empty(): changeset = Changeset(User()).cast({}, []) assert changeset.is_valid assert changeset.changes == {}
def test_cast(): changeset = Changeset(User()).cast({"name": "Richard", "foo": "bar"}, ["name"]) assert changeset.is_valid assert changeset.changes == {"name": "Richard"}
def test_invalid_data(): with pytest.raises(AttributeError): Changeset("foo")
def test_get_change_found(): assert (Changeset(Book()).put_change("foo", "bar").get_change("foo")) == "bar"
def test_pipe(): def _put_foo(changeset: Changeset) -> Changeset: return changeset.put_change("foo", "bar") assert Changeset(Book()).pipe(_put_foo).changes == {"foo": "bar"}
def test_get_change_not_found_custom_value(): assert (Changeset(Book()).get_change("foo", "baz")) == "baz"
def test_get_change_not_found_default_value(): assert (Changeset(Book()).get_change("foo")) is None