Home | History | Annotate | Download | only in generate
      1 # Copyright 2013 The Chromium Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import sys
      6 
      7 import module as mojom
      8 import pack
      9 import test_support
     10 
     11 
     12 EXPECT_EQ = test_support.EXPECT_EQ
     13 EXPECT_TRUE = test_support.EXPECT_TRUE
     14 RunTest = test_support.RunTest
     15 
     16 
     17 def TestOrdinalOrder():
     18   errors = 0
     19   struct = mojom.Struct('test')
     20   struct.AddField('testfield1', mojom.INT32, 2)
     21   struct.AddField('testfield2', mojom.INT32, 1)
     22   ps = pack.PackedStruct(struct)
     23 
     24   errors += EXPECT_EQ(2, len(ps.packed_fields))
     25   errors += EXPECT_EQ('testfield2', ps.packed_fields[0].field.name)
     26   errors += EXPECT_EQ('testfield1', ps.packed_fields[1].field.name)
     27 
     28   return errors
     29 
     30 def TestZeroFields():
     31   errors = 0
     32   struct = mojom.Struct('test')
     33   ps = pack.PackedStruct(struct)
     34   errors += EXPECT_EQ(0, len(ps.packed_fields))
     35   return errors
     36 
     37 
     38 def TestOneField():
     39   errors = 0
     40   struct = mojom.Struct('test')
     41   struct.AddField('testfield1', mojom.INT8)
     42   ps = pack.PackedStruct(struct)
     43   errors += EXPECT_EQ(1, len(ps.packed_fields))
     44   return errors
     45 
     46 # Pass three tuples.
     47 # |kinds| is a sequence of mojom.Kinds that specify the fields that are to
     48 # be created.
     49 # |fields| is the expected order of the resulting fields, with the integer
     50 # "1" first.
     51 # |offsets| is the expected order of offsets, with the integer "0" first.
     52 def TestSequence(kinds, fields, offsets):
     53   errors = 0
     54   struct = mojom.Struct('test')
     55   index = 1
     56   for kind in kinds:
     57     struct.AddField("%d" % index, kind)
     58     index += 1
     59   ps = pack.PackedStruct(struct)
     60   num_fields = len(ps.packed_fields)
     61   errors += EXPECT_EQ(len(kinds), num_fields)
     62   for i in xrange(num_fields):
     63     EXPECT_EQ("%d" % fields[i], ps.packed_fields[i].field.name)
     64     EXPECT_EQ(offsets[i], ps.packed_fields[i].offset)
     65 
     66   return errors
     67 
     68 
     69 def TestPaddingPackedInOrder():
     70   return TestSequence(
     71       (mojom.INT8, mojom.UINT8, mojom.INT32),
     72       (1, 2, 3),
     73       (0, 1, 4))
     74 
     75 
     76 def TestPaddingPackedOutOfOrder():
     77   return TestSequence(
     78       (mojom.INT8, mojom.INT32, mojom.UINT8),
     79       (1, 3, 2),
     80       (0, 1, 4))
     81 
     82 
     83 def TestPaddingPackedOverflow():
     84   kinds = (mojom.INT8, mojom.INT32, mojom.INT16, mojom.INT8, mojom.INT8)
     85   # 2 bytes should be packed together first, followed by short, then by int.
     86   fields = (1, 4, 3, 2, 5)
     87   offsets = (0, 1, 2, 4, 8)
     88   return TestSequence(kinds, fields, offsets)
     89 
     90 
     91 def TestAllTypes():
     92   struct = mojom.Struct('test')
     93   array = mojom.Array()
     94   return TestSequence(
     95       (mojom.BOOL, mojom.INT8, mojom.STRING, mojom.UINT8,
     96        mojom.INT16, mojom.DOUBLE, mojom.UINT16,
     97        mojom.INT32, mojom.UINT32, mojom.INT64,
     98        mojom.FLOAT, mojom.STRING, mojom.HANDLE,
     99        mojom.UINT64, mojom.Struct('test'), mojom.Array()),
    100       (1, 2, 4, 5, 7, 3, 6,  8,  9,  10, 11, 13, 12, 14, 15, 16, 17),
    101       (0, 1, 2, 4, 6, 8, 16, 24, 28, 32, 40, 44, 48, 56, 64, 72, 80))
    102 
    103 
    104 def TestPaddingPackedOutOfOrderByOrdinal():
    105   errors = 0
    106   struct = mojom.Struct('test')
    107   struct.AddField('testfield1', mojom.INT8)
    108   struct.AddField('testfield3', mojom.UINT8, 3)
    109   struct.AddField('testfield2', mojom.INT32, 2)
    110   ps = pack.PackedStruct(struct)
    111   errors += EXPECT_EQ(3, len(ps.packed_fields))
    112 
    113   # Second byte should be packed in behind first, altering order.
    114   errors += EXPECT_EQ('testfield1', ps.packed_fields[0].field.name)
    115   errors += EXPECT_EQ('testfield3', ps.packed_fields[1].field.name)
    116   errors += EXPECT_EQ('testfield2', ps.packed_fields[2].field.name)
    117 
    118   # Second byte should be packed with first.
    119   errors += EXPECT_EQ(0, ps.packed_fields[0].offset)
    120   errors += EXPECT_EQ(1, ps.packed_fields[1].offset)
    121   errors += EXPECT_EQ(4, ps.packed_fields[2].offset)
    122 
    123   return errors
    124 
    125 
    126 def TestBools():
    127   errors = 0
    128   struct = mojom.Struct('test')
    129   struct.AddField('bit0', mojom.BOOL)
    130   struct.AddField('bit1', mojom.BOOL)
    131   struct.AddField('int', mojom.INT32)
    132   struct.AddField('bit2', mojom.BOOL)
    133   struct.AddField('bit3', mojom.BOOL)
    134   struct.AddField('bit4', mojom.BOOL)
    135   struct.AddField('bit5', mojom.BOOL)
    136   struct.AddField('bit6', mojom.BOOL)
    137   struct.AddField('bit7', mojom.BOOL)
    138   struct.AddField('bit8', mojom.BOOL)
    139   ps = pack.PackedStruct(struct)
    140   errors += EXPECT_EQ(10, len(ps.packed_fields))
    141 
    142   # First 8 bits packed together.
    143   for i in xrange(8):
    144     pf = ps.packed_fields[i]
    145     errors += EXPECT_EQ(0, pf.offset)
    146     errors += EXPECT_EQ("bit%d" % i, pf.field.name)
    147     errors += EXPECT_EQ(i, pf.bit)
    148 
    149   # Ninth bit goes into second byte.
    150   errors += EXPECT_EQ("bit8", ps.packed_fields[8].field.name)
    151   errors += EXPECT_EQ(1, ps.packed_fields[8].offset)
    152   errors += EXPECT_EQ(0, ps.packed_fields[8].bit)
    153 
    154   # int comes last.
    155   errors += EXPECT_EQ("int", ps.packed_fields[9].field.name)
    156   errors += EXPECT_EQ(4, ps.packed_fields[9].offset)
    157 
    158   return errors
    159 
    160 
    161 def Main(args):
    162   errors = 0
    163   errors += RunTest(TestZeroFields)
    164   errors += RunTest(TestOneField)
    165   errors += RunTest(TestPaddingPackedInOrder)
    166   errors += RunTest(TestPaddingPackedOutOfOrder)
    167   errors += RunTest(TestPaddingPackedOverflow)
    168   errors += RunTest(TestAllTypes)
    169   errors += RunTest(TestPaddingPackedOutOfOrderByOrdinal)
    170   errors += RunTest(TestBools)
    171 
    172   return errors
    173 
    174 
    175 if __name__ == '__main__':
    176   sys.exit(Main(sys.argv[1:]))
    177