-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest.py
More file actions
executable file
·531 lines (422 loc) · 18.6 KB
/
test.py
File metadata and controls
executable file
·531 lines (422 loc) · 18.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
#!/usr/bin/env python
# encoding: utf-8
# This is a python testing file
import config
import game_engine
from logs import *
import itertools, random
import collections
def flatten(l):
"""This flattens arbitrarily annoying lists / dicts"""
for el in l:
if isinstance(el, collections.Iterable) and not isinstance(el, basestring):
for sub in flatten(el):
yield sub
else:
yield el
class __CommonTest__(object):
def __init__(self):
pass
def run_tests(self, tests, display=True):
"""Runs all functions"""
self.logger.info("Begin Testing Cycle")
self.logger.info("")
# loop through all functions
# and get results - store in a dictionary
# prints out if display=True
for func_name in tests:
self.logger.info("Running Test: {}".format(func_name))
func = getattr(self, func_name)
self.logger.debug(func.__doc__)
res = func()
if res:
self.logger.error("Test Failed: {}".format(func_name))
else:
self.logger.info("Test Passed: {}".format(func_name))
pass
class ParentChild(__CommonTest__):
def __init__(self):
# # creates a logger for the test file
get_logger(self)
self.game = game_engine.Gameplay(config.defaults)
self.game.user = self.game.User(**config.defaults['user'])
self.game.computer = self.game.Computer(**config.defaults['computer'])
self.game.central = self.game.Central(**config.defaults['central'])
# runs all tests
tests = [
"access_parent_attrs",
"access_sibling_attrs"
]
self.run_tests(tests)
pass
def access_sibling_attrs(self):
"""This tests if the classes can access attributes in the parent"""
error = False
actual_val = "KAPOW!"
# list of test cases
actors = ['user', 'computer', 'central']
# iterate through instances of the children
for actor in actors:
instance = getattr(self.game, actor) # create an instance of the child
instance_parent = getattr(instance, 'parent') # create a parent instance
# comapre against all others that != to current
siblings = [a for a in actors if a != actor]
for sibling in siblings: # iterate through all siblings
test_instance = getattr(self.game, sibling) # create sibling instance
test_instance.test_value = actual_val # create test value in sibling
if hasattr(instance_parent, sibling): # check that test_actor
sibling_instance = getattr(instance_parent, sibling) # create sibling instance exists
self.logger.debug("Found sibling: {}".format(sibling))
test_val =sibling_instance.test_value # get test_value
if test_val == actual_val: # check that sibling value is as expected
self.logger.debug("Test value equal.")
else:
self.logger.warning("Values not equal (actual:{}, test:{})".format(actual_val, test_val))
error=True
else:
self.logger.warning("Couldn't find sibling: self.{}.parent.{}".format(actor, sibling))
error=True
return error
def access_parent_attrs(self):
"""This tests if the classes can access attributes in the parent"""
error = False
actual_val = "KAPOW!"
self.game.test_value = actual_val
actors = ['user', 'computer', 'central']
for actor in actors:
instance = getattr(self.game, actor)
if hasattr(instance, 'parent'): # check that parent.test_value exists
self.logger.debug("Found parent in {}".format(actor))
test_val = self.game.user.parent.test_value # access text_value
if test_val == actual_val: # caompre values
self.logger.debug("Test value equal.")
else: # values not equal
error = True
self.logger.warning("Test values not equal (actual: {} vs. parent: {})".format(
actual_val,test_val))
else: # couldnt find parent.test_value
error=True
self.logger.warning("Did not find parent in {}".format(actor))
return error
class Settings(__CommonTest__):
"""This contains the tests related to the game settings"""
def __init__(self):
"""run tests"""
# # creates a logger for the test file
get_logger(self)
# create classes of users and central deck
self.game = game_engine.Gameplay(config.defaults)
self.central = self.game.Central(**config.defaults['central'])
self.user = self.game.User(**config.defaults['user'])
self.computer = self.game.Computer(**config.defaults['computer'])
# runs all tests
tests = [
"newgame_settings",
"deck_creator"
]
self.run_tests(tests)
pass
def deck_creator(self):
"""Tests the deck creator can correctly create Card() classes"""
class __Card(object):
"""Original Card Class"""
def __init__(self, name, values=(0, 0), cost=1):
self.name = name
self.cost = cost
self.attack, self.money = values
def __str__(self):
return 'Name %s costing %s with attack %s and money %s' \
% (self.name, self.cost, self.attack, self.money)
def get_attack(self):
return self.attack
def get_money(self):
return self.money
def expected():
"""Taken directly from original game code"""
sdc = [ # Central deck cards
4 * [__Card('Archer', (3, 0), 2)],
4 * [__Card('Baker', (0, 3), 2)],
3 * [__Card('Swordsman', (4, 0), 3)],
2 * [__Card('Knight', (6, 0), 5)],
3 * [__Card('Tailor', (0, 4), 3)],
3 * [__Card('Crossbowman', (4, 0), 3)],
3 * [__Card('Merchant', (0, 5), 4)],
4 * [__Card('Thug', (2, 0), 1)],
4 * [__Card('Thief', (1, 1), 1)],
2 * [__Card('Catapult', (7, 0), 6)],
2 * [__Card('Caravan', (1, 5), 5)],
2 * [__Card('Assassin', (5, 0), 4)]]
# Flatten central deck to one list
deck = list(itertools.chain.from_iterable(sdc))
return deck
deck_settings = [ # Central deck paramss
{"count":4 ,"params":{"name":'Archer', "attack":3, "money":0, "cost":2}},
{"count":4 ,"params":{"name":'Baker', "attack":0, "money":3, "cost":2}},
{"count":3 ,"params":{"name":'Swordsman', "attack":4, "money":0, "cost":3}},
{"count":2 ,"params":{"name":'Knight', "attack":6, "money":0, "cost":5}},
{"count":3 ,"params":{"name":'Tailor', "attack":0, "money":4, "cost":3}},
{"count":3 ,"params":{"name":'Crossbowman', "attack":4, "money":0, "cost":3}},
{"count":3 ,"params":{"name":'Merchant', "attack":0, "money":5, "cost":4}},
{"count":4 ,"params":{"name":'Thug', "attack":2, "money":0, "cost":1}},
{"count":4 ,"params":{"name":'Thief', "attack":1, "money":1, "cost":1}},
{"count":2 ,"params":{"name":'Catapult', "attack":7, "money":0, "cost":6}},
{"count":2 ,"params":{"name":'Caravan', "attack":1, "money":5, "cost":5}},
{"count":2 ,"params":{"name":'Assassin', "attack":5, "money":0, "cost":4}}
]
# create deck
test_deck = self.user.deck_creator(deck_settings)
# create expected output
expected_deck = expected()
# routine returns true if success so result must be not True
error = not self.compare_vals(test_deck, expected_deck)
return error
def newgame_settings(self):
"""Tests that new game settings match the original game settings"""
self.computer.newgame()
self.user.newgame()
self.central.newgame()
central = { # Central deck settings
'name': self.central.name,
'active': self.central.active,
'activesize': self.central.hand_size,
'supplement': self.central.supplements,
'deck': self.central.deck}
# Initial settings
pO = { # User settings
'name': self.user.name,
'health': self.user.health,
'deck': self.user.deck,
'hand': self.user.hand,
'active': self.user.active,
'hand_size': self.user.hand_size,
'discard': self.user.discard}
# Initial settings
pC = { # User settings
'name': self.computer.name,
'health': self.computer.health,
'deck': self.computer.deck,
'hand': self.computer.hand,
'active': self.computer.active,
'hand_size': self.computer.hand_size,
'discard': self.computer.discard}
test_attrs = {
"computer":{'pC':pC},
"player":{'pO':pO},
"Engine":{'central':central}}
# loop through all variables
original_settings = self.__original_newgame_settings()
error = self.__loop_compare(original_settings, test_attrs)
return error
def compare_vals(self, a, b):
"""Compares values from the game
Input::
a,b :: Iterables - recursive allowed can contain Card()
Output::
same :: boolean - True if items seem the same
Creates a list of flattened parameters using
the function flattened()
This returns most values but Card() remain.
Fundamentally, Card() contain the parameters we
need to check so an isinstance() and __dict__ rip
open each and every Card()'s attributes
We then compare sorted lists.
"""
same = False
# create unsorted flattened lists for a and b
a = [i.__dict__ if 'class' in str(type(i)) else i for i in flatten(a)]
b = [i.__dict__ if 'class' in str(type(i)) else i for i in flatten(b)]
# must sort the variables to ensure correct comparision
a = sorted(a)
b = sorted(b)
# are both items the same
same = (b == a)
return same
def __loop_compare(self, original_settings, test_attrs):
"""combined functionality for initial settings comparision
Used in:
self.replay_settings()
self.newgame_settings()
compares values from the two input lists
"""
error = False
for item_name,item in original_settings.iteritems():
if item_name == 'self': continue # don't compare self!
# loop through each class and find the class that contains
# the variable - check it is correct and verify vairables
in_class = None
attr_is_same = False
for class_name,class_attrs in test_attrs.iteritems():
# see if variable is in class
if item_name in class_attrs.keys():
in_class = class_name
if in_class:
attr_is_same = self.compare_vals(class_attrs[item_name], item)
# report error status
if in_class:
if attr_is_same:
self.logger.debug("Items are same. Found {0} in {1}".format(
item_name, in_class, attr_is_same))
else:
error = True
self.logger.warning("Items not same. Found {0} in {1}".format(
item_name, in_class, attr_is_same))
else:
self.logger.warning("Couldn't find attr: {}".format(item_name))
error=True
return error
def __original_newgame_settings(self):
"""
Creates an dict.iteritem() of all initial game
parameters.
Warning: This will return every item instanced in
this function as it uses the local() method
for item_name,item in self.initial:
globals()[item_name] = item
"""
class __old_Card(object):
def __init__(self, name, values=(0, 0), cost=1, clan=None):
self.name = name
self.cost = cost
self.values = values
self.clan = clan
def __str__(self):
return 'Name %s costing %s with attack %s and money %s' % (self.name, self.cost, self.values[0], self.values[1])
def get_attack(self):
return self.values[0]
def get_money(self):
return self.values[1]
# Initial settings
pO = { # User settings
'name': 'player one',
'health': 30,
'deck': None,
'hand': None,
'active': None,
'hand_size': 5,
'discard': None}
pC = { # PC settings
'name': 'player computer',
'health': 30,
'deck': None,
'hand': None,
'active': None,
'hand_size': 5,
'discard': None}
central = { # Central deck settings
'name': 'central',
'active': None,
'activesize': 5,
'supplement': None,
'deck': None}
sdc = [ # Central deck cards
4 * [__old_Card('Archer', (3, 0), 2)],
4 * [__old_Card('Baker', (0, 3), 2)],
3 * [__old_Card('Swordsman', (4, 0), 3)],
2 * [__old_Card('Knight', (6, 0), 5)],
3 * [__old_Card('Tailor', (0, 4), 3)],
3 * [__old_Card('Crossbowman', (4, 0), 3)],
3 * [__old_Card('Merchant', (0, 5), 4)],
4 * [__old_Card('Thug', (2, 0), 1)],
4 * [__old_Card('Thief', (1, 1), 1)],
2 * [__old_Card('Catapult', (7, 0), 6)],
2 * [__old_Card('Caravan', (1, 5), 5)],
2 * [__old_Card('Assassin', (5, 0), 4)]
]
# User's deck
playeronedeck = [
8 * [__old_Card('Serf', (0, 1), 0)],
2 * [__old_Card('Squire', (1, 0), 0)]
]
# Flatten User deck into one list
pod = list(itertools.chain.from_iterable(playeronedeck))
# Initiate User deck dictionary
pO['deck'] = pod
pO['hand'] = []
pO['discard'] = []
pO['active'] = []
# Create User deck (list of lists)
playertwodeck = [
8 * [__old_Card('Serf', (0, 1), 0)],
2 * [__old_Card('Squire', (1, 0), 0)]
]
# Flattens PC deck to one list
ptd = list(itertools.chain.from_iterable(playertwodeck))
# Initiate PC deck dictionary
pC['deck'] = ptd
pC['hand'] = []
pC['discard'] = []
pC['active'] = []
# Creating supplements
supplement = 10 * [__old_Card('Levy', (1, 2), 2)]
# Flatten central deck to one list
deck = list(itertools.chain.from_iterable(sdc))
random.shuffle(deck)
# Create central deck dictionary
central['deck'] = deck
central['supplement'] = supplement
central['active'] = []
# items = locals()
# only want to return pC, pO and central
items = {"pC":pC,"pO":pO,"central":central}
return items
class Gameplay(__CommonTest__):
"""Tests gameplay"""
def __init__(self):
"""run tests"""
# # creates a logger for the test file
get_logger(self)
self.game = game_engine.Gameplay(config.defaults)
# create classes of users and central deck
self.central = self.game.Central(**config.defaults['central'])
self.user = self.game.User(**config.defaults['user'])
self.computer = self.game.Computer(**config.defaults['computer'])
# runs all tests
tests = [
"object_interaction"
]
self.run_tests(tests)
pass
def object_interaction(self):
"""testing that classes can interact"""
def fn(class_input):
"""test fn"""
class_input.deck = "test item"
pass
self.central.test_param = "LOLCANO"
self.user.test_fn = fn
error = (self.central.test_param != "LOLCANO")
return error
class Formatting(__CommonTest__):
def __init__(self):
# # creates a logger for the test file
get_logger(self)
# runs all tests
tests = [
"formatter_names"
]
self.run_tests(tests)
pass
def formatter_names(self):
"""tests the formatting levels work correctly"""
LOGGER_NAMES = ["USER","COMPUTER", "GAME"]
colors = ["white", "cyan", "orange"]
self.logger.info("")
# loop
for test_name,c in zip(LOGGER_NAMES, colors):
small = test_name.lower()
getattr(self.logger, small)(
"KAPOW! ~ from logger.{}".format(small))
self.logger.warning("")
self.logger.warning("Visual check required.")
self.logger.warning("Hit 'e' if error anything else is a pass.")
self.logger.warning("")
for test_name,c in zip(LOGGER_NAMES, colors):
small = test_name.lower()
self.logger.warning("logger.{} should be {}".format(small,c))
error = (raw_input() == 'e')
return error
if __name__ == '__main__':
settings = Settings()
test = Gameplay()
children = ParentChild()
formatting = Formatting()