1 # Copyright 2020 The Pigweed Authors
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 # use this file except in compliance with the License. You may obtain a copy of
7 # https://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations under
14 """Tests for pw_cli.envparse."""
19 import pw_cli.envparse as envparse
21 # pylint: disable=no-member
24 class ErrorError(Exception):
28 def error(value: str):
29 raise ErrorError('error!')
32 class TestEnvironmentParser(unittest.TestCase):
33 """Tests for envparse.EnvironmentParser."""
36 'PATH': '/bin:/usr/bin:/usr/local/bin',
41 self.parser = envparse.EnvironmentParser()
42 self.parser.add_var('PATH')
43 self.parser.add_var('FOO', type=int)
44 self.parser.add_var('BAR', type=bool)
45 self.parser.add_var('BAZ', type=float, default=math.pi)
46 self.parser.add_var('ReVeRsE', type=lambda s: s[::-1])
47 self.parser.add_var('INT', type=int)
48 self.parser.add_var('ERROR', type=error)
50 def test_string_value(self):
51 env = self.parser.parse_env(env=self.raw_env)
52 self.assertEqual(env.PATH, self.raw_env['PATH'])
54 def test_int_value(self):
55 env = self.parser.parse_env(env=self.raw_env)
56 self.assertEqual(env.FOO, 2020)
58 def test_custom_value(self):
59 env = self.parser.parse_env(env=self.raw_env)
60 self.assertEqual(env.ReVeRsE, 'deewgip')
62 def test_empty_value(self):
63 env = self.parser.parse_env(env=self.raw_env)
64 self.assertEqual(env.BAR, None)
66 def test_default_value(self):
67 env = self.parser.parse_env(env=self.raw_env)
68 self.assertEqual(env.BAZ, math.pi)
70 def test_unknown_key(self):
71 env = self.parser.parse_env(env=self.raw_env)
72 with self.assertRaises(AttributeError):
73 env.BBBBB # pylint: disable=pointless-statement
75 def test_bad_value(self):
76 raw_env = {**self.raw_env, 'INT': 'not an int'}
77 with self.assertRaises(envparse.EnvironmentValueError) as ctx:
78 self.parser.parse_env(env=raw_env)
80 self.assertEqual(ctx.exception.variable, 'INT')
81 self.assertIsInstance(ctx.exception.__cause__, ValueError)
83 def test_custom_exception(self):
84 raw_env = {**self.raw_env, 'ERROR': 'error'}
85 with self.assertRaises(envparse.EnvironmentValueError) as ctx:
86 self.parser.parse_env(env=raw_env)
88 self.assertEqual(ctx.exception.variable, 'ERROR')
89 self.assertIsInstance(ctx.exception.__cause__, ErrorError)
92 class TestEnvironmentParserWithPrefix(unittest.TestCase):
93 """Tests for envparse.EnvironmentParser using a prefix."""
102 def test_parse_unrecognized_variable(self):
103 parser = envparse.EnvironmentParser(prefix='PW_')
104 parser.add_var('PW_FOO')
105 parser.add_var('PW_BAR')
107 with self.assertRaises(ValueError):
108 parser.parse_env(env=self.raw_env)
110 def test_parse_unrecognized_but_allowed_suffix(self):
111 parser = envparse.EnvironmentParser(prefix='PW_')
112 parser.add_allowed_suffix('_ALLOWED_SUFFIX')
114 env = parser.parse_env(env={'PW_FOO_ALLOWED_SUFFIX': '001'})
115 self.assertEqual(env.PW_FOO_ALLOWED_SUFFIX, '001')
117 def test_parse_allowed_suffix_but_not_suffix(self):
118 parser = envparse.EnvironmentParser(prefix='PW_')
119 parser.add_allowed_suffix('_ALLOWED_SUFFIX')
121 with self.assertRaises(ValueError):
122 parser.parse_env(env={'PW_FOO_ALLOWED_SUFFIX_FOO': '001'})
124 def test_parse_ignore_unrecognized(self):
125 parser = envparse.EnvironmentParser(prefix='PW_',
126 error_on_unrecognized=False)
127 parser.add_var('PW_FOO')
128 parser.add_var('PW_BAR')
130 env = parser.parse_env(env=self.raw_env)
131 self.assertEqual(env.PW_FOO, self.raw_env['PW_FOO'])
132 self.assertEqual(env.PW_BAR, self.raw_env['PW_BAR'])
134 def test_add_var_without_prefix(self):
135 parser = envparse.EnvironmentParser(prefix='PW_')
136 with self.assertRaises(ValueError):
137 parser.add_var('FOO')
140 class TestStrictBool(unittest.TestCase):
141 """Tests for envparse.strict_bool."""
143 self.good_bools = ['true', '1', 'TRUE', 'tRuE']
145 '', 'false', '0', 'foo', '2', '999', 'ok', 'yes', 'no'
148 def test_good_bools(self):
150 all(envparse.strict_bool(val) for val in self.good_bools))
152 def test_bad_bools(self):
154 any(envparse.strict_bool(val) for val in self.bad_bools))
157 if __name__ == '__main__':