~azzar1/unity/add-show-desktop-key

1294.2.5 by William Grant
Use nose.tools.raises in the error tests.
1
from nose.tools import assert_equal, raises
2
1294.2.66 by William Grant
Rename ivle.webapp.urls to ivle.webapp.routing.
3
from ivle.webapp.routing import (INF, InsufficientPathSegments, NoPath,
4
                                 NotFound, RouteConflict, Router, ROOT)
1294.2.1 by William Grant
Add an object-traversal-based router.
5
6
class Root(object):
7
    def __init__(self):
8
        self.subjects = {}
9
10
    def add_subject(self, subject):
11
        self.subjects[subject.name] = subject
12
13
class Subject(object):
14
    def __init__(self, name, code):
15
        self.name = name
16
        self.code = code
17
        self.offerings = {}
18
19
    def add_offering(self, offering):
20
        assert self.name == offering.subject.name
21
        self.offerings[(offering.year, offering.semester)] = offering
22
23
class Offering(object):
24
    def __init__(self, subject, year, semester):
25
        self.subject = subject
26
        self.year = year
27
        self.semester = semester
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
28
        self.projects = {}
29
30
    def add_project(self, project):
31
        assert project.offering is self
32
        self.projects[project.name] = project
1294.2.1 by William Grant
Add an object-traversal-based router.
33
1294.2.36 by William Grant
Replace the tests' OfferingProjects with OfferingFiles.
34
class OfferingFiles(object):
1294.2.22 by William Grant
Test named routes.
35
    def __init__(self, offering):
36
        self.offering = offering
37
1294.2.37 by William Grant
Test a route with infinitely many arguments.
38
class OfferingFile(object):
39
    def __init__(self, offeringfiles, path):
40
        self.offering = offeringfiles.offering
41
        self.path = path
42
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
43
class Project(object):
44
    def __init__(self, offering, name):
45
        self.offering = offering
46
        self.name = name
47
1294.2.37 by William Grant
Test a route with infinitely many arguments.
48
1294.2.1 by William Grant
Add an object-traversal-based router.
49
class View(object):
50
    def __init__(self, context):
51
        self.context = context
52
53
class RootIndex(View):
54
    pass
55
56
class SubjectIndex(View):
57
    pass
58
59
class SubjectEdit(View):
60
    pass
61
62
class OfferingIndex(View):
63
    pass
64
65
class OfferingEdit(View):
66
    pass
67
1294.2.2 by William Grant
Split out views from normal routes, and add a viewset concept.
68
class OfferingAPIIndex(View):
69
    pass
70
1294.2.36 by William Grant
Replace the tests' OfferingProjects with OfferingFiles.
71
class OfferingFilesIndex(View):
1294.2.35 by William Grant
Fix and expand tests to cover new NotFound cases.
72
    pass
73
1294.2.37 by William Grant
Test a route with infinitely many arguments.
74
class OfferingFileIndex(View):
75
    pass
76
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
77
class ProjectIndex(View):
78
    pass
79
1294.2.46 by William Grant
Add tests for default deep views.
80
class OfferingProjects(View):
81
    pass
82
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
83
class OfferingAddProject(View):
84
    pass
85
1294.2.1 by William Grant
Add an object-traversal-based router.
86
def root_to_subject(root, name):
1294.2.35 by William Grant
Fix and expand tests to cover new NotFound cases.
87
    return root.subjects.get(name)
1294.2.1 by William Grant
Add an object-traversal-based router.
88
89
def subject_to_offering(subject, year, semester):
1294.2.35 by William Grant
Fix and expand tests to cover new NotFound cases.
90
    return subject.offerings.get((int(year), int(semester)))
1294.2.1 by William Grant
Add an object-traversal-based router.
91
1294.2.36 by William Grant
Replace the tests' OfferingProjects with OfferingFiles.
92
def offering_to_files(offering):
93
    return OfferingFiles(offering)
1294.2.1 by William Grant
Add an object-traversal-based router.
94
1294.2.37 by William Grant
Test a route with infinitely many arguments.
95
def offering_files_to_file(offeringfiles, *path):
96
    return OfferingFile(offeringfiles, path)
97
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
98
def offering_to_project(offering, name):
99
    return offering.projects.get(name)
100
1294.2.1 by William Grant
Add an object-traversal-based router.
101
def subject_url(subject):
102
    return (ROOT, subject.name)
103
104
def offering_url(offering):
105
    return (offering.subject, (str(offering.year), str(offering.semester)))
