def test_string_derived_fields(): f = fields.EmailField() definitions, schema = f.get_definitions_and_schema() assert s(schema) == { 'type': 'string', 'format': 'email', } f = fields.IPv4Field() definitions, schema = f.get_definitions_and_schema() assert s(schema) == { 'type': 'string', 'format': 'ipv4', } f = fields.DateTimeField() definitions, schema = f.get_definitions_and_schema() assert s(schema) == { 'type': 'string', 'format': 'date-time', } f = fields.UriField() definitions, schema = f.get_definitions_and_schema() assert s(schema) == { 'type': 'string', 'format': 'uri', }
def test_keyword_of_fields(keyword, field_cls): s_f = StringField() n_f = NumberField() i_f = IntField() field = field_cls([n_f, Var({'role_1': s_f}), Var({'role_2': i_f})]) assert s(field.get_schema()) == {keyword: [n_f.get_schema()]} assert s(field.get_schema(role='role_1')) == { keyword: [n_f.get_schema(), s_f.get_schema()] } assert s(field.get_schema(role='role_2')) == { keyword: [n_f.get_schema(), i_f.get_schema()] } field = field_cls( Var( { 'role_1': [n_f, Var({'role_1': s_f}), Var({'role_2': i_f})], 'role_2': [Var({'role_2': i_f})], }, propagate='role_1')) assert s(field.get_schema(role='role_1')) == { keyword: [n_f.get_schema(), s_f.get_schema()] } with pytest.raises(SchemaGenerationException): field.get_schema(role='role_2')
def test_recursive_document_field(): class Tree(Document): node = fields.OneOfField([ fields.ArrayField(fields.DocumentField('self')), fields.StringField(), ]) expected_schema = { '$schema': 'http://json-schema.org/draft-04/schema#', 'definitions': { 'test_fields.Tree': { 'type': 'object', 'additionalProperties': False, 'properties': { 'node': { 'oneOf': [ { 'type': 'array', 'items': {'$ref': '#/definitions/test_fields.Tree'}, }, { 'type': 'string', }, ], }, }, }, }, '$ref': '#/definitions/test_fields.Tree', } assert s(Tree.get_schema()) == s(expected_schema)
def generate_tag_info(self): # We take the creation of an annotated tag as being a "mini-release-announcement" # and show a 'git shortlog' of the changes since the last tag that was an # ancestor of the new tag. last_tag = None try: # A bit of a hack to get that previous tag last_tag = git.describe(self.newrev + "^", abbrev="0", _quiet=True) except CalledProcessError: # Assume that this means no older tag pass extra = "" if last_tag: revision_range = last_tag + ".." + self.newrev extra = ( s( """ Changes since the last tag '%(last_tag)s': """ ) % {"last_tag": last_tag} ) else: extra = s( """ Changes: """ ) revision_range = self.newrev extra += ( s( """ %(short_log)s %(short_stat)s """ ) % {"short_log": git.shortlog(revision_range), "short_stat": git.diff(revision_range, shortstat=True)} ) return ( s( """ Tagger: %(tagger)s Date: %(date)s %(message)s %(extra)s """ ) % {"tagger": self.tagger, "date": self.date, "message": self.message, "extra": extra} )
def test_number_and_int_fields(): f = fields.NumberField(multiple_of=10) definitions, schema = f.get_definitions_and_schema() assert s(schema) == { 'type': 'number', 'multipleOf': 10, } f = fields.NumberField(minimum=0, maximum=10, exclusive_minimum=True, exclusive_maximum=True) definitions, schema = f.get_definitions_and_schema() assert s(schema) == { 'type': 'number', 'exclusiveMinimum': True, 'exclusiveMaximum': True, 'minimum': 0, 'maximum': 10, } f = fields.NumberField(enum=(1, 2, 3)) definitions, schema = f.get_definitions_and_schema() assert s(schema) == { 'type': 'number', 'enum': [1, 2, 3], } f = fields.IntField() definitions, schema = f.get_definitions_and_schema() assert s(schema) == { 'type': 'integer', }
def test_string_field(): f = fields.StringField() definitions, schema = f.get_definitions_and_schema() assert s(schema) == {'type': 'string'} f = fields.StringField(min_length=1, max_length=10, pattern='^test$', enum=('a', 'b', 'c'), title='Pururum') expected_items = [ ('type', 'string'), ('title', 'Pururum'), ('enum', ['a', 'b', 'c']), ('pattern', '^test$'), ('minLength', 1), ('maxLength', 10), ] definitions, schema = f.get_definitions_and_schema() assert s(schema) == dict(expected_items) definitions, ordered_schema = f.get_definitions_and_schema(ordered=True) assert isinstance(ordered_schema, OrderedDict) assert s(ordered_schema) == OrderedDict(expected_items) with pytest.raises(ValueError) as e: fields.StringField(pattern='(') assert str(e.value) == 'Invalid regular expression: unbalanced parenthesis'
def test_document_field(): document_cls_mock = mock.Mock() expected_schema = mock.Mock() attrs = { 'get_definitions_and_schema.return_value': ({}, expected_schema), 'get_definition_id.return_value': 'document.Document', 'is_recursive.return_value': False, } document_cls_mock.configure_mock(**attrs) f = fields.DocumentField(document_cls_mock) definitions, schema = f.get_definitions_and_schema() assert schema == expected_schema assert not definitions definitions, schema = f.get_definitions_and_schema(ref_documents=set([document_cls_mock])) assert s(schema) == {'$ref': '#/definitions/document.Document'} f = fields.DocumentField(document_cls_mock, as_ref=True) definitions, schema = f.get_definitions_and_schema() assert definitions == {'document.Document': expected_schema} assert s(schema) == {'$ref': '#/definitions/document.Document'} attrs = { 'get_definitions_and_schema.return_value': ({}, expected_schema), 'get_definition_id.return_value': 'document.Document', 'is_recursive.return_value': True, } document_cls_mock.reset_mock() document_cls_mock.configure_mock(**attrs) f = fields.DocumentField(document_cls_mock, as_ref=True) definitions, schema = f.get_definitions_and_schema() assert schema == expected_schema assert not definitions
def get_body(self): if len(self.added_commits) > 0: return ( s( """ The branch '%(short_refname)s' was created. Summary of new commits: %(summary)s """ ) % {"short_refname": self.short_refname, "summary": self.generate_commit_summary(self.added_commits)} ) else: return ( s( """ The branch '%(short_refname)s' was created pointing to: %(commit_oneline)s """ ) % {"short_refname": self.short_refname, "commit_oneline": commit_oneline(self.newrev)} )
def get_coq_output(coqc_prog, coqc_prog_args, contents, timeout_val, cwd=None, is_coqtop=False, pass_on_stdin=False, verbose_base=1, **kwargs): """Returns the coqc output of running through the given contents. Pass timeout_val = None for no timeout.""" global TIMEOUT if timeout_val is not None and timeout_val < 0 and TIMEOUT is not None: return get_coq_output(coqc_prog, coqc_prog_args, contents, TIMEOUT, cwd=cwd, is_coqtop=is_coqtop, pass_on_stdin=pass_on_stdin, verbose_base=verbose_base, **kwargs) key, file_name, cmds, input_val = prepare_cmds_for_coq_output( coqc_prog, coqc_prog_args, contents, cwd=cwd, timeout_val=timeout_val, is_coqtop=is_coqtop, pass_on_stdin=pass_on_stdin, verbose_base=verbose_base, **kwargs) if key in COQ_OUTPUT.keys(): return COQ_OUTPUT[key][1] start = time.time() ((stdout, stderr), returncode) = memory_robust_timeout_Popen_communicate( kwargs['log'], cmds, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, stdin=subprocess.PIPE, timeout=(timeout_val if timeout_val is not None and timeout_val > 0 else None), input=input_val, cwd=cwd) finish = time.time() if kwargs['verbose'] >= verbose_base + 1: kwargs['log']('\nretcode: %d\nstdout:\n%s\n\nstderr:\n%s\n\n' % (returncode, util.s(stdout), util.s(stderr))) if TIMEOUT is None and timeout_val is not None: TIMEOUT = 3 * max((1, int(math.ceil(finish - start)))) clean_v_file(file_name) ## remove instances of the file name #stdout = stdout.replace(os.path.basename(file_name[:-2]), 'Top') COQ_OUTPUT[key] = (file_name, (clean_output(util.s(stdout)), tuple(cmds), returncode)) return COQ_OUTPUT[key][1]
def test_basics(): class User(Document): id = Var({ 'response': IntField(required=True) }) login = StringField(required=True) class Task(Document): class Options(object): title = 'Task' description = 'A task.' definition_id = 'task' id = IntField(required=Var({'response': True})) name = StringField(required=True, min_length=5) type = StringField(required=True, enum=['TYPE_1', 'TYPE_2']) created_at = DateTimeField(required=True) author = Var({'response': DocumentField(User)}) assert s(Task.get_schema()) == s({ '$schema': 'http://json-schema.org/draft-04/schema#', 'additionalProperties': False, 'description': 'A task.', 'properties': { 'created_at': {'format': 'date-time', 'type': 'string'}, 'id': {'type': 'integer'}, 'name': {'minLength': 5, 'type': 'string'}, 'type': {'enum': ['TYPE_1', 'TYPE_2'], 'type': 'string'} }, 'required': ['created_at', 'type', 'name'], 'title': 'Task', 'type': 'object' }) assert s(Task.get_schema(role='response')) == s({ '$schema': 'http://json-schema.org/draft-04/schema#', 'title': 'Task', 'description': 'A task.', 'type': 'object', 'additionalProperties': False, 'properties': { 'created_at': {'format': 'date-time', 'type': 'string'}, 'id': {'type': 'integer'}, 'name': {'minLength': 5, 'type': 'string'}, 'type': {'enum': ['TYPE_1', 'TYPE_2'], 'type': 'string'}, 'author': { 'additionalProperties': False, 'properties': { 'id': {'type': 'integer'}, 'login': {'type': 'string'} }, 'required': ['id', 'login'], 'type': 'object' }, }, 'required': ['created_at', 'type', 'name', 'id'], })
def test_inheritance_2(): class Base(Document): class Options(object): inheritance_mode = ALL_OF definition_id = 'base' title = 'Base' a = StringField() class Child(Base): class Options(object): definition_id = 'child' title = 'Child' b = StringField() c = DocumentField(RECURSIVE_REFERENCE_CONSTANT) expected_schema = { "definitions": { "base": { "type": "object", "title": "Base", "properties": { "a": { "type": "string" } }, "additionalProperties": False, }, "child": { "allOf": [ { "$ref": "#/definitions/base" }, { "type": "object", "title": "Child", "properties": { "c": { "$ref": "#/definitions/child" }, "b": { "type": "string" } }, "additionalProperties": False, } ] } }, "$schema": "http://json-schema.org/draft-04/schema#", "$ref": "#/definitions/child" } schema = Child.get_schema() assert s(schema) == s(expected_schema)
def generate_tag_info(self): # We take the creation of an annotated tag as being a "mini-release-announcement" # and show a 'git shortlog' of the changes since the last tag that was an # ancestor of the new tag. last_tag = None try: # A bit of a hack to get that previous tag last_tag = git.describe(self.newrev + "^", abbrev='0', _quiet=True) except CalledProcessError: # Assume that this means no older tag pass extra = "" if last_tag: revision_range = last_tag + ".." + self.newrev extra = s(""" Changes since the last tag '%(last_tag)s': """) % { 'last_tag': last_tag } else: extra = s(""" Changes: """) revision_range = self.newrev extra += s(""" %(short_log)s %(short_stat)s """) % { 'short_log': git.shortlog(revision_range), 'short_stat': git.diff(revision_range, shortstat=True) } return s(""" Tagger: %(tagger)s Date: %(date)s %(message)s %(extra)s """) % { 'tagger': self.tagger, 'date': self.date, 'message': self.message, 'extra': extra }
def test_recursive_definitions_3(): class Main(Document): a = DocumentField('test_document.A') b = DocumentField('B') class A(Document): name = StringField() a = DocumentField('A', as_ref=True) class B(Document): c = DocumentField('C') class C(Document): name = StringField() c = DocumentField('C') expected_schema = { '$schema': 'http://json-schema.org/draft-04/schema#', 'definitions': { 'test_document.A': { 'type': 'object', 'additionalProperties': False, 'properties': { 'a': {'$ref': '#/definitions/test_document.A'}, 'name': {'type': 'string'} }, }, 'test_document.C': { 'type': 'object', 'additionalProperties': False, 'properties': { 'c': {'$ref': '#/definitions/test_document.C'}, 'name': {'type': 'string'} }, } }, 'type': 'object', 'additionalProperties': False, 'properties': { 'a': {'$ref': '#/definitions/test_document.A'}, 'b': { 'type': 'object', 'additionalProperties': False, 'properties': { 'c': { '$ref': '#/definitions/test_document.C' } }, } }, } assert s(Main.get_schema()) == s(expected_schema)
def test_string_field(): _ = lambda value: Var({'role_1': value}) field = StringField(format=_('date-time'), min_length=_(1), max_length=_(2)) assert s(field.get_schema()) == s({'type': 'string'}) assert s(field.get_schema(role='role_1')) == s({ 'type': 'string', 'format': 'date-time', 'minLength': 1, 'maxLength': 2, }) with pytest.raises(ValueError) as e: StringField(pattern=_('(')) assert str(e.value) == 'Invalid regular expression: unbalanced parenthesis'
def test_not_field(): f = fields.NotField(fields.StringField(), description='Not a string.') expected_schema = { 'description': 'Not a string.', 'not': {'type': 'string'}, } assert s(f.get_schema()) == expected_schema
def test_string_field(): _ = lambda value: Var({'role_1': value}) field = StringField(format=_('date-time'), min_length=_(1), max_length=_(2)) assert s(field.get_schema()) == s({ 'type': 'string' }) assert s(field.get_schema(role='role_1')) == s({ 'type': 'string', 'format': 'date-time', 'minLength': 1, 'maxLength': 2, }) with pytest.raises(ValueError) as e: StringField(pattern=_('(')) assert str(e.value) == 'Invalid regular expression: unbalanced parenthesis'
def generate_body_non_fast_forward(self): return s(""" The branch '%(short_refname)s' was changed in a way that was not a fast-forward update. NOTE: This may cause problems for people pulling from the branch. For more information, please see: http://live.gnome.org/Git/Help/NonFastForward Commits removed from the branch: %(commits_removed)s Commits added to the branch: %(commits_added)s """) % { 'short_refname': self.short_refname, 'commits_removed': self.generate_commit_summary(self.removed_commits, show_details=False), 'commits_added': self.generate_commit_summary(self.added_commits) }
def get_coqc_config_helper(coqc): p = subprocess.Popen([coqc, "-q", "-config"], stderr=subprocess.STDOUT, stdout=subprocess.PIPE, stdin=subprocess.PIPE) (stdout, stderr) = p.communicate() return util.s(stdout).replace('\r\n', '\n').strip()
def get_body(self): return ( s( """ The tag '%(short_refname)s' was replaced with a new tag. It previously pointed to: %(old_commit_oneline)s NOTE: People pulling from the repository will not get the new tag. For more information, please see: http://live.gnome.org/Git/Help/TagUpdates New tag information: %(tag_info)s """ ) % { "short_refname": self.short_refname, "old_commit_oneline": commit_oneline(self.old_commit_id), "tag_info": self.generate_tag_info(), } )
def get_coqc_help_helper(coqc): p = subprocess.Popen([coqc, "-q", "--help"], stderr=subprocess.STDOUT, stdout=subprocess.PIPE, stdin=subprocess.PIPE) (stdout, stderr) = p.communicate() return util.s(stdout).strip()
def sendDefinitions(self, acronyms, channel): if not acronyms: self.sendMessage(channel, 'No acronyms found.') return attachments = [] definition_number = 0 for abbreviation, acronym, confidence in acronyms: attachment = {} attachment['title'] = abbreviation.upper() attachment['mrkdwn_in'] = ['text'] if acronym: attachment['fallback'] = acronym.getFallbackText() attachment['text'] = '\n'.join([md.toSlack(x.definition) for x in acronym.definitions]) attachment['color'] = '#ccaa55' definition_number += len(acronym.definitions) else: attachment['fallback'] = abbreviation.upper() + ': not found' attachment['text'] = 'not found' attachment['color'] = 'danger' attachments.append(attachment) self.sendMessage(channel, 'Found ' + str(definition_number) + ' definition' + util.s(definition_number), attachments)
def generate_body_non_fast_forward(self): return ( s( """ The branch '%(short_refname)s' was changed in a way that was not a fast-forward update. NOTE: This may cause problems for people pulling from the branch. For more information, please see: http://live.gnome.org/Git/Help/NonFastForward Commits removed from the branch: %(commits_removed)s Commits added to the branch: %(commits_added)s """ ) % { "short_refname": self.short_refname, "commits_removed": self.generate_commit_summary(self.removed_commits, show_details=False), "commits_added": self.generate_commit_summary(self.added_commits), } )
def test_array_field(): s_f = StringField() n_f = NumberField() field = ArrayField(Var({ 'role_1': s_f, 'role_2': n_f, })) schema = s(field.get_schema(role='role_1')) assert s(schema['items']) == s_f.get_schema() schema = s(field.get_schema(role='role_2')) assert schema['items'] == n_f.get_schema() schema = s(field.get_schema()) assert 'items' not in schema _ = lambda value: Var({'role_1': value}) field = ArrayField(s_f, min_items=_(1), max_items=_(2), unique_items=_(True), additional_items=_(True)) assert s(field.get_schema()) == s({ 'type': 'array', 'items': s_f.get_schema(), }) assert field.get_schema(role='role_1') == s({ 'type': 'array', 'items': s_f.get_schema(), 'minItems': 1, 'maxItems': 2, 'uniqueItems': True, 'additionalItems': True, })
def get_coqc_version_helper(coqc): p = subprocess.Popen([coqc, "-q", "-v"], stderr=subprocess.STDOUT, stdout=subprocess.PIPE, stdin=subprocess.PIPE) (stdout, stderr) = p.communicate() return util.s(stdout).replace('The Coq Proof Assistant, version ', '').replace('\r\n', ' ').replace('\n', ' ').strip()
def generate_body_normal(self): return s(""" Summary of changes: %(summary)s """) % { 'summary': self.generate_commit_summary(self.added_commits) }
def get_coqtop_version_helper(coqtop): p = subprocess.Popen([coqtop, "-q"], stderr=subprocess.PIPE, stdout=subprocess.PIPE, stdin=subprocess.PIPE) (stdout, stderr) = p.communicate() return util.s(stdout).replace('Welcome to Coq ', '').replace( 'Skipping rcfile loading.', '').replace('\r\n', ' ').replace('\n', ' ').strip()
def get_body(self): return ( s( """ The branch '%(short_refname)s' was deleted. """ ) % {"short_refname": self.short_refname} )
def get_body(self): return ( s( """ The ref '%(refname)s' was deleted. It previously pointed nowhere. """ ) % {"refname": self.refname} )
def get_body(self): return s(""" The pull-request ref '%(refname)s' was merged. A new ref has been created for the merge pointing to: %(newrev)s """) % { 'refname': self.refname, 'oldrev': self.oldrev, }
def get_body(self): return s(""" The lightweight tag '%(short_refname)s' was created pointing to: %(commit_oneline)s """) % { 'short_refname': self.short_refname, 'commit_oneline': commit_oneline(self.newrev) }
def get_body(self): return s(""" The lighweight tag '%(short_refname)s' was deleted. It previously pointed to: %(commit_oneline)s """) % { 'short_refname': self.short_refname, 'commit_oneline': commit_oneline(self.oldrev) }
def get_coq_accepts_top(coqc): temp_file = tempfile.NamedTemporaryFile(suffix='.v', dir='.', delete=True) temp_file_name = temp_file.name p = subprocess.Popen([coqc, "-q", "-top", "Top", temp_file_name], stderr=subprocess.STDOUT, stdout=subprocess.PIPE) (stdout, stderr) = p.communicate() temp_file.close() clean_v_file(temp_file_name) return '-top: no such file or directory' not in util.s(stdout)
def get_coq_statement_ranges(file_name, coqc, **kwargs): kwargs = fill_kwargs(kwargs) if not get_coq_accepts_time(coqc, **kwargs): raise UnsupportedCoqVersionError p = subprocess.Popen([coqc, '-q', '-time'] + list(kwargs['coqc_args']) + [file_name], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE) (stdout, stderr) = p.communicate() ranges = tuple((int(start), int(finish)) for start, finish in RANGE_REG.findall(util.s(stdout))) return ranges
def get_body(self): return s(""" The ref for a pull request '%(refname)s' was created pointing to: %(newrev)s """) % { 'refname': self.refname, 'oldrev': self.oldrev, }
def get_body(self): return s(""" The %(tag_type)s '%(short_refname)s' was created. %(tag_info)s """) % { 'tag_type': self.get_tag_type(), 'short_refname': self.short_refname, 'tag_info': self.generate_tag_info() }
def get_body(self): return s(""" The %(tag_type)s '%(short_refname)s' was deleted. It previously pointed to: %(old_commit_oneline)s """) % { 'tag_type': self.get_tag_type(), 'short_refname': self.short_refname, 'old_commit_oneline': commit_oneline(self.old_commit_id) }
def parse_argument_list(klass, args): """ Collects options from the given argument list, returning any unparsable ones. """ #''' if klass._cache: print ( "Warning: Option%s %s set before command-line parsing" % (s(len(klass._cache)), expand_list(klass._cache.keys())) ) result = [arg for arg in args if not klass.parse_argument(arg)] return result
def get_body(self): return ( s( """ The ref for a pull request '%(refname)s' was created pointing to: %(newrev)s """ ) % {"refname": self.refname, "oldrev": self.oldrev} )
def test_recursive_definitions_5(): # regression test for https://github.com/aromanovich/jsl/issues/14 class Test(Document): class Options(object): definition_id = 'test' with Scope('test') as test: test.field = DocumentField(RECURSIVE_REFERENCE_CONSTANT) assert s(Test.get_schema(role='test')) == s({ '$schema': 'http://json-schema.org/draft-04/schema#', '$ref': '#/definitions/test', 'definitions': { 'test': { 'additionalProperties': False, 'type': 'object', 'properties': { 'field': { '$ref': '#/definitions/test' } } } }, })
def test_recursive_definitions_6(): # regression test for https://github.com/aromanovich/jsl/issues/16 class Children(Document): class Options(object): definition_id = 'children' children = OneOfField([ DocumentField('A',), ]) class A(Document): class Options(object): definition_id = 'a' derived_from = DocumentField(Children, as_ref=True) assert s(A.get_schema()) == s({ '$schema': 'http://json-schema.org/draft-04/schema#', 'definitions': { 'a': { 'type': 'object', 'properties': { 'derived_from': { '$ref': '#/definitions/children', }, }, 'additionalProperties': False, }, 'children': { 'type': 'object', 'properties': { 'children': { 'oneOf': [{'$ref': '#/definitions/a'}], }, }, 'additionalProperties': False, }, }, '$ref': '#/definitions/a', })
def get_body(self): return s(""" The ref '%(refname)s' was deleted. It previously pointed to: %(oldrev)s This is unexpected because: %(message)s """) % { 'refname': self.refname, 'oldrev': self.oldrev, 'message': self.message }