Skip to content

Commit 90fbd53

Browse files
committed
Test and fix extension loading components
1 parent af88107 commit 90fbd53

File tree

4 files changed

+53
-22
lines changed

4 files changed

+53
-22
lines changed

extension_use_test.yaml

+18-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,28 @@
22
---
33
- config:
44
- testset: "Simple github.com API Test with custom validator"
5+
- generators:
6+
- 'number' : {type: 'doubling', start: 8}
57
- test:
68
- name: "Test with successful validations"
79
- url: "/search/users?q=jewzaam"
810
- group: "Successful"
911
- validators:
1012
- contains: 'subscriptions_url'
11-
#- extract_test: {jsonpath_mini: 'items', test: 'has_braces'}
13+
- extract_test: {jsonpath_mini: 'items.0', test: 'is_dict'}
1214
- compare: {jsonpath_mini: 'items.0.login', comparator: 'str.eq.lower', expected: 'JewZaam'}
13-
#- extract_test: {'weirdzo': 'blah', test: 'exists'}
15+
- extract_test: {'weirdzo': 'blah', test: 'exists'}
16+
- test:
17+
- generator_binds: {num: number}
18+
- name: "Test with generator"
19+
- url: {template: "/search/users?q=$num&in=id"}
20+
- group: "Successful"
21+
- validators:
22+
- compare: {jsonpath_mini: 'items.0.login', comparator: 'contains', expected: '8'}
23+
- test:
24+
- generator_binds: {num: number}
25+
- name: "Test with generator run 2"
26+
- url: {template: "/search/users?q=$num&in=id"}
27+
- group: "Successful"
28+
- validators:
29+
- compare: {jsonpath_mini: 'items.0.login', comparator: 'contains', expected: '16'}

pyresttest/resttest.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -591,9 +591,9 @@ def register_extensions(modules):
591591
# Extensions are registered by applying a register function to sets of registry name/function pairs inside an object
592592
extension_applies = {
593593
'VALIDATORS': validators.register_validator,
594-
'VALIDATOR_COMPARATORS': validators.register_comparator,
594+
'COMPARATORS': validators.register_comparator,
595595
'VALIDATOR_TESTS': validators.register_test,
596-
'VALIDATOR_EXTRACTORS': validators.register_extractor,
596+
'EXTRACTORS': validators.register_extractor,
597597
'GENERATORS': generators.register_generator
598598
}
599599

pyresttest/validators.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -203,14 +203,14 @@ def _get_extractor(config_dict):
203203
if key in EXTRACTORS:
204204
return parse_extractor(key, value)
205205
else: # No valid extractor
206-
return None
206+
raise Exception('No valid extractor name to use in input: {0}'.format(config_dict))
207207

208208
class AbstractValidator(object):
209209
""" Encapsulates basic validator handling """
210210
name = None
211211
config = None
212212

213-
def validate(self, body, context=None):
213+
def validate(self, body=None, headers=None, context=None):
214214
""" Run the validation function, return true or a ValidationFailure """
215215
pass
216216

@@ -227,7 +227,7 @@ class ComparatorValidator(AbstractValidator):
227227

228228
def validate(self, body=None, headers=None, context=None):
229229
try :
230-
extracted_val = self.extractor.extract(body, context=context)
230+
extracted_val = self.extractor.extract(body=body, headers=headers, context=context)
231231
except Exception as e:
232232
return ValidationFailure(message="Extractor threw exception", details=e, validator=self)
233233

@@ -327,9 +327,9 @@ def parse(config):
327327
output.test_fn = test_fn
328328
return output
329329

330-
def validate(self, body, context=None):
330+
def validate(self, body=None, headers=None, context=None):
331331
try:
332-
extracted = self.extractor.extract(body, context=context)
332+
extracted = self.extractor.extract(body=body, headers=headers, context=context)
333333
except Exception as e:
334334
return ValidationFailure(message="Exception thrown while running extraction from body", details=e, validator=self)
335335

@@ -355,6 +355,11 @@ def parse_extractor(extractor_type, config):
355355

356356
if isinstance(parsed, AbstractExtractor): # Parser gave a full extractor
357357
return parsed
358+
359+
# Look for matching attributes... simple inheritance has issues because of cross-module loading
360+
items = AbstractExtractor().__dict__
361+
if set(parsed.__dict__.keys()).issuperset(set(items.keys())):
362+
return parsed
358363
else:
359364
raise TypeError("Parsing functions for extractors must return an AbstractExtractor instance!")
360365

sample_extension.py

+23-13
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,10 @@ def parse(config):
2525
validator.contains_string = config
2626
return validator
2727

28-
def test_has_braces(input_string):
29-
""" Test if input string contains a brace ({}) """
30-
return '{' in input_string or '}' in input_string
31-
32-
3328
class WeirdzoExtractor(validators.AbstractExtractor):
34-
extractor_type = 'weirdozo'
29+
""" Always returns 'zorba' """
30+
31+
extractor_type = 'weirdzo'
3532
is_body_extractor = True
3633

3734
@classmethod
@@ -44,17 +41,30 @@ def parse(cls, config, extractor_base=None):
4441
def extract_internal(self, query=None, args=None, body=None, headers=None):
4542
return 'zorba'
4643

44+
def parse_generator_doubling(config):
45+
""" Returns generators that double with each value returned, config includes start value """
46+
start = 1
47+
if 'start' in config:
48+
start = int(config['start'])
4749

48-
def parse_extractor_weirdzo(config):
49-
""" Parser for extractor config that always ignores config
50-
and returns the extract_weirdzo function """
51-
return extract_weirdzo
50+
# We cannot simply use start as the variable, because of scoping limitations
51+
def generator():
52+
val = start
53+
while(True):
54+
yield val
55+
val = val*2
56+
return generator()
5257

58+
def test_is_dict(input):
59+
""" Simple test that returns true if item is a dictionary """
60+
return isinstance(input, dict)
5361

5462
# This is where the magic happens, each one of these is a registry of validators/extractors/generators to use
5563
VALIDATORS = {'contains': ContainsValidator.parse}
56-
VALIDATOR_TESTS = {'has_braces': test_has_braces}
64+
VALIDATOR_TESTS = {'is_dict': test_is_dict}
65+
5766
# Converts to lowercase and tests for equality
58-
VALIDATOR_COMPARATORS = {'str.eq.lower': lambda a,b: str(a).lower() == str(b).lower()}
67+
COMPARATORS = {'str.eq.lower': lambda a,b: str(a).lower() == str(b).lower()}
5968

60-
EXTRACTORS = {'weirdzo': WeirdzoExtractor.parse}
69+
EXTRACTORS = {'weirdzo': WeirdzoExtractor.parse}
70+
GENERATORS = {'doubling': parse_generator_doubling}

0 commit comments

Comments
 (0)