106
1294.2.40 by William Grant
Test generation of URLs for named routes.
107
def offering_files_url(offeringfiles):
108
    return (offeringfiles.offering, '+files')
1294.2.22 by William Grant
Test named routes.
109
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
110
def project_url(project):
111
    return (project.offering, ('+projects', project.name))
1294.2.1 by William Grant
Add an object-traversal-based router.
112
113
class BaseTest(object):
114
    def setUp(self):
115
        r = Root()
116
        self.r = r
117
118
        # Give us some subjects...
119
        r.add_subject(Subject('info1', '600151'))
120
        r.add_subject(Subject('info2', '600152'))
121
        r.add_subject(Subject('info3', '600251'))
122
123
        # ... and some offerings.
124
        r.subjects['info1'].add_offering(Offering(self.r.subjects['info1'],
125
                                         2008, 1))
126
        r.subjects['info1'].add_offering(Offering(self.r.subjects['info1'],
127
                                         2008, 2))
128
        r.subjects['info1'].add_offering(Offering(self.r.subjects['info1'],
129
                                         2009, 1))
130
        r.subjects['info2'].add_offering(Offering(self.r.subjects['info2'],
131
                                         2008, 2))
132
        r.subjects['info2'].add_offering(Offering(self.r.subjects['info2'],
133
                                         2009, 1))
134
        r.subjects['info3'].add_offering(Offering(self.r.subjects['info3'],
135
                                         2009, 1))
136
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
137
        # A normal project...
138
        r.subjects['info1'].offerings[(2009, 1)].add_project(
139
            Project(r.subjects['info1'].offerings[(2009, 1)], 'p1')
140
            )
141
142
        # And one conflicting with a deep view, just to be nasty.
143
        r.subjects['info1'].offerings[(2009, 1)].add_project(
144
            Project(r.subjects['info1'].offerings[(2009, 1)], '+new')
145
            )
146
1294.2.1 by William Grant
Add an object-traversal-based router.
147
class TestResolution(BaseTest):
1294.2.10 by William Grant
Refactor resolution tests too.
148
    def setUp(self):
149
        super(TestResolution, self).setUp()
150
        self.rtr = Router(root=self.r, viewset='browser')
151
        self.rtr.add_set_switch('api', 'api')
152
        self.rtr.add_forward(Root, None, root_to_subject, 1)
153
        self.rtr.add_forward(Subject, None, subject_to_offering, 2)
1294.2.36 by William Grant
Replace the tests' OfferingProjects with OfferingFiles.
154
        self.rtr.add_forward(Offering, '+files', offering_to_files, 0)
1294.2.37 by William Grant
Test a route with infinitely many arguments.
155
        self.rtr.add_forward(OfferingFiles, None, offering_files_to_file, INF)
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
156
        self.rtr.add_forward(Offering, '+projects', offering_to_project, 1)
1294.2.10 by William Grant
Refactor resolution tests too.
157
        self.rtr.add_view(Subject, '+index', SubjectIndex, viewset='browser')
158
        self.rtr.add_view(Subject, '+edit', SubjectEdit, viewset='browser')
159
        self.rtr.add_view(Offering, '+index', OfferingIndex, viewset='browser')
160
        self.rtr.add_view(Offering, '+index', OfferingAPIIndex, viewset='api')
1294.2.36 by William Grant
Replace the tests' OfferingProjects with OfferingFiles.
161
        self.rtr.add_view(OfferingFiles, '+index', OfferingFilesIndex,
1294.2.35 by William Grant
Fix and expand tests to cover new NotFound cases.
162
                          viewset='browser')
1294.2.37 by William Grant
Test a route with infinitely many arguments.
163
        self.rtr.add_view(OfferingFile, '+index', OfferingFileIndex,
164
                          viewset='browser')
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
165
        self.rtr.add_view(Project, '+index', ProjectIndex, viewset='browser')
166
        self.rtr.add_view(Offering, ('+projects', '+new'), OfferingAddProject,
167
                          viewset='browser')
1294.2.46 by William Grant
Add tests for default deep views.
168
        self.rtr.add_view(Offering, ('+projects', '+index'), OfferingProjects,
169
                          viewset='browser')
1294.2.10 by William Grant
Refactor resolution tests too.
170
1294.2.23 by William Grant
Stop testing resolutions with views.
171
    def testOneRoute(self):
