1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/bindings/parser/tests/test_nullable_equivalency.py Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,125 @@ 1.4 +import WebIDL 1.5 + 1.6 +def WebIDLTest(parser, harness): 1.7 + parser.parse(""" 1.8 + interface TestNullableEquivalency1 { 1.9 + attribute long a; 1.10 + attribute long? b; 1.11 + }; 1.12 + 1.13 + interface TestNullableEquivalency2 { 1.14 + attribute ArrayBuffer a; 1.15 + attribute ArrayBuffer? b; 1.16 + }; 1.17 + 1.18 + /* Can't have dictionary-valued attributes, so can't test that here */ 1.19 + 1.20 + enum TestNullableEquivalency4Enum { 1.21 + "Foo", 1.22 + "Bar" 1.23 + }; 1.24 + 1.25 + interface TestNullableEquivalency4 { 1.26 + attribute TestNullableEquivalency4Enum a; 1.27 + attribute TestNullableEquivalency4Enum? b; 1.28 + }; 1.29 + 1.30 + interface TestNullableEquivalency5 { 1.31 + attribute TestNullableEquivalency4 a; 1.32 + attribute TestNullableEquivalency4? b; 1.33 + }; 1.34 + 1.35 + interface TestNullableEquivalency6 { 1.36 + attribute boolean a; 1.37 + attribute boolean? b; 1.38 + }; 1.39 + 1.40 + interface TestNullableEquivalency7 { 1.41 + attribute DOMString a; 1.42 + attribute DOMString? b; 1.43 + }; 1.44 + 1.45 + interface TestNullableEquivalency8 { 1.46 + attribute float a; 1.47 + attribute float? b; 1.48 + }; 1.49 + 1.50 + interface TestNullableEquivalency9 { 1.51 + attribute double a; 1.52 + attribute double? b; 1.53 + }; 1.54 + 1.55 + interface TestNullableEquivalency10 { 1.56 + attribute object a; 1.57 + attribute object? b; 1.58 + }; 1.59 + 1.60 + interface TestNullableEquivalency11 { 1.61 + attribute double[] a; 1.62 + attribute double[]? b; 1.63 + }; 1.64 + 1.65 + interface TestNullableEquivalency12 { 1.66 + attribute TestNullableEquivalency9[] a; 1.67 + attribute TestNullableEquivalency9[]? b; 1.68 + }; 1.69 + """) 1.70 + 1.71 + for decl in parser.finish(): 1.72 + if decl.isInterface(): 1.73 + checkEquivalent(decl, harness) 1.74 + 1.75 +def checkEquivalent(iface, harness): 1.76 + type1 = iface.members[0].type 1.77 + type2 = iface.members[1].type 1.78 + 1.79 + harness.check(type1.nullable(), False, 'attr1 should not be nullable') 1.80 + harness.check(type2.nullable(), True, 'attr2 should be nullable') 1.81 + 1.82 + # We don't know about type1, but type2, the nullable type, definitely 1.83 + # shouldn't be builtin. 1.84 + harness.check(type2.builtin, False, 'attr2 should not be builtin') 1.85 + 1.86 + # Ensure that all attributes of type2 match those in type1, except for: 1.87 + # - names on an ignore list, 1.88 + # - names beginning with '_', 1.89 + # - functions which throw when called with no args, and 1.90 + # - class-level non-callables ("static variables"). 1.91 + # 1.92 + # Yes, this is an ugly, fragile hack. But it finds bugs... 1.93 + for attr in dir(type1): 1.94 + if attr.startswith('_') or \ 1.95 + attr in ['nullable', 'builtin', 'filename', 'location', 1.96 + 'inner', 'QName', 'getDeps'] or \ 1.97 + (hasattr(type(type1), attr) and not callable(getattr(type1, attr))): 1.98 + continue 1.99 + 1.100 + a1 = getattr(type1, attr) 1.101 + 1.102 + if callable(a1): 1.103 + try: 1.104 + v1 = a1() 1.105 + except: 1.106 + # Can't call a1 with no args, so skip this attriute. 1.107 + continue 1.108 + 1.109 + try: 1.110 + a2 = getattr(type2, attr) 1.111 + except: 1.112 + harness.ok(False, 'Missing %s attribute on type %s in %s' % (attr, type2, iface)) 1.113 + continue 1.114 + 1.115 + if not callable(a2): 1.116 + harness.ok(False, "%s attribute on type %s in %s wasn't callable" % (attr, type2, iface)) 1.117 + continue 1.118 + 1.119 + v2 = a2() 1.120 + harness.check(v2, v1, '%s method return value' % attr) 1.121 + else: 1.122 + try: 1.123 + a2 = getattr(type2, attr) 1.124 + except: 1.125 + harness.ok(False, 'Missing %s attribute on type %s in %s' % (attr, type2, iface)) 1.126 + continue 1.127 + 1.128 + harness.check(a2, a1, '%s attribute should match' % attr)