Example #1
0
 def test_clean_condition_empty_column_is_none(self):
     self.assertIsNone(
         self._call_clean_value(
             ParamSchema.Condition(),
             {
                 "operation": "text_is",
                 "column": "",
                 "value": "",
                 "isCaseSensitive": False,
                 "isRegex": False,
             },
             input_table_columns=[NUMBER("A")],
         ))
     # And test it in the context of a broader and/or
     self.assertIsNone(
         self._call_clean_value(
             ParamSchema.Condition(),
             {
                 "operation":
                 "and",
                 "conditions": [{
                     "operation":
                     "or",
                     "conditions": [{
                         "operation": "text_is",
                         "column": "",
                         "value": "",
                         "isCaseSensitive": False,
                         "isRegex": False,
                     }],
                 }],
             },
             input_table_columns=[NUMBER("A")],
         ))
Example #2
0
 def test_clean_condition_and_or_simplify(self):
     self.assertEqual(
         self._call_clean_value(
             ParamSchema.Condition(),
             {
                 "operation":
                 "and",
                 "conditions": [
                     {
                         "operation":
                         "or",
                         "conditions": [
                             {
                                 "operation": "cell_is_blank",
                                 "column": "A",
                                 "value": "",
                                 "isCaseSensitive": False,
                                 "isRegex": False,
                             },
                         ],
                     },
                 ],
             },
             input_table_columns=[NUMBER("A")],
         ),
         {
             "operation": "cell_is_blank",
             "column": "A",
         },
     )
    def test_validate_not_2_levels(self):
        comparison = {
            "operation": "text_is",
            "column": "A",
            "value": "x",
            "isCaseSensitive": True,
            "isRegex": False,
        }

        # level 0
        with pytest.raises(ValueError):
            S.Condition().validate(comparison)

        # level 1
        with pytest.raises(ValueError):
            S.Condition().validate({"operation": "and", "conditions": [comparison]})

        # level 2 is okay
        S.Condition().validate(
            {
                "operation": "and",
                "conditions": [{"operation": "or", "conditions": [comparison]}],
            }
        )

        # level 3
        with pytest.raises(ValueError):
            S.Condition().validate(
                {
                    "operation": "and",
                    "conditions": [
                        {
                            "operation": "or",
                            "conditions": [
                                {"operation": "and", "conditions": [comparison]}
                            ],
                        }
                    ],
                }
            )
Example #4
0
 def test_clean_condition_missing_column_is_none(self):
     self.assertIsNone(
         self._call_clean_value(
             ParamSchema.Condition(),
             {
                 "operation": "text_is",
                 "column": "B",
                 "value": "",
                 "isCaseSensitive": False,
                 "isRegex": False,
             },
             input_table_columns=[NUMBER("A")],
         ))
    def test_validate_missing_key(self):
        comparison = {
            "operation": "text_is",
            "column": "A",
            "value": "x",
            "isCaseSensitive": True,
        }

        with pytest.raises(ValueError):
            S.Condition().validate(
                {
                    "operation": "and",
                    "conditions": [{"operation": "or", "conditions": [comparison]}],
                }
            )
Example #6
0
 def test_clean_condition_empty_and_and_or_are_none(self):
     self.assertEqual(
         self._call_clean_value(
             ParamSchema.Condition(),
             {
                 "operation": "and",
                 "conditions": [{
                     "operation": "or",
                     "conditions": []
                 }],
             },
             input_table_columns=[NUMBER("A")],
         ),
         None,
     )
Example #7
0
    def test_clean_condition_number_wrong_value(self):
        with self.assertRaises(PromptingError) as cm:
            self._call_clean_value(
                ParamSchema.Condition(),
                {
                    "operation": "number_is",
                    "column": "A",
                    "value": "bad",
                    "isCaseSensitive": False,
                    "isRegex": False,
                },
                input_table_columns=[NUMBER("A")],
            )

        self.assertEqual(cm.exception.errors,
                         [PromptingError.CannotCoerceValueToNumber("bad")])
    def test_validate_empty_operation_is_okay(self):
        # The UI lets users select nothing. We can't stop them.
        comparison = {
            "operation": "",
            "column": "A",
            "value": "x",
            "isCaseSensitive": True,
            "isRegex": False,
        }

        S.Condition().validate(
            {
                "operation": "and",
                "conditions": [{"operation": "or", "conditions": [comparison]}],
            }
        )
    def test_validate_condition_value_wrong_type(self):
        comparison = {
            "operation": "text_is",
            "column": "A",
            "value": 312,
            "isCaseSensitive": True,
            "isRegex": False,
        }

        with pytest.raises(ValueError):
            S.Condition().validate(
                {
                    "operation": "and",
                    "conditions": [{"operation": "or", "conditions": [comparison]}],
                }
            )
Example #10
0
    def test_validate_no_such_operation(self):
        comparison = {
            "operation": "text_is_blargy",
            "column": "A",
            "value": "x",
            "isCaseSensitive": True,
            "isRegex": False,
        }

        with pytest.raises(ValueError):
            S.Condition().validate(
                {
                    "operation": "and",
                    "conditions": [{"operation": "or", "conditions": [comparison]}],
                }
            )
Example #11
0
    def test_clean_condition_not_with_subclause_error(self):
        with self.assertRaises(PromptingError) as cm:
            self._call_clean_value(
                ParamSchema.Condition(),
                {
                    "operation": "text_is",
                    "column": "A",
                    "value": "",
                    "isCaseSensitive": False,
                    "isRegex": False,
                },
                input_table_columns=[NUMBER("A")],
            )

        self.assertEqual(
            cm.exception.errors,
            [PromptingError.WrongColumnType(["A"], None, frozenset({"text"}))],
        )