172
        assert_equal(self.rtr.resolve('/info1'),
173
                     (self.r.subjects['info1'], SubjectIndex, ())
174
                     )
175
        assert_equal(self.rtr.resolve('/info3'),
176
                     (self.r.subjects['info3'], SubjectIndex, ())
177
                     )
178
179
    def testTwoRoutes(self):
180
        assert_equal(self.rtr.resolve('/info1/2009/1'),
181
             (self.r.subjects['info1'].offerings[(2009, 1)], OfferingIndex, ())
182
             )
183
        assert_equal(self.rtr.resolve('/info2/2008/2'),
184
             (self.r.subjects['info2'].offerings[(2008, 2)], OfferingIndex, ())
185
             )
1294.2.10 by William Grant
Refactor resolution tests too.
186
1294.2.22 by William Grant
Test named routes.
187
    def testNamedRoute(self):
1294.2.36 by William Grant
Replace the tests' OfferingProjects with OfferingFiles.
188
        assert_equal(type(self.rtr.resolve('/info1/2009/1/+files')[0]),
189
                     OfferingFiles
1294.2.22 by William Grant
Test named routes.
190
                    )
1294.2.36 by William Grant
Replace the tests' OfferingProjects with OfferingFiles.
191
        assert_equal(self.rtr.resolve('/info1/2009/1/+files')[0].offering,
1294.2.22 by William Grant
Test named routes.
192
                     self.r.subjects['info1'].offerings[(2009, 1)]
193
                    )
194
1294.2.23 by William Grant
Stop testing resolutions with views.
195
    def testNonDefaultView(self):
1294.2.10 by William Grant
Refactor resolution tests too.
196
        assert_equal(self.rtr.resolve('/info1/+edit'),
1294.2.11 by William Grant
Revise generation and resolution tests to involve subpaths.
197
                     (self.r.subjects['info1'], SubjectEdit, ())
1294.2.10 by William Grant
Refactor resolution tests too.
198
                     )
1294.2.1 by William Grant
Add an object-traversal-based router.
199
1294.2.3 by William Grant
Add tests to complete coverage.
200
    def testDefaultView(self):
1294.2.10 by William Grant
Refactor resolution tests too.
201
        assert_equal(self.rtr.resolve('/info1'),
1294.2.11 by William Grant
Revise generation and resolution tests to involve subpaths.
202
                     (self.r.subjects['info1'], SubjectIndex, ())
203
                     )
204
205
    def testViewWithSubpath(self):
206
        assert_equal(self.rtr.resolve('/info1/+edit/foo/bar'),
1294.2.13 by William Grant
Fix view mistake in test.
207
                     (self.r.subjects['info1'], SubjectEdit, ('foo', 'bar'))
1294.2.10 by William Grant
Refactor resolution tests too.
208
                     )
209
1294.2.35 by William Grant
Fix and expand tests to cover new NotFound cases.
210
    def testNoDefaultView(self):
211
        try:
212
            self.rtr.default = 'not+index'
213
            self.rtr.resolve('/info1')
214
        except NotFound, e:
215
            assert_equal(e.args, (self.r.subjects['info1'], '+index', ()))
216
        except:
217
            raise
218
        else:
219
            raise AssertionError('did not raise NotFound')
220
        finally:
221
            self.rtr.default = '+index'
222
223
    def testMissingView(self):
224
        try:
225
            self.rtr.resolve('/info1/+foo')
226
        except NotFound, e:
227
            assert_equal(e.args, (self.r.subjects['info1'], '+foo', ()))
228
        except:
229
            raise
230
        else:
231
            raise AssertionError('did not raise NotFound')
232
1294.2.10 by William Grant
Refactor resolution tests too.
233
    def testViewSetSeparation(self):
1294.2.35 by William Grant
Fix and expand tests to cover new NotFound cases.
234
        try:
235
            self.rtr.resolve('/api/info1/+edit')
236
        except NotFound, e:
237
            assert_equal(e.args, (self.r.subjects['info1'], '+edit', ()))
238
        except:
239
            raise
240
        else:
241
            raise AssertionError('did not raise NotFound')
242
243
    def testRouteReturningNone(self):
244
        try:
245
            self.rtr.resolve('/info9/+index')
246
        except NotFound, e:
247
            assert_equal(e.args, (self.r, 'info9', ('+index',)))
248
        except:
249
            raise
250
        else:
251
            raise AssertionError('did not raise NotFound')
