9
9
from txaws.server.exception import APIError
10
10
from txaws.server.schema import (
11
11
Arguments, Bool, Date, Enum, Integer, Parameter, RawStr, Schema, Unicode,
12
UnicodeLine, List, Structure, InconsistentParameterError)
13
InconsistentParameterError)
15
16
class ArgumentsTestCase(TestCase):
41
42
arguments = Arguments({})
42
43
self.assertRaises(KeyError, arguments.__getitem__, 1)
44
def test_contains(self):
46
The presence of a certain argument can be inspected using the 'in'
49
arguments = Arguments({"foo": 1})
50
self.assertIn("foo", arguments)
51
self.assertNotIn("bar", arguments)
53
45
def test_len(self):
54
46
"""C{len()} can be used with an L{Arguments} instance."""
55
47
self.assertEqual(0, len(Arguments({})))
211
203
Enum(mapping={"hey": 1}, doc="foo"),
213
205
List(item=Integer(), doc="foo"),
214
Structure(fields={}, doc="foo")]
206
Structure(fields={}, doc="foo")
215
208
for parameter in parameters:
216
209
self.assertEqual("foo", parameter.doc)
260
253
self.assertEqual("InvalidParameterValue", error.code)
263
class UnicodeLineTestCase(TestCase):
265
def test_parse(self):
266
"""L{UnicodeLine.parse} converts the given raw C{value} to
268
parameter = UnicodeLine("Test")
269
self.assertEqual(u"foo", parameter.parse("foo"))
271
def test_newlines_in_text(self):
273
The L{UnicodeLine} parameter returns an error if text contains
276
parameter = UnicodeLine("Test")
277
error = self.assertRaises(APIError, parameter.coerce, "Test\nError")
278
self.assertIn(u"Can't contain newlines", error.message)
279
self.assertEqual(400, error.status)
282
256
class RawStrTestCase(TestCase):
284
258
def test_parse(self):
411
385
class SchemaTestCase(TestCase):
413
def test_get_parameters(self):
415
L{Schema.get_parameters} returns the original list of parameters.
417
schema = Schema(parameters=[
419
List("scores", Integer())])
420
parameters = schema.get_parameters()
421
self.assertEqual("name", parameters[0].name)
422
self.assertEqual("scores", parameters[1].name)
424
def test_get_parameters_order_on_parameter_only_construction(self):
426
L{Schema.get_parameters} returns the original list of L{Parameter}s
427
even when they are passed as positional arguments to L{Schema}.
431
List("scores", Integer()),
432
Integer("index", Integer()))
433
self.assertEqual(["name", "scores", "index"],
434
[p.name for p in schema.get_parameters()])
436
387
def test_extract(self):
438
389
L{Schema.extract} returns an L{Argument} object whose attributes are
564
515
given without an index.
566
517
schema = Schema(Unicode("name.n"))
568
InconsistentParameterError,
569
schema.extract, {"nameFOOO": "foo", "nameFOOO.1": "bar"})
518
self.assertRaises(InconsistentParameterError,
519
schema.extract, {"name": "foo", "name.1": "bar"})
571
521
def test_extract_with_non_numbered_template(self):
664
614
def test_bundle_with_structure(self):
665
615
"""L{Schema.bundle} can bundle L{Structure}s."""
668
Structure("struct", fields={"field1": Unicode(),
669
"field2": Integer()})])
618
"struct": Structure(fields={"field1": Unicode(),
619
"field2": Integer()})})
670
620
params = schema.bundle(struct={"field1": "hi", "field2": 59})
671
621
self.assertEqual({"struct.field1": "hi", "struct.field2": "59"},
674
624
def test_bundle_with_list(self):
675
625
"""L{Schema.bundle} can bundle L{List}s."""
676
schema = Schema(parameters=[List("things", item=Unicode())])
626
schema = Schema(parameters={"things": List(item=Unicode())})
677
627
params = schema.bundle(things=["foo", "bar"])
678
628
self.assertEqual({"things.1": "foo", "things.2": "bar"}, params)
682
632
L{Schema.bundle} can bundle L{Structure}s (specified as L{Arguments}).
686
Structure("struct", fields={"field1": Unicode(),
687
"field2": Integer()})])
636
"struct": Structure(fields={"field1": Unicode(),
637
"field2": Integer()})})
688
638
params = schema.bundle(struct=Arguments({"field1": "hi",
690
640
self.assertEqual({"struct.field1": "hi", "struct.field2": "59"},
693
643
def test_bundle_with_list_with_arguments(self):
694
644
"""L{Schema.bundle} can bundle L{List}s (specified as L{Arguments})."""
695
schema = Schema(parameters=[List("things", item=Unicode())])
645
schema = Schema(parameters={"things": List(item=Unicode())})
696
646
params = schema.bundle(things=Arguments({1: "foo", 2: "bar"}))
697
647
self.assertEqual({"things.1": "foo", "things.2": "bar"}, params)
820
770
{name: field} format.
823
parameters=[Structure("foo",
824
fields={"l": List(item=Integer())})])
773
parameters={"foo": Structure(
774
fields={"l": List(item=Integer())})})
825
775
arguments, _ = schema.extract({"foo.l.1": "1", "foo.l.2": "2"})
826
776
self.assertEqual([1, 2], arguments.foo.l)
828
def test_schema_conversion_list(self):
778
def test_schema_conversion_list_name(self):
830
780
Backwards-compatibility conversion maintains the name of lists.
832
782
schema = Schema(Unicode("foos.N"))
833
parameters = schema.get_parameters()
834
self.assertEqual(1, len(parameters))
835
self.assertTrue(isinstance(parameters[0], List))
836
self.assertEqual("foos", parameters[0].name)
838
def test_coerce_list(self):
840
When a L{List} coerces the value of one of its item, it uses the the
841
proper name in the C{MissingParameter} error raised.
843
parameter = List("foo", Unicode())
844
error = self.assertRaises(APIError, parameter.item.coerce, "")
845
self.assertEqual(400, error.status)
846
self.assertEqual("MissingParameter", error.code)
847
self.assertEqual("The request must contain the parameter foo "
783
self.assertEqual("foos", schema._parameters["foos"].name)
851
785
def test_schema_conversion_structure_name(self):
856
790
schema = Schema(Unicode("foos.N.field"),
857
791
Unicode("foos.N.field2"))
858
parameters = schema.get_parameters()
859
self.assertEqual(1, len(parameters))
860
self.assertTrue(isinstance(parameters[0], List))
861
self.assertEqual("foos", parameters[0].name)
862
self.assertEqual("N",
863
parameters[0].item.name)
864
self.assertEqual("field",
865
parameters[0].item.fields["field"].name)
866
self.assertEqual("field2",
867
parameters[0].item.fields["field2"].name)
792
self.assertEqual("anonymous_structure",
793
schema._parameters["foos"].item.name)
794
self.assertEqual("foos.N.field",
795
schema._parameters["foos"].item.fields["field"].name)
796
self.assertEqual("foos.N.field2",
797
schema._parameters["foos"].item.fields["field2"].name)
869
799
def test_schema_conversion_optional_list(self):
890
820
Additional data can be specified on the Schema class for specifying a
891
821
more rich schema.
893
result = {'id': Integer(), 'name': Unicode(), 'data': RawStr()}
894
827
errors = [APIError]
898
831
doc="""Get the stuff.""",
912
845
The additional schema attributes can be passed to L{Schema.extend}.
914
result = {'id': Integer(), 'name': Unicode(), 'data': RawStr()}
915
851
errors = [APIError]
919
parameters=[Integer("id")])
855
parameters={"id": Integer()})
921
857
schema2 = schema.extend(
922
858
name="GetStuff2",
923
859
doc="Get stuff 2",
924
parameters=[Unicode("scope")],
860
parameters={'scope': Unicode()},
939
875
If additional schema attributes aren't passed to L{Schema.extend}, they
942
result = {'id': Integer(), 'name': Unicode(), 'data': RawStr()}
943
882
errors = [APIError]
947
886
doc="""Get the stuff.""",
948
parameters=[Integer("id")],
887
parameters={'id': Integer()},
952
schema2 = schema.extend(parameters=[Unicode("scope")])
891
schema2 = schema.extend(parameters={'scope': Unicode()})
954
893
self.assertEqual("GetStuff", schema2.name)
955
894
self.assertEqual("Get the stuff.", schema2.doc)
965
904
Result fields can also be extended with L{Schema.extend}.
967
schema = Schema(result={'name': Unicode()})
907
result={'name': Unicode()}
968
909
schema2 = schema.extend(
969
910
result={'id': Integer()})
970
911
result_structure = Structure(fields=schema2.result)
977
918
Errors can be extended with L{Schema.extend}.
979
schema = Schema(parameters=[], errors=[APIError])
920
schema = Schema(parameters={}, errors=[APIError])
980
921
schema2 = schema.extend(errors=[ZeroDivisionError])
981
922
self.assertEqual(set([APIError, ZeroDivisionError]), schema2.errors)
983
def test_extend_maintains_parameter_order(self):
985
Extending a schema with additional parameters puts the new parameters
988
schema = Schema(parameters=[Unicode("name"), Unicode("value")])
989
schema2 = schema.extend(parameters=[Integer("foo"), Unicode("index")])
990
self.assertEqual(["name", "value", "foo", "index"],
991
[p.name for p in schema2.get_parameters()])
993
def test_schema_field_names(self):
994
structure = Structure(fields={"foo": Integer()})
995
self.assertEqual("foo", structure.fields["foo"].name)