1# Copyright (c) 2004 Divmod. 2# See LICENSE for details. 3 4 5from nevow import tags, flat, testutil, context, loaders, stan 6 7from nevow.inevow import IQ 8 9 10simple = tags.html[tags.div(pattern="foo")] 11tooMany = tags.html[tags.div(pattern="foo"), tags.div(pattern="foo")] 12notEnough = tags.html[tags.div[tags.span["Hello"]]] 13 14 15class OnePatternTestCase(testutil.TestCase): 16 """ 17 Test various C{IQ.onePattern} implementations. 18 """ 19 _patternDiv = tags.div(pattern="foo") 20 21 _simpleStan = tags.html[_patternDiv] 22 23 _simpleSlot = tags.slot('slotname')[_patternDiv] 24 25 _tooManyPatternsSiblingStan = tags.html[ 26 tags.div(pattern="foo"), 27 tags.div(pattern="foo")] 28 29 _manyPatternsLinealStan = tags.html(pattern="foo")[ 30 tags.div(pattern="foo"), 31 "extra content"] 32 33 34 def _testQuery(self, container, expected): 35 pattern = IQ(container).onePattern('foo') 36 37 # The pattern node has had its pattern special removed - put it back, 38 # so we can perform a comparison 39 self.assertEqual(pattern.pattern, None) 40 pattern.pattern = 'foo' 41 42 self.assertEqual(str(pattern), str(expected)) 43 44 45 def test_tagQuery(self): 46 return self._testQuery( 47 self._simpleStan, self._patternDiv) 48 49 50 def test_contextQuery(self): 51 return self._testQuery( 52 context.WovenContext(tag=self._simpleStan), 53 self._patternDiv) 54 55 56 def test_listQuery(self): 57 return self._testQuery( 58 flat.precompile(self._simpleStan), 59 self._patternDiv) 60 61 62 def test_loaderQuery(self): 63 return self._testQuery( 64 loaders.stan(self._simpleStan), 65 self._patternDiv) 66 67 68 def test_slotQuery(self): 69 return self._testQuery( 70 self._simpleSlot, 71 self._patternDiv) 72 73 74 def test_precompiledSlotQuery(self): 75 return self._testQuery( 76 flat.precompile(self._simpleSlot), 77 self._patternDiv) 78 79 80 def _testTooManyPatterns(self, obj): 81 """ 82 Test that the L{IQ} adapter for C{obj} provides a L{onePattern} method 83 which raises L{stan.TooManyNodes} if passed a pattern name for which 84 there are multiple pattern nodes. 85 """ 86 self.assertRaises(stan.TooManyNodes, IQ(obj).onePattern, 'foo') 87 88 89 def test_stanTooManySiblingPatterns(self): 90 """ 91 Test that a Tag with children with the same pattern name causes 92 onePattern to raise L{TooManyNodes}. 93 """ 94 return self._testTooManyPatterns(self._tooManyPatternsSiblingStan) 95 96 97 def test_contextTooManySiblingPatterns(self): 98 """ 99 Like L{test_stanTooManySiblingPatterns} but for a WovenContext. 100 """ 101 return self._testTooManyPatterns( 102 context.WovenContext(tag=self._tooManyPatternsSiblingStan)) 103 104 105 def test_listTooManySiblingPatterns(self): 106 """ 107 Like L{test_stanTooManySiblingPatterns} but for a list. 108 """ 109 return self._testTooManyPatterns([self._tooManyPatternsSiblingStan]) 110 111 112 def test_precompiledTooManySiblingPatterns(self): 113 """ 114 Like L{test_stanTooManySiblingPatterns} but for a precompiled document. 115 """ 116 P = flat.precompile(self._tooManyPatternsSiblingStan) 117 return self._testTooManyPatterns(P) 118 119 120 def test_loaderTooManySiblingPatterns(self): 121 """ 122 Like L{test_stanTooManySiblingPatterns} but for a loader. 123 """ 124 return self._testTooManyPatterns(loaders.stan(self._tooManyPatternsSiblingStan)) 125 126 127 def test_stanMultipleLinealPatterns(self): 128 """ 129 Test that calling onePattern a Tag with a pattern and a child with the 130 same pattern 131 """ 132 return self._testQuery( 133 self._manyPatternsLinealStan, 134 self._manyPatternsLinealStan) 135 136 137 def test_contextMultipleLinealPatterns(self): 138 return self._testQuery( 139 context.WovenContext(tag=self._manyPatternsLinealStan), 140 self._manyPatternsLinealStan) 141 142 143 def test_listMultipleLinealPatterns(self): 144 return self._testQuery( 145 [self._manyPatternsLinealStan], 146 self._manyPatternsLinealStan) 147 148 149 def test_precompiledMultipleLinealPatterns(self): 150 P = flat.precompile(self._manyPatternsLinealStan) 151 return self._testQuery( 152 P, 153 P[0].tag) 154 155 156 def test_loaderMultipleLinealPatterns(self): 157 return self._testQuery( 158 loaders.stan(self._manyPatternsLinealStan), 159 loaders.stan(self._manyPatternsLinealStan).load()[0].tag) 160 161 162 def test_tagNotEnough(self): 163 self.assertRaises(stan.NodeNotFound, IQ(notEnough).onePattern, 'foo') 164 165 def test_contextNotEnough(self): 166 self.assertRaises( 167 stan.NodeNotFound, 168 IQ(context.WovenContext(tag=notEnough)).onePattern, 'foo') 169 170 def test_contextTagQuery(self): 171 T = simple.clone(deep=False) 172 T.pattern = "outer" 173 C = context.WovenContext(tag=T) 174 new = IQ(C).onePattern('outer') 175 self.assertEquals(new.tagName, 'html') 176 177 def test_listNotEnough(self): 178 P = flat.precompile(notEnough) 179 self.assertRaises(stan.NodeNotFound, IQ(P).onePattern, 'foo') 180 181 def test_loaderNotEnough(self): 182 L = loaders.stan(notEnough) 183 self.assertRaises(stan.NodeNotFound, IQ(L).onePattern, 'foo') 184 185 186multiple = tags.html[tags.div(pattern="foo", bar="one"), tags.span(pattern="foo", bar="two")] 187 188 189class TestAll(testutil.TestCase): 190 def verify(self, them): 191 them = list(them) 192 self.assertEquals(len(them), 2) 193 self.assertEquals(them[0].tagName, 'div') 194 self.assertEquals(them[1].tagName, 'span') 195 self.assertEquals(them[0].attributes['bar'], 'one') 196 self.assertEquals(them[1].attributes['bar'], 'two') 197 198 def testTagPatterns(self): 199 self.verify( 200 IQ(multiple).allPatterns('foo')) 201 202 def testContextPatterns(self): 203 self.verify( 204 IQ(context.WovenContext(tag=multiple)).allPatterns('foo')) 205 206 def testListPatterns(self): 207 self.verify( 208 IQ(flat.precompile(multiple)).allPatterns('foo')) 209 210 def testLoaderPatterns(self): 211 self.verify( 212 IQ(loaders.stan(multiple)).allPatterns('foo')) 213 214 215class TestGenerator(testutil.TestCase): 216 def verify(self, it): 217 one = it(color="red") 218 two = it(color="blue") 219 three = it(color="green") 220 four = it(color="orange") 221 self.assertEquals(one.attributes['color'], 'red') 222 self.assertEquals(one.attributes['bar'], 'one') 223 self.assertEquals(two.attributes['color'], 'blue') 224 self.assertEquals(two.attributes['bar'], 'two') 225 self.assertEquals(three.attributes['color'], 'green') 226 self.assertEquals(three.attributes['bar'], 'one') 227 self.assertEquals(four.attributes['color'], 'orange') 228 self.assertEquals(four.attributes['bar'], 'two') 229 230 def testTagGenerators(self): 231 self.verify( 232 IQ(multiple).patternGenerator('foo')) 233 234 def testTagMissing(self): 235 self.assertRaises(stan.NodeNotFound, IQ(notEnough).patternGenerator, 'foo') 236 237 def testContextGenerators(self): 238 self.verify( 239 IQ(context.WovenContext(tag=multiple)).patternGenerator('foo')) 240 241 def testContextMissing(self): 242 self.assertRaises(stan.NodeNotFound, IQ(context.WovenContext(tag=notEnough)).patternGenerator, 'foo') 243 244 def testListGenerators(self): 245 self.verify( 246 IQ(flat.precompile(multiple)).patternGenerator('foo')) 247 248 def testListMissing(self): 249 self.assertRaises(stan.NodeNotFound, IQ(flat.precompile(notEnough)).patternGenerator, 'foo') 250 251 def testLoaderGenerators(self): 252 self.verify( 253 IQ(loaders.stan(multiple)).patternGenerator('foo')) 254 255 def testTagMissing(self): 256 self.assertRaises(stan.NodeNotFound, IQ(loaders.stan(notEnough)).patternGenerator, 'foo') 257 258 def testClonableDefault(self): 259 orig = tags.p["Hello"] 260 gen = IQ(flat.precompile(notEnough)).patternGenerator('foo', orig) 261 new = gen.next() 262 self.assertEquals(new.tagName, 'p') 263 self.assertNotIdentical(orig, new) 264 265 def testNonClonableDefault(self): 266 gen = IQ(flat.precompile(notEnough)).patternGenerator('foo', 'bar') 267 new = gen.next() 268 self.assertEquals(new, 'bar') 269 270 def testXmlMissing(self): 271 self.assertRaises(stan.NodeNotFound, IQ(stan.xml('<html>hello</html>')).patternGenerator, 'foo') 272 273 274 def test_listOfTagPatternGenerator(self): 275 """ 276 Querying a list which contains a tag for patterns gives back the tag if 277 the tag has a matching pattern special. 278 """ 279 patterns = IQ([tags.div(pattern="foo", bar="baz")]).patternGenerator("foo") 280 for i in xrange(3): 281 self.assertEqual(patterns.next().attributes['bar'], "baz") 282