1294.2.10 by William Grant
Refactor resolution tests too.
252
1294.2.37 by William Grant
Test a route with infinitely many arguments.
253
    def testRouteWithInfinitelyManyArguments(self):
254
        o, v, sp = self.rtr.resolve('/info1/2009/1/+files/foo/bar/baz')
255
256
        assert_equal(type(o), OfferingFile)
257
        assert_equal(o.path, ('foo', 'bar', 'baz'))
258
        assert_equal(o.offering, self.r.subjects['info1'].offerings[(2009, 1)])
259
        assert_equal(v, OfferingFileIndex)
260
        assert_equal(sp, ())
261
1294.2.38 by William Grant
Test behaviour when a nonexistent route is specified.
262
    def testMissingRoute(self):
263
        try:
264
            self.rtr.resolve('/info1/2009/1/+foo')
265
        except NotFound, e:
266
            assert_equal(e.args, (
267
                self.r.subjects['info1'].offerings[(2009, 1)],
268
                '+foo',
269
                ()
270
                ))
271
        except:
272
            raise
273
        else:
274
            raise AssertionError('did not raise NotFound')
275
1294.2.10 by William Grant
Refactor resolution tests too.
276
    def testAlternateViewSetWithDefault(self):
277
        assert_equal(self.rtr.resolve('/info1/2009/1'),
1294.2.11 by William Grant
Revise generation and resolution tests to involve subpaths.
278
             (self.r.subjects['info1'].offerings[(2009, 1)], OfferingIndex, ())
279
             )
1294.2.2 by William Grant
Split out views from normal routes, and add a viewset concept.
280
1294.2.10 by William Grant
Refactor resolution tests too.
281
        assert_equal(self.rtr.resolve('/api/info1/2009/1'),
1294.2.11 by William Grant
Revise generation and resolution tests to involve subpaths.
282
          (self.r.subjects['info1'].offerings[(2009, 1)], OfferingAPIIndex, ())
283
          )
1294.2.3 by William Grant
Add tests to complete coverage.
284
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
285
    def testDeepView(self):
286
        assert_equal(self.rtr.resolve('/info1/2009/1/+projects/+new'),
287
             (self.r.subjects['info1'].offerings[(2009, 1)],
288
              OfferingAddProject, ())
289
             )
290
1294.2.46 by William Grant
Add tests for default deep views.
291
    def testDefaultDeepView(self):
292
        assert_equal(self.rtr.resolve('/info1/2009/1/+projects'),
293
             (self.r.subjects['info1'].offerings[(2009, 1)],
294
              OfferingProjects, ())
295
             )
296
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
297
    def testNamedRouteWithDeepView(self):
298
        assert_equal(self.rtr.resolve('/info1/2009/1/+projects/p1'),
299
             (self.r.subjects['info1'].offerings[(2009, 1)].projects['p1'],
300
              ProjectIndex, ())
301
             )
302
303
1294.2.1 by William Grant
Add an object-traversal-based router.
304
class TestGeneration(BaseTest):
1294.2.9 by William Grant
Refactor generation tests.
305
    def setUp(self):
306
        super(TestGeneration, self).setUp()
307
        self.rtr = Router(root=self.r, viewset='browser')
308
        self.rtr.add_set_switch('api', 'api')
309
        self.rtr.add_reverse(Subject, subject_url)
310
        self.rtr.add_reverse(Offering, offering_url)
1294.2.40 by William Grant
Test generation of URLs for named routes.
311
        self.rtr.add_reverse(OfferingFiles, offering_files_url)
1294.2.43 by William Grant
Test deep view generation.
312
        self.rtr.add_reverse(Project, project_url)
1294.2.9 by William Grant
Refactor generation tests.
313
        self.rtr.add_view(Subject, '+index', SubjectIndex, viewset='browser')
314
        self.rtr.add_view(Subject, '+edit', SubjectEdit, viewset='browser')
315
        self.rtr.add_view(Offering, '+index', OfferingIndex, viewset='browser')
316
        self.rtr.add_view(Offering, '+index', OfferingAPIIndex, viewset='api')
1294.2.43 by William Grant
Test deep view generation.
317
        self.rtr.add_view(Project, '+index', ProjectIndex, viewset='browser')
318
        self.rtr.add_view(Offering, ('+projects', '+new'), OfferingAddProject,
319
                          viewset='browser')
1294.2.46 by William Grant
Add tests for default deep views.
320
        self.rtr.add_view(Offering, ('+projects', '+index'), OfferingProjects,
321
                          viewset='browser')
