github.com/google/skylark@v0.0.0-20181101142754-a5f7082aabed/skylarkstruct/testdata/struct.sky (about)

     1  # Tests of Skylark 'struct' extension.
     2  # This is not a standard feature and the Go and Skylark APIs may yet change.
     3  
     4  load('assert.sky', 'assert')
     5  
     6  assert.eq(str(struct), '<built-in function struct>')
     7  
     8  # struct is a constructor for "unbranded" structs.
     9  s = struct(host='localhost', port=80)
    10  assert.eq(s, s)
    11  assert.eq(s, struct(host='localhost', port=80))
    12  assert.ne(s, struct(host='localhost', port=81))
    13  assert.eq(type(s), 'struct')
    14  assert.eq(str(s),  'struct(host = "localhost", port = 80)')
    15  assert.eq(s.host, 'localhost')
    16  assert.eq(s.port, 80)
    17  assert.fails(lambda: s.protocol, 'struct has no .protocol attribute')
    18  assert.eq(dir(s), ['host', 'port'])
    19  
    20  # Use gensym to create "branded" struct types.
    21  hostport = gensym(name='hostport')
    22  assert.eq(type(hostport), 'symbol')
    23  assert.eq(str(hostport), 'hostport')
    24  
    25  # Call the symbol to instantiate a new type.
    26  http = hostport(host='localhost', port=80)
    27  assert.eq(type(http), 'struct')
    28  assert.eq(str(http), 'hostport(host = "localhost", port = 80)') # includes name of constructor
    29  assert.eq(http, http)
    30  assert.eq(http, hostport(host='localhost', port=80))
    31  assert.ne(http, hostport(host='localhost', port=443))
    32  assert.eq(http.host, 'localhost')
    33  assert.eq(http.port, 80)
    34  assert.fails(lambda: http.protocol, 'hostport struct has no .protocol attribute')
    35  
    36  person = gensym(name='person')
    37  bob = person(name='bob', age=50)
    38  alice = person(name='alice', city='NYC')
    39  assert.ne(http, bob)  # different constructor symbols
    40  assert.ne(bob, alice) # different fields
    41  
    42  hostport2 = gensym(name='hostport')
    43  assert.eq(hostport, hostport)
    44  assert.ne(hostport, hostport2) # same name, different symbol
    45  assert.ne(http, hostport2(host='localhost', port=80)) # equal fields but different ctor symbols
    46  
    47  # dir
    48  assert.eq(dir(alice), ['city', 'name'])
    49  assert.eq(dir(bob), ['age', 'name'])
    50  assert.eq(dir(http), ['host', 'port'])
    51  
    52  # hasattr, getattr
    53  assert.true(hasattr(alice, 'city'))
    54  assert.eq(hasattr(alice, 'ageaa'), False)
    55  assert.eq(getattr(alice, 'city'), 'NYC')
    56  
    57  # +
    58  assert.eq(bob + bob, bob)
    59  assert.eq(bob + alice, person(age=50, city='NYC', name='alice'))
    60  assert.eq(alice + bob, person(age=50, city='NYC', name='bob'))  # not commutative! a misfeature
    61  assert.fails(lambda: alice + 1, r'struct \+ int')
    62  assert.eq(http + http, http)
    63  assert.fails(lambda: http + bob, r'different constructors: hostport \+ person')
    64  
    65  # to_json (deprecated)
    66  assert.eq(alice.to_json(), '{"city": "NYC", "name": "alice"}')
    67  assert.eq(bob.to_json(), '{"age": 50, "name": "bob"}')
    68  # These deprecated methods are hidden from dir:
    69  assert.eq(hasattr(alice, "to_json"), True)
    70  assert.eq(hasattr(bob, "to_proto"), True)
    71  
    72  # to_proto
    73  assert.eq(struct().to_proto(), '')
    74  assert.eq(struct(int=1, float=3.141, str="hello", bool=True, intlist=[1, 2, 3]).to_proto(),
    75            '''bool: true
    76  float: 3.141
    77  int: 1
    78  intlist: 1
    79  intlist: 2
    80  intlist: 3
    81  str: "hello"
    82  ''')
    83  assert.eq(struct(x=struct(), y=[struct(a=1), struct(b=2, c=struct(p=1, q=2))]).to_proto(),
    84            '''x {
    85  }
    86  y {
    87    a: 1
    88  }
    89  y {
    90    b: 2
    91    c {
    92      p: 1
    93      q: 2
    94    }
    95  }
    96  ''')
    97  assert.fails(lambda: struct(none=None).to_proto(), 'cannot convert NoneType to proto')
    98  assert.fails(lambda: struct(dict={}).to_proto(), 'cannot convert dict to proto')