]> mj.ucw.cz Git - moe.git/blob - t/moe/conftest.py
Sanitize by adding newlines detween defs
[moe.git] / t / moe / conftest.py
1 import moe.conf as conf
2 from moe.confparser import *
3 import logging as log
4 import unittest
5
6 class TestConfig(unittest.TestCase):
7
8   def setUp(s):
9     s.t = conf.ConfigTree()    
10
11   def parse(s, string, level=0, fname='test'):
12     c=ConfigParser(string, s.t, fname, level)
13     ops = c.parse()
14     c.p_WS()
15     assert c.eof()
16     return ops
17
18   def val(s, varname):
19     return s.t.lookup(varname, create=False).value()
20
21   def eqparse(s, string, *args, **kwargs):
22     return [(i[0], i[1].operation) for i in s.parse(string, *args, **kwargs)]
23
24
25 class TestParser(TestConfig):
26   s1 = r"""a="1";z{b='2';w{S.Tr_an-g.e='""'}};c.d='\n';e="{a}{b}";e+='{c.d}';a+="\"\n\{\}";f+='Z{a.b}'"""
27   s2 = '\t\n \n ' + s1.replace('=', '= \n ').replace(';', '\t \n\t \n ').replace('+=',' \n += ') + '\n\n '
28
29   def test_noWS(s):
30     assert len(s.parse(s.s1)) == 8
31
32   def test_noWS_COMMENT(s):
33     assert s.eqparse(s.s1+'#COMMENT') == s.eqparse(s.s1+'#') == s.eqparse(s.s1+'#\n') == s.eqparse(s.s1+'\n#')
34
35   def test_manyWS(s):
36     assert s.eqparse(s.s2) == s.eqparse(s.s1)
37
38   def test_manyWS_COMMENT(s):
39     assert s.eqparse(s.s2.replace('\n',' #COMMENT \n')) == s.eqparse(s.s2.replace('\n','#\n')) == s.eqparse(s.s1)
40
41   def test_empty(s):
42     assert s.eqparse('') == s.eqparse('\n') == s.eqparse('') == s.eqparse('a{}') == \
43       s.eqparse('a.b.c{if ""==\'\' {d.e{\n\n#Nothing\n}} }') == []
44
45   def test_syntax_errors(s):
46     s.assertRaises(ConfigSyntaxError, s.parse, "a=#")
47     s.assertRaises(ConfigSyntaxError, s.parse, "a='\"")
48     s.assertRaises(ConfigSyntaxError, s.parse, 'a="{a@b}"')
49     s.assertRaises(ConfigSyntaxError, s.parse, 'a="A{A"')
50
51   def test_error_location(s):
52     try: s.parse('\t \n  \n  { \n \n ')
53     except ConfigSyntaxError, e:
54       assert e.line == 3 and e.column in range(2,4)
55
56   def test_quoting(s):
57     s.parse(' a="\\"\\{a$b\\}\'\n\n\'{z}" ')
58     assert s.t.lookup('z', create=False)
59     # No escaping in '-string 
60     s.assertRaises(ConfigSyntaxError, s.parse, " a='\"\\'\n\n' ")
61     # Variable should not be created
62     s.parse(" a='{z2}' ")
63     s.assertRaises(conf.ConfigError, s.t.lookup, 'z2', create=False)
64
65   def test_conditions(s):
66     s.assertRaises(ConfigSyntaxError, s.parse, "if '{a}'=='{b}' and ''!='' {}")
67     s.parse('if ((#C\n (\n (not not not""!="")\n#C\n)\t ) ) {}')
68     s.parse('if (""=="" and not (not not ""!="" or ""=="")){}')
69     s.parse('if(""==""){a{if(""==""){if(""==""){b{if(""==""){if(""==""){}}}}}}}')
70     s.assertRaises(ConfigSyntaxError, s.parse, "if notnot'{a}'=='{b}' {}")
71     s.assertRaises(ConfigSyntaxError, s.parse, "if ('{a}'=='{b}' not and ''!='') {}")
72     s.assertRaises(ConfigSyntaxError, s.parse, "if ('{a}'=='{b}' ornot ''!='') {}")
73
74
75 class TestConfigEval(TestConfig):
76
77   def test_ops(s):
78     s.parse('c+="-C_APP"', level=20)
79     s.parse('a="A"; b="{a}-B"; c="C1-{b}-C2"; a+="FOO"; a="AA"')
80     assert s.val('c') == 'C1-AA-B-C2-C_APP'
81     s.parse('b+="-A:\{{a}\}";a+="A"', level=10)
82     assert s.val('c') == 'C1-AAA-B-A:{AAA}-C2-C_APP'
83
84   def test_nested(s):
85     s.parse('a="0"; b{a="1"; b{a="2"; b{a="3"; b{a="4"; b{a="5"}}}}}')
86     assert s.val('b.b.b.a') == '3'
87     s.parse('b.b{b.b{b.a="5MOD"}}')
88     assert s.val('b.b.b.b.b.a') == '5MOD'
89
90   def test_escape_chars(s):
91     s.parse(r"""a='{a}\\\\#\n'; b="{a}'\"\{\}"; c='\'; c+="\{{b}\}";""")
92     assert s.val('c') == r"""\{{a}\\\\#\n'"{}}"""
93   ts = 'a="A:"; if "{c1}"=="1" {a+="C1"; b="B"; if ("{c2a}"=="1" or not "{c2b}"=="1") { a+="C2"; '\
94     'if ("{c3a}"=="1" and "{c3b}"=="1") { a+="C3" }}}'
95
96   def test_cond_chain(s):
97     s.parse(s.ts)
98     s.parse('c1="1"; c2="0"')
99     # b should have determined value, a should not (since c3a is undefined)
100     s.assertRaises(conf.UndefinedError, s.val, 'a')
101     assert s.val('b') == 'B'
102     s.parse('c1="0"')
103     # now b should be undefined
104     s.assertRaises(conf.UndefinedError, s.val, 'b')
105     # Normal evaluation
106     s.parse('c1="1"; c2a="1"; c2b="0"; c3a="0"')
107     assert s.val('a') == 'A:C1C2'
108     s.parse('c3a="1"; c3b="1"; c2b="1"')
109     assert s.val('a') == 'A:C1C2C3'
110     # tests condition invalidating 
111     s.parse('c2a+="0"')
112     assert s.val('a') == 'A:C1'
113
114   def test_cond_eager(s):
115     s.parse(s.ts)
116     # undefined c2b and c3a should not be evaluated 
117     s.parse('c1="1"; c2a="1"; c3a="0"')
118     assert s.val('a') == 'A:C1C2'
119     # but now c3b should be evaluated 
120     s.parse('c1="1"; c2a="1"; c3a="1"')
121     s.assertRaises(conf.UndefinedError, s.val, 'a')
122     s.parse('c1="1"; c2a="1"; c3b="1"')
123     assert s.val('a') == 'A:C1C2C3'
124
125   def test_undef(s):
126     s.assertRaises(conf.UndefinedError, s.val, 'a')
127     s.parse('a="{b}"')
128     s.assertRaises(conf.UndefinedError, s.val, 'a')
129     s.parse('b+="1"')
130     s.assertRaises(conf.UndefinedError, s.val, 'b')
131
132   def test_loopy_def(s):
133     s.parse('a="A"; a+="{a}"')
134     s.assertRaises(conf.CyclicConfigError, s.val, 'a')
135     s.parse('b="{c}"; c="{b}"')
136     s.assertRaises(conf.CyclicConfigError, s.val, 'b')
137
138   def test_varname(s):
139     s.assertRaises(conf.VariableNameError, s.val, 'b/c')
140     s.assertRaises(conf.VariableNameError, s.val, '.b.c')
141     s.assertRaises(conf.VariableNameError, s.val, 'b.c.')
142     s.assertRaises(conf.VariableNameError, s.val, 'b..c')
143
144   def test_remove(s):
145     l = s.parse('a="A1"; b="B1"; if "{cond}"=="1" {a+="A2"; b+="B2"}; a+="A3"; b+="B3"; cond="1"')
146     assert s.val('a') == 'A1A2A3'
147     assert s.val('b') == 'B1B2B3'
148     # remove b+="B2"
149     s.t.lookup('b').remove_operation(l[3][1])
150     assert s.val('a') == 'A1A2A3'
151     assert s.val('b') == 'B1B3'
152     # are the dependencies still handled properly? 
153     s.parse('cond+="-invalidated"')
154     assert s.val('a') == 'A1A3'
155     s.parse('cond="1"')
156     assert s.val('a') == 'A1A2A3'
157
158 # TODO: fixing, fail on 1st April
159 # TODO: coverage
160
161
162 if __name__ == '__main__':
163   log.getLogger().setLevel(log.WARN)
164   #log.getLogger().setLevel(log.DEBUG)
165   unittest.main()
166
167 # TODO: log.info('maxdepth: %d', conf.debug_maxdepth)
168