1294.2.9 by William Grant
Refactor generation tests.
322
1294.2.1 by William Grant
Add an object-traversal-based router.
323
    def testOneLevel(self):
1294.2.9 by William Grant
Refactor generation tests.
324
        assert_equal(self.rtr.generate(self.r.subjects['info1']), '/info1')
1294.2.1 by William Grant
Add an object-traversal-based router.
325
326
    def testTwoLevel(self):
1294.2.9 by William Grant
Refactor generation tests.
327
        assert_equal(
328
            self.rtr.generate(self.r.subjects['info1'].offerings[(2009, 1)]),
329
            '/info1/2009/1'
330
            )
331
        assert_equal(
332
            self.rtr.generate(self.r.subjects['info2'].offerings[(2008, 2)]),
333
            '/info2/2008/2'
334
            )
1294.2.1 by William Grant
Add an object-traversal-based router.
335
1294.2.40 by William Grant
Test generation of URLs for named routes.
336
    def testNamedRoute(self):
337
        assert_equal(self.rtr.generate(
338
                OfferingFiles(self.r.subjects['info1'].offerings[(2009, 1)])),
339
                '/info1/2009/1/+files'
340
            )
341
1294.2.9 by William Grant
Refactor generation tests.
342
    def testView(self):
343
        assert_equal(self.rtr.generate(self.r.subjects['info1'], SubjectEdit),
344
                     '/info1/+edit'
345
                     )
1294.2.1 by William Grant
Add an object-traversal-based router.
346
1294.2.4 by William Grant
Support generation of view URLs.
347
    def testDefaultView(self):
1294.2.9 by William Grant
Refactor generation tests.
348
        assert_equal(
349
            self.rtr.generate(self.r.subjects['info1'].offerings[(2009, 1)],
350
                              OfferingIndex
351
                              ),
352
            '/info1/2009/1'
353
            )
1294.2.1 by William Grant
Add an object-traversal-based router.
354
1294.2.11 by William Grant
Revise generation and resolution tests to involve subpaths.
355
    def testViewWithSubpath(self):
356
        assert_equal(self.rtr.generate(self.r.subjects['info1'], SubjectEdit,
357
                                       ('foo', 'bar')),
358
                     '/info1/+edit/foo/bar'
359
                     )
360
361
    def testViewWithStringSubpath(self):
362
        assert_equal(self.rtr.generate(self.r.subjects['info1'], SubjectEdit,
363
                                       'foo/bar'),
364
                     '/info1/+edit/foo/bar'
365
                     )
366
1294.2.9 by William Grant
Refactor generation tests.
367
    def testAlternateViewSetWithDefault(self):
368
        assert_equal(
369
            self.rtr.generate(self.r.subjects['info1'].offerings[(2009, 1)],
370
                              OfferingAPIIndex
371
                              ),
372
            '/api/info1/2009/1'
373
            )
1294.2.4 by William Grant
Support generation of view URLs.
374
1294.2.43 by William Grant
Test deep view generation.
375
    def testDeepView(self):
376
        assert_equal(
377
            self.rtr.generate(
378
                self.r.subjects['info1'].offerings[(2009, 1)],
379
                OfferingAddProject
380
                ),
381
        '/info1/2009/1/+projects/+new'
382
        )
383
1294.2.46 by William Grant
Add tests for default deep views.
384
    def testDefaultDeepView(self):
385
        assert_equal(
386
            self.rtr.generate(
387
                self.r.subjects['info1'].offerings[(2009, 1)],
388
                OfferingProjects
389
                ),
390
        '/info1/2009/1/+projects'
391
        )
392
393
    def testDefaultDeepViewWithSubpath(self):
394
        assert_equal(
395
            self.rtr.generate(
396
                self.r.subjects['info1'].offerings[(2009, 1)],
397
                OfferingProjects, ('foo', 'bar')
398
                ),
399
        '/info1/2009/1/+projects/+index/foo/bar'
400
        )
401
1294.2.43 by William Grant
Test deep view generation.
402
    def testNamedRouteWithDeepView(self):
403
        assert_equal(
404
            self.rtr.generate(
405
                self.r.subjects['info1'].offerings[(2009, 1)].projects['p1'],
406
                ProjectIndex
407
                ),
408
        '/info1/2009/1/+projects/p1'
409
        )
410
1294.3.1 by William Grant
Allow reverse routes to return the real root too.
411
    def testRoot(self):
412
        assert_equal(self.rtr.generate(self.r), '/')