Example #12
0
 def test_clean_condition_untyped(self):
     self.assertEqual(
         self._call_clean_value(
             ParamSchema.Condition(),
             {
                 "operation": "cell_is_blank",
                 "column": "A",
                 "value": "2020-11-01",
                 "isCaseSensitive": True,
                 "isRegex": False,
             },
             input_table_columns=[NUMBER("A")],
         ),
         {
             "operation": "cell_is_blank",
             "column": "A",
         },
     )
Example #13
0
 def test_clean_condition_timestamp_happy_path(self):
     self.assertEqual(
         self._call_clean_value(
             ParamSchema.Condition(),
             {
                 "operation": "timestamp_is_greater_than",
                 "column": "A",
                 "value": "2020-11-01",
                 "isCaseSensitive": False,
                 "isRegex": False,
             },
             input_table_columns=[TIMESTAMP("A")],
         ),
         {
             "operation": "timestamp_is_greater_than",
             "column": "A",
             "value": "2020-11-01",
         },
     )
Example #14
0
 def test_clean_condition_number_happy_path(self):
     self.assertEqual(
         self._call_clean_value(
             ParamSchema.Condition(),
             {
                 "operation": "number_is",
                 "column": "A",
                 "value": "1",
                 "isCaseSensitive": False,
                 "isRegex": False,
             },
             input_table_columns=[NUMBER("A")],
         ),
         {
             "operation": "number_is",
             "column": "A",
             "value": 1,
         },
     )
Example #15
0
    def test_clean_condition_timestamp_wrong_value(self):
        with self.assertRaises(PromptingError) as cm:
            self._call_clean_value(
                ParamSchema.Condition(),
                {
                    "operation": "timestamp_is_greater_than",
                    "column": "A",
                    "value": "Yesterday",
                    "isCaseSensitive": False,
                    "isRegex": False,
                },
                input_table_columns=[TIMESTAMP("A")],
            )

        self.assertEqual(
            cm.exception.errors,
            [
                PromptingError.CannotCoerceValueToTimestamp("Yesterday"),
            ],
        )
Example #16
0
 def test_clean_condition_text_happy_path(self):
     self.assertEqual(
         self._call_clean_value(
             ParamSchema.Condition(),
             {
                 "operation": "text_is",
                 "column": "A",
                 "value": "a",
                 "isCaseSensitive": False,
                 "isRegex": False,
             },
             input_table_columns=[TEXT("A")],
         ),
         {
             "operation": "text_is",
             "column": "A",
             "value": "a",
             "isCaseSensitive": False,
             "isRegex": False,
         },
     )
Example #17
0
    def test_clean_condition_number_wrong_column_type(self):
        with self.assertRaises(PromptingError) as cm:
            self._call_clean_value(
                ParamSchema.Condition(),
                {
                    "operation": "number_is",
                    "column": "A",
                    "value": "1",
                    "isCaseSensitive": False,
                    "isRegex": False,
                },
                input_table_columns=[TEXT("A")],
            )

        self.assertEqual(
            cm.exception.errors,
            [
                PromptingError.WrongColumnType(["A"], "text",
                                               frozenset({"number"}))
            ],
        )
Example #18
0
    def test_clean_condition_timestamp_wrong_column_type(self):
        with self.assertRaises(PromptingError) as cm:
            self._call_clean_value(
                ParamSchema.Condition(),
                {
                    "operation": "timestamp_is_greater_than",
                    "column": "A",
                    "value": "2020-01-01T00:00Z",
                    "isCaseSensitive": False,
                    "isRegex": False,
                },
                input_table_columns=[NUMBER("A")],
            )

        self.assertEqual(
            cm.exception.errors,
            [
                PromptingError.WrongColumnType(
                    ["A"], "number", frozenset({"date", "timestamp"})),
            ],
        )
Example #19
0
def test_param_schema_includes_empty_tuples():
    # Bug on 2021-04-21: empty NamedTuple ParamSchema classes evaluate to
    # False; but they should still be included in the param_schema.
    spec = load_spec(
        dict(
            id_name="x",
            name="x",
            category="Clean",
            parameters=[
                dict(id_name="timezone", name="timezone", type="timezone"),
                dict(id_name="tab", name="tab", type="tab"),
                dict(id_name="condition", type="condition"),
            ],
        )
    )

    assert spec.param_schema == ParamSchema.Dict(
        {
            "timezone": ParamSchema.Timezone(),
            "tab": ParamSchema.Tab(),
            "condition": ParamSchema.Condition(),
        }
    )
Example #20
0
 def test_default(self):
     assert S.Condition().default == {"operation": "and", "conditions": []}
Example #21
0
 def test_validate_non_dict(self):
     with pytest.raises(ValueError):
         S.Condition().validate([])
Example #22
0
 def test_validate_missing_conditions(self):
     with pytest.raises(ValueError):
         S.Condition().validate({"operation": "and", "condition": []})
Example #23
0
 def test_validate_conditions_not_list(self):
     with pytest.raises(ValueError):
         S.Condition().validate({"operation": "and", "conditions": "hi"})
Example #24
0
 def test_validate_and_with_extra_property(self):
     with pytest.raises(ValueError):
         S.Condition().validate({"operation": "and", "conditions": [], "foo": "bar"})