From 2de83db16b276bd31c0894a2ecf2c35ed4a841e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Mond=C3=A9jar=20Rubio?= Date: Fri, 27 May 2022 20:27:41 +0200 Subject: [PATCH 1/3] Fix falsy values not being properly compared --- src/nitpick/blender.py | 3 ++- tests/test_yaml.py | 25 ++++++++++++++++++- tests/test_yaml/dict-falsy-values-actual.yaml | 16 ++++++++++++ .../test_yaml/dict-falsy-values-desired.toml | 20 +++++++++++++++ .../test_yaml/dict-falsy-values-expected.yaml | 16 ++++++++++++ 5 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 tests/test_yaml/dict-falsy-values-actual.yaml create mode 100644 tests/test_yaml/dict-falsy-values-desired.toml create mode 100644 tests/test_yaml/dict-falsy-values-expected.yaml diff --git a/src/nitpick/blender.py b/src/nitpick/blender.py index 52b083cc..7f7ef41c 100644 --- a/src/nitpick/blender.py +++ b/src/nitpick/blender.py @@ -10,6 +10,7 @@ import json import re import shlex +from collections.abc import Iterable from functools import lru_cache, partial from pathlib import Path from typing import Any, Callable, TypeVar, cast @@ -160,7 +161,7 @@ def find_by_key(self, desired: ElementDetail) -> ElementDetail | None: def set_key_if_not_empty(dict_: JsonDict, key: str, value: Any) -> None: """Update the dict if the value is valid.""" - if not value: + if isinstance(value, Iterable) and not value: return dict_[key] = value diff --git a/tests/test_yaml.py b/tests/test_yaml.py index 2b531057..817fd173 100644 --- a/tests/test_yaml.py +++ b/tests/test_yaml.py @@ -121,7 +121,6 @@ def test_objects_are_compared_by_hash_on_list_of_dicts_and_new_ones_are_added(tm def test_maximum_two_level_nesting_on_lists_using_jmes_expression_as_list_key_fails(tmp_path, datadir): """Test a maximum of two-level nesting on lists. Using a JMES expression as a list key will fail. - Keys must have a maximum of 2 level for now: parent and nested keys. """ filename = "an/arbitrary/file.yaml" @@ -153,3 +152,27 @@ def test_maximum_two_level_nesting_on_lists_using_jmes_expression_as_list_key_fa ), ).assert_file_contents(filename, datadir / "jmes-list-key-expected.yaml") project.api_check().assert_violations() + + +def test_falsy_values_properly_reported(tmp_path, datadir): + filename = "foo/file.yaml" + project = ProjectMock(tmp_path).save_file(filename, datadir / "dict-falsy-values-actual.yaml") + project.style(datadir / "dict-falsy-values-desired.toml").api_check_then_fix( + Fuss( + True, + filename, + 369, + " has different values. Use this:", + """ + boolean_true_unmatch: true + boolean_false_unmatch: false + string_a_unmatch: string_a + string_b_unmatch: string_b + truthy_int_unmatch: 1 + falsy_int_unmatch: 0 + truthy_float_unmatch: 1.0 + falsy_float_unmatch: 0.0 + """, + ), + ).assert_file_contents(filename, datadir / "dict-falsy-values-expected.yaml") + project.api_check().assert_violations() diff --git a/tests/test_yaml/dict-falsy-values-actual.yaml b/tests/test_yaml/dict-falsy-values-actual.yaml new file mode 100644 index 00000000..ac087005 --- /dev/null +++ b/tests/test_yaml/dict-falsy-values-actual.yaml @@ -0,0 +1,16 @@ +boolean_true_match: true +boolean_true_unmatch: false +boolean_false_match: false +boolean_false_unmatch: true +string_a_match: 'string_a' +string_a_unmatch: 'string_b' +string_b_match: 'string_b' +string_b_unmatch: 'string_a' +truthy_int_match: 1 +truthy_int_unmatch: 0 +falsy_int_match: 0 +falsy_int_unmatch: 1 +truthy_float_match: 1.0 +truthy_float_unmatch: 0.0 +falsy_float_match: 0.0 +falsy_float_unmatch: 1.0 diff --git a/tests/test_yaml/dict-falsy-values-desired.toml b/tests/test_yaml/dict-falsy-values-desired.toml new file mode 100644 index 00000000..4323cc0e --- /dev/null +++ b/tests/test_yaml/dict-falsy-values-desired.toml @@ -0,0 +1,20 @@ +["foo/file.yaml"] +boolean_true_match = true +boolean_true_unmatch = true +boolean_false_match = false +boolean_false_unmatch = false + +string_a_match = "string_a" +string_a_unmatch = "string_a" +string_b_match = "string_b" +string_b_unmatch = "string_b" + +truthy_int_match = 1 +truthy_int_unmatch = 1 +falsy_int_match = 0 +falsy_int_unmatch = 0 + +truthy_float_match = 1.0 +truthy_float_unmatch = 1.0 +falsy_float_match = 0.0 +falsy_float_unmatch = 0.0 diff --git a/tests/test_yaml/dict-falsy-values-expected.yaml b/tests/test_yaml/dict-falsy-values-expected.yaml new file mode 100644 index 00000000..4455bb19 --- /dev/null +++ b/tests/test_yaml/dict-falsy-values-expected.yaml @@ -0,0 +1,16 @@ +boolean_true_match: true +boolean_true_unmatch: true +boolean_false_match: false +boolean_false_unmatch: false +string_a_match: 'string_a' +string_a_unmatch: 'string_a' +string_b_match: 'string_b' +string_b_unmatch: 'string_b' +truthy_int_match: 1 +truthy_int_unmatch: 1 +falsy_int_match: 0 +falsy_int_unmatch: 0 +truthy_float_match: 1.0 +truthy_float_unmatch: 1.0 +falsy_float_match: 0.0 +falsy_float_unmatch: 0.0 From c08758a84f5853b8c3deaf8e28d235a141e974bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Mond=C3=A9jar=20Rubio?= Date: Fri, 27 May 2022 20:37:18 +0200 Subject: [PATCH 2/3] Add docstring --- tests/test_yaml.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_yaml.py b/tests/test_yaml.py index 817fd173..11e487f9 100644 --- a/tests/test_yaml.py +++ b/tests/test_yaml.py @@ -155,6 +155,7 @@ def test_maximum_two_level_nesting_on_lists_using_jmes_expression_as_list_key_fa def test_falsy_values_properly_reported(tmp_path, datadir): + """Test that falsy and truthy values are included in the report.""" filename = "foo/file.yaml" project = ProjectMock(tmp_path).save_file(filename, datadir / "dict-falsy-values-actual.yaml") project.style(datadir / "dict-falsy-values-desired.toml").api_check_then_fix( From 70b2d524d10368a37c5845f970518ef6d5f0dbba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Mond=C3=A9jar=20Rubio?= Date: Fri, 27 May 2022 20:38:26 +0200 Subject: [PATCH 3/3] Revert change --- tests/test_yaml.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_yaml.py b/tests/test_yaml.py index 11e487f9..e44084bb 100644 --- a/tests/test_yaml.py +++ b/tests/test_yaml.py @@ -121,6 +121,7 @@ def test_objects_are_compared_by_hash_on_list_of_dicts_and_new_ones_are_added(tm def test_maximum_two_level_nesting_on_lists_using_jmes_expression_as_list_key_fails(tmp_path, datadir): """Test a maximum of two-level nesting on lists. Using a JMES expression as a list key will fail. + Keys must have a maximum of 2 level for now: parent and nested keys. """ filename = "an/arbitrary/file.yaml"