1294.2.43 by William Grant
Test deep view generation.
413
1294.2.1 by William Grant
Add an object-traversal-based router.
414
415
class TestErrors(BaseTest):
1294.2.6 by William Grant
Refactor the error tests, using a single router.
416
    def setUp(self):
417
        super(TestErrors, self).setUp()
418
        self.rtr = Router(root=self.r)
419
        self.rtr.add_forward(Root, None, root_to_subject, 1)
420
        self.rtr.add_forward(Subject, '+foo', lambda s: s.name + 'foo', 0)
421
        self.rtr.add_forward(Subject, None, subject_to_offering, 2)
422
        self.rtr.add_reverse(Subject, subject_url)
423
        self.rtr.add_reverse(Offering, offering_url)
424
        self.rtr.add_view(Offering, '+index', OfferingIndex)
425
        self.rtr.add_view(Offering, '+index', OfferingAPIIndex, viewset='api')
426
        self.rtr.add_set_switch('rest', 'rest')
427
1294.2.5 by William Grant
Use nose.tools.raises in the error tests.
428
    @raises(RouteConflict)
1294.2.1 by William Grant
Add an object-traversal-based router.
429
    def testForwardConflict(self):
1294.2.6 by William Grant
Refactor the error tests, using a single router.
430
        self.rtr.add_forward(Subject, '+foo', object(), 2)
1294.2.1 by William Grant
Add an object-traversal-based router.
431
1294.2.5 by William Grant
Use nose.tools.raises in the error tests.
432
    @raises(RouteConflict)
1294.2.1 by William Grant
Add an object-traversal-based router.
433
    def testReverseConflict(self):
1294.2.6 by William Grant
Refactor the error tests, using a single router.
434
        self.rtr.add_reverse(Subject, object())
1294.2.1 by William Grant
Add an object-traversal-based router.
435
1294.2.5 by William Grant
Use nose.tools.raises in the error tests.
436
    @raises(RouteConflict)
1294.2.3 by William Grant
Add tests to complete coverage.
437
    def testViewConflict(self):
1294.2.6 by William Grant
Refactor the error tests, using a single router.
438
        self.rtr.add_view(Offering, '+index', object())
439
440
    @raises(RouteConflict)
441
    def testSetSwitchForwardConflict(self):
442
        self.rtr.add_set_switch('rest', 'foo')
443
444
    @raises(RouteConflict)
445
    def testSetSwitchReverseConflict(self):
446
        self.rtr.add_set_switch('bar', 'rest')
1294.2.5 by William Grant
Use nose.tools.raises in the error tests.
447
448
    @raises(NoPath)
1294.2.1 by William Grant
Add an object-traversal-based router.
449
    def testNoPath(self):
1294.2.6 by William Grant
Refactor the error tests, using a single router.
450
        self.rtr.generate(object())
1294.2.1 by William Grant
Add an object-traversal-based router.
451
1294.2.5 by William Grant
Use nose.tools.raises in the error tests.
452
    @raises(NoPath)
1294.2.4 by William Grant
Support generation of view URLs.
453
    def testNoSetSwitch(self):
1294.2.6 by William Grant
Refactor the error tests, using a single router.
454
        self.rtr.generate(self.r.subjects['info1'].offerings[(2009, 1)],
455
                          OfferingAPIIndex)
1294.2.5 by William Grant
Use nose.tools.raises in the error tests.
456
457
    @raises(NoPath)
1294.2.4 by William Grant
Support generation of view URLs.
458
    def testUnregisteredView(self):
1294.2.6 by William Grant
Refactor the error tests, using a single router.
459
        self.rtr.generate(self.r.subjects['info1'], SubjectIndex)
1294.2.5 by William Grant
Use nose.tools.raises in the error tests.
460
461
    @raises(NotFound)
1294.2.1 by William Grant
Add an object-traversal-based router.
462
    def testNotFound(self):
1294.2.6 by William Grant
Refactor the error tests, using a single router.
463
        self.rtr.resolve('/bar')
1294.2.1 by William Grant
Add an object-traversal-based router.
464
1294.2.5 by William Grant
Use nose.tools.raises in the error tests.
465
    @raises(InsufficientPathSegments)
1294.2.1 by William Grant
Add an object-traversal-based router.
466
    def testInsufficientPathSegments(self):
1294.2.6 by William Grant
Refactor the error tests, using a single router.
467
        self.rtr.resolve('/info1/foo')