blob: a90baae936f24ec9c0375410845f866a9fcee178 [file] [log] [blame]
Austin Schuh272c6132020-11-14 16:37:52 -08001import XCTest
2@testable import FlatBuffers
3
4final class FlatBuffersUnionTests: XCTestCase {
5
6 func testCreateMonstor() {
7
8 var b = FlatBufferBuilder(initialSize: 20)
9 let dmg: Int16 = 5
10 let str = "Axe"
11 let axe = b.create(string: str)
12 let weapon = Weapon.createWeapon(builder: &b, offset: axe, dmg: dmg)
13 let weapons = b.createVector(ofOffsets: [weapon])
14 let root = LocalMonster.createMonster(builder: &b,
15 offset: weapons,
16 equipment: .Weapon,
17 equippedOffset: weapon.o)
18 b.finish(offset: root)
19 let buffer = b.sizedByteArray
20 XCTAssertEqual(buffer, [16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 7, 0, 12, 0, 10, 0, 0, 0, 0, 0, 0, 1, 8, 0, 0, 0, 20, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 8, 0, 12, 0, 8, 0, 6, 0, 8, 0, 0, 0, 0, 0, 5, 0, 4, 0, 0, 0, 3, 0, 0, 0, 65, 120, 101, 0])
21 let monster = LocalMonster.getRootAsMonster(bb: ByteBuffer(bytes: buffer))
22 XCTAssertEqual(monster.weapon(at: 0)?.dmg, dmg)
23 XCTAssertEqual(monster.weapon(at: 0)?.name, str)
24 XCTAssertEqual(monster.weapon(at: 0)?.nameVector, [65, 120, 101])
25 let p: Weapon? = monster.equiped()
26 XCTAssertEqual(p?.dmg, dmg)
27 XCTAssertEqual(p?.name, str)
28 XCTAssertEqual(p?.nameVector, [65, 120, 101])
29 }
30
31 func testEndTableFinish() {
32 var builder = FlatBufferBuilder(initialSize: 20)
33 let sword = builder.create(string: "Sword")
34 let axe = builder.create(string: "Axe")
35 let weaponOne = Weapon.createWeapon(builder: &builder, offset: sword, dmg: 3)
36 let weaponTwo = Weapon.createWeapon(builder: &builder, offset: axe, dmg: 5)
37 let name = builder.create(string: "Orc")
38 let inventory: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
39 let inv = builder.createVector(inventory, size: 10)
40 let weapons = builder.createVector(ofOffsets: [weaponOne, weaponTwo])
41 builder.startVectorOfStructs(count: 2, size: Vec.size, alignment: Vec.alignment)
42 createVecWrite(builder: &builder, x: 1.0, y: 2.0, z: 3.0)
43 createVecWrite(builder: &builder, x: 4.0, y: 5.0, z: 6.0)
44 let path = builder.endVectorOfStructs(count: 2)
45 let orc = FinalMonster.createMonster(builder: &builder,
46 position: createVecWrite(builder: &builder, x: 1.0, y: 2.0, z: 3.0),
47 hp: 300,
48 name: name,
49 inventory: inv,
50 color: .red,
51 weapons: weapons,
52 equipment: .Weapon,
53 equippedOffset: weaponTwo,
54 path: path)
55 builder.finish(offset: orc)
56 XCTAssertEqual(builder.sizedByteArray, [32, 0, 0, 0, 0, 0, 26, 0, 36, 0, 36, 0, 0, 0, 34, 0, 28, 0, 0, 0, 24, 0, 23, 0, 16, 0, 15, 0, 8, 0, 4, 0, 26, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 1, 60, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 76, 0, 0, 0, 0, 0, 44, 1, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 2, 0, 0, 0, 0, 0, 128, 64, 0, 0, 160, 64, 0, 0, 192, 64, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 2, 0, 0, 0, 52, 0, 0, 0, 28, 0, 0, 0, 10, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 3, 0, 0, 0, 79, 114, 99, 0, 244, 255, 255, 255, 0, 0, 5, 0, 24, 0, 0, 0, 8, 0, 12, 0, 8, 0, 6, 0, 8, 0, 0, 0, 0, 0, 3, 0, 12, 0, 0, 0, 3, 0, 0, 0, 65, 120, 101, 0, 5, 0, 0, 0, 83, 119, 111, 114, 100, 0, 0, 0])
57 }
58
59 func testEnumVector() {
60 let vectorOfEnums: [ColorsNameSpace.RGB] = [.blue, .green]
61
62 var builder = FlatBufferBuilder(initialSize: 1)
63 let off = builder.createVector(vectorOfEnums)
64 let start = ColorsNameSpace.Monster.startMonster(&builder)
65 ColorsNameSpace.Monster.add(colors: off, &builder)
66 let end = ColorsNameSpace.Monster.endMonster(&builder, start: start)
67 builder.finish(offset: end)
68 XCTAssertEqual(builder.sizedByteArray, [12, 0, 0, 0, 0, 0, 6, 0, 8, 0, 4, 0, 6, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0])
69 let monster = ColorsNameSpace.Monster.getRootAsMonster(bb: builder.buffer)
70 XCTAssertEqual(monster.colorsCount, 2)
71 XCTAssertEqual(monster.colors(at: 0), .blue)
72 XCTAssertEqual(monster.colors(at: 1), .green)
73 }
74
75 func testUnionVector() {
76 var fb = FlatBufferBuilder()
77
78 let swordDmg: Int32 = 8
79 let attackStart = Attacker.startAttacker(&fb)
80 Attacker.add(swordAttackDamage: swordDmg, &fb)
81 let attack = Attacker.endAttacker(&fb, start: attackStart)
82
83 let characterType: [Character] = [.belle, .mulan, .bookfan]
84
85 let characters = [
86 BookReader.createBookReader(builder: &fb, booksRead: 7),
87 attack,
88 BookReader.createBookReader(builder: &fb, booksRead: 2)
89 ]
90 let types = fb.createVector(characterType)
91 let characterVector = fb.createVector(ofOffsets: characters)
92 let end = Movie.createMovie(&fb, vectorOfCharactersType: types, vectorOfCharacters: characterVector)
93 Movie.finish(&fb, end: end)
94
95 var movie = Movie.getRootAsMovie(bb: fb.buffer)
96 XCTAssertEqual(movie.charactersTypeCount, Int32(characterType.count))
97 XCTAssertEqual(movie.charactersCount, Int32(characters.count))
98
99 for i in 0..<movie.charactersTypeCount {
100 XCTAssertEqual(movie.charactersType(at: i), characterType[Int(i)])
101 }
102
103 XCTAssertEqual(movie.characters(at: 0, type: BookReader.self)?.booksRead, 7)
104 XCTAssertEqual(movie.characters(at: 1, type: Attacker.self)?.swordAttackDamage, swordDmg)
105 XCTAssertEqual(movie.characters(at: 2, type: BookReader.self)?.booksRead, 2)
106
107 var objc: MovieT? = movie.unpack()
108 XCTAssertEqual(movie.charactersTypeCount, Int32(objc?.characters.count ?? 0))
109 XCTAssertEqual(movie.characters(at: 0, type: BookReader.self)?.booksRead, (objc?.characters[0]?.value as? BookReaderT)?.booksRead)
110 fb.clear()
111 let newMovie = Movie.pack(&fb, obj: &objc)
112 fb.finish(offset: newMovie)
113
114 let packedMovie = Movie.getRootAsMovie(bb: fb.buffer)
115
116 XCTAssertEqual(packedMovie.characters(at: 0, type: BookReader.self)?.booksRead, movie.characters(at: 0, type: BookReader.self)?.booksRead)
117 XCTAssertEqual(packedMovie.characters(at: 1, type: Attacker.self)?.swordAttackDamage, movie.characters(at: 1, type: Attacker.self)?.swordAttackDamage)
118 XCTAssertEqual(packedMovie.characters(at: 2, type: BookReader.self)?.booksRead, movie.characters(at: 2, type: BookReader.self)?.booksRead)
119 }
120}
121
122public enum ColorsNameSpace {
123
124 enum RGB: Int32, Enum {
125 typealias T = Int32
126 static var byteSize: Int { return MemoryLayout<Int32>.size }
127 var value: Int32 { return self.rawValue }
128 case red = 0, green = 1, blue = 2
129 }
130
131 struct Monster: FlatBufferObject {
132 var __buffer: ByteBuffer! { _accessor.bb }
133
134 private var _accessor: Table
135 static func getRootAsMonster(bb: ByteBuffer) -> Monster { return Monster(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
136
137 init(_ t: Table) { _accessor = t }
138 init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
139
140 public var colorsCount: Int32 { let o = _accessor.offset(4); return o == 0 ? 0 : _accessor.vector(count: o) }
141 public func colors(at index: Int32) -> ColorsNameSpace.RGB? { let o = _accessor.offset(4); return o == 0 ? ColorsNameSpace.RGB(rawValue: 0)! : ColorsNameSpace.RGB(rawValue: _accessor.directRead(of: Int32.self, offset: _accessor.vector(at: o) + index * 4)) }
142 static func startMonster(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
143 static func add(colors: Offset<UOffset>, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: colors, at: 4) }
144 static func endMonster(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
145 }
146}
147
148
149enum Equipment: Byte { case none, Weapon }
150
151enum Color3: Int8 { case red = 0, green, blue }
152
153struct FinalMonster {
154
155 @inlinable static func createMonster(builder: inout FlatBufferBuilder,
156 position: Offset<UOffset>,
157 hp: Int16,
158 name: Offset<String>,
159 inventory: Offset<UOffset>,
160 color: Color3,
161 weapons: Offset<UOffset>,
162 equipment: Equipment = .none,
163 equippedOffset: Offset<Weapon>,
164 path: Offset<UOffset>) -> Offset<LocalMonster> {
165 let start = builder.startTable(with: 11)
166 builder.add(structOffset: 4)
167 builder.add(element: hp, def: 100, at: 8)
168 builder.add(offset: name, at: 10)
169 builder.add(offset: inventory, at: 14)
170 builder.add(element: color.rawValue, def: Color3.green.rawValue, at: 16)
171 builder.add(offset: weapons, at: 18)
172 builder.add(element: equipment.rawValue, def: Equipment.none.rawValue, at: 20)
173 builder.add(offset: equippedOffset, at: 22)
174 builder.add(offset: path, at: 24)
175 return Offset(offset: builder.endTable(at: start))
176 }
177}
178
179struct LocalMonster {
180
181 private var __t: Table
182
183 init(_ fb: ByteBuffer, o: Int32) { __t = Table(bb: fb, position: o) }
184 init(_ t: Table) { __t = t }
185
186 func weapon(at index: Int32) -> Weapon? { let o = __t.offset(4); return o == 0 ? nil : Weapon.assign(__t.indirect(__t.vector(at: o) + (index * 4)), __t.bb) }
187
188 func equiped<T: FlatBufferObject>() -> T? {
189 let o = __t.offset(8); return o == 0 ? nil : __t.union(o)
190 }
191
192 static func getRootAsMonster(bb: ByteBuffer) -> LocalMonster {
193 return LocalMonster(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: 0))))
194 }
195
196 @inlinable static func createMonster(builder: inout FlatBufferBuilder,
197 offset: Offset<UOffset>,
198 equipment: Equipment = .none,
199 equippedOffset: UOffset) -> Offset<LocalMonster> {
200 let start = builder.startTable(with: 3)
201 builder.add(element: equippedOffset, def: 0, at: 8)
202 builder.add(offset: offset, at: 4)
203 builder.add(element: equipment.rawValue, def: Equipment.none.rawValue, at: 6)
204 return Offset(offset: builder.endTable(at: start))
205 }
206}
207
208struct Weapon: FlatBufferObject {
209
210 var __buffer: ByteBuffer! { __t.bb }
211
212 static let offsets: (name: VOffset, dmg: VOffset) = (4, 6)
213 private var __t: Table
214
215 init(_ t: Table) { __t = t }
216 init(_ fb: ByteBuffer, o: Int32) { __t = Table(bb: fb, position: o)}
217
218 var dmg: Int16 { let o = __t.offset(6); return o == 0 ? 0 : __t.readBuffer(of: Int16.self, at: o) }
219 var nameVector: [UInt8]? { return __t.getVector(at: 4) }
220 var name: String? { let o = __t.offset(4); return o == 0 ? nil : __t.string(at: o) }
221
222 static func assign(_ i: Int32, _ bb: ByteBuffer) -> Weapon { return Weapon(Table(bb: bb, position: i)) }
223
224 @inlinable static func createWeapon(builder: inout FlatBufferBuilder, offset: Offset<String>, dmg: Int16) -> Offset<Weapon> {
225 let _start = builder.startTable(with: 2)
226 Weapon.add(builder: &builder, name: offset)
227 Weapon.add(builder: &builder, dmg: dmg)
228 return Weapon.end(builder: &builder, startOffset: _start)
229 }
230
231 @inlinable static func end(builder: inout FlatBufferBuilder, startOffset: UOffset) -> Offset<Weapon> {
232 return Offset(offset: builder.endTable(at: startOffset))
233 }
234
235 @inlinable static func add(builder: inout FlatBufferBuilder, name: Offset<String>) {
236 builder.add(offset: name, at: Weapon.offsets.name)
237 }
238
239 @inlinable static func add(builder: inout FlatBufferBuilder, dmg: Int16) {
240 builder.add(element: dmg, def: 0, at: Weapon.offsets.dmg)
241 }
242}