|
18 | 18 | import pandas as pd |
19 | 19 | import pyomo.environ as pyomo_env |
20 | 20 | from runtime.optimize.local import generate_model_with_data_frame, solve_model |
21 | | -from runtime.optimize.model_generation import \ |
22 | | - generate_objective_and_constraint_expression |
| 21 | +from runtime.optimize.model_generation import ( |
| 22 | + IDENTIFIER_REGEX, assert_are_valid_tokens, |
| 23 | + generate_objective_and_constraint_expression) |
| 24 | + |
| 25 | + |
| 26 | +class TestAssertValidTokens(unittest.TestCase): |
| 27 | + def is_identifier(self, token): |
| 28 | + return IDENTIFIER_REGEX.fullmatch(token) is not None |
| 29 | + |
| 30 | + def test_is_identifier(self): |
| 31 | + tokens = ['a', '_', 'a123', '__', '_123'] |
| 32 | + for t in tokens: |
| 33 | + self.assertTrue(self.is_identifier(t)) |
| 34 | + |
| 35 | + tokens = ['1', '123_', '3def'] |
| 36 | + for t in tokens: |
| 37 | + self.assertFalse(self.is_identifier(t)) |
| 38 | + |
| 39 | + def test_assert_valid_tokens(self): |
| 40 | + tokens = ['SUM', '(', 'finishing', '*', 'product', ')', '<=', '100'] |
| 41 | + |
| 42 | + # valid expression |
| 43 | + assert_are_valid_tokens(columns=['finishing', 'product'], |
| 44 | + tokens=tokens, |
| 45 | + result_value_name='product') |
| 46 | + |
| 47 | + # invalid group_by |
| 48 | + with self.assertRaises(AssertionError): |
| 49 | + assert_are_valid_tokens(columns=['finishing', 'product'], |
| 50 | + tokens=tokens, |
| 51 | + result_value_name='product', |
| 52 | + group_by='invalid_group_by') |
| 53 | + |
| 54 | + # tokens = None |
| 55 | + with self.assertRaises(AssertionError): |
| 56 | + assert_are_valid_tokens(columns=['finishing', 'product'], |
| 57 | + tokens=None, |
| 58 | + result_value_name='product') |
| 59 | + |
| 60 | + # tokens = [] |
| 61 | + with self.assertRaises(AssertionError): |
| 62 | + assert_are_valid_tokens(columns=['finishing', 'product'], |
| 63 | + tokens=[], |
| 64 | + result_value_name='product') |
| 65 | + |
| 66 | + # tokens not inside columns |
| 67 | + tokens = [ |
| 68 | + 'SUM', '(', 'finishing', '*', 'invalid_token', ')', '<=', '100' |
| 69 | + ] |
| 70 | + with self.assertRaises(AssertionError): |
| 71 | + assert_are_valid_tokens(columns=['finishing', 'product'], |
| 72 | + tokens=tokens, |
| 73 | + result_value_name='product') |
| 74 | + |
| 75 | + # tokens not inside columns but equal to result_value_name |
| 76 | + # ignore cases |
| 77 | + tokens = [ |
| 78 | + 'SUM', '(', 'FinisHing', '*', 'pRoducT_VaLue', ')', '<=', '100' |
| 79 | + ] |
| 80 | + assert_are_valid_tokens(columns=['finishing', 'product'], |
| 81 | + tokens=tokens, |
| 82 | + result_value_name='product_value') |
23 | 83 |
|
24 | 84 |
|
25 | 85 | class TestModelGenerationBase(unittest.TestCase): |
@@ -72,7 +132,7 @@ def replace_objective_token(self, objective, old, new): |
72 | 132 |
|
73 | 133 | def replace_constraint_token(self, constraint, old, new): |
74 | 134 | def replace_one_constraint(c): |
75 | | - c = copy.copy(c) |
| 135 | + c = copy.deepcopy(c) |
76 | 136 | for i, token in enumerate(c["tokens"]): |
77 | 137 | if token == old: |
78 | 138 | c["tokens"][i] = new |
|
0 commit comments