diff --git a/MANIFEST.in b/MANIFEST.in index c0f653ab..3df67dcf 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -18,6 +18,5 @@ recursive-include docs *.txt *.rst conf.py Makefile make.bat *.jpg *.png *.gif recursive-include docs/code_examples *.py prune docs/_build -prune gql-checker global-exclude *.py[co] __pycache__ diff --git a/gql-checker/.gitignore b/gql-checker/.gitignore deleted file mode 100644 index fe0fe6cc..00000000 --- a/gql-checker/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -*.pyc -*.pyo -__pycache__ -*.egg-info -*~ -.coverage -.tox/ -build/ -dist/ diff --git a/gql-checker/.travis.yml b/gql-checker/.travis.yml deleted file mode 100644 index eb155b3b..00000000 --- a/gql-checker/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: python -addons: - apt: - sources: - - deadsnakes - packages: - - python3.5 -install: - - pip install tox -script: - - tox -sudo: false diff --git a/gql-checker/LICENSE b/gql-checker/LICENSE deleted file mode 100644 index 141776c3..00000000 --- a/gql-checker/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 GraphQL Python - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/gql-checker/MANIFEST.in b/gql-checker/MANIFEST.in deleted file mode 100644 index 93eaa028..00000000 --- a/gql-checker/MANIFEST.in +++ /dev/null @@ -1,4 +0,0 @@ -include LICENSE -include README.md -recursive-include tests * -recursive-exclude tests *.py[co] diff --git a/gql-checker/README.rst b/gql-checker/README.rst deleted file mode 100644 index 1fd9c42b..00000000 --- a/gql-checker/README.rst +++ /dev/null @@ -1,29 +0,0 @@ -gql-checker -=========== - -|Build Status| - -A `flake8 `__ and -`Pylama `__ plugin that checks the -all the static gql calls given a GraphQL schema. - -It will not check anything else about the gql calls. Merely that the -GraphQL syntax is correct and it validates against the provided schema. - -Warnings --------- - -This package adds 3 new flake8 warnings - -- ``GQL100``: The gql query is doesn't match GraphQL syntax -- ``GQL101``: The gql query have valid syntax but doesn't validate against provided schema - -Configuration -------------- - -You will want to set the ``gql-introspection-schema`` option to a -file with the json introspection of the schema. - - -.. |Build Status| image:: https://travis-ci.org/graphql-python/gql-checker.png?branch=master - :target: https://travis-ci.org/graphql-python/gql-checker diff --git a/gql-checker/gql_checker/__about__.py b/gql-checker/gql_checker/__about__.py deleted file mode 100644 index c2f25195..00000000 --- a/gql-checker/gql_checker/__about__.py +++ /dev/null @@ -1,18 +0,0 @@ -__all__ = [ - "__title__", "__summary__", "__uri__", "__version__", "__author__", - "__email__", "__license__", "__copyright__", -] - -__title__ = "gql-checker" -__summary__ = ( - "Flake8 and pylama plugin that checks gql GraphQL calls." -) -__uri__ = "https://github.com/graphql-python/gql-checker" - -__version__ = "0.1" - -__author__ = "Syrus Akbary" -__email__ = "me@syrusakbary.com" - -__license__ = "MIT" -__copyright__ = "Copyright 2016 %s" % __author__ diff --git a/gql-checker/gql_checker/__init__.py b/gql-checker/gql_checker/__init__.py deleted file mode 100644 index 8b8f09bd..00000000 --- a/gql-checker/gql_checker/__init__.py +++ /dev/null @@ -1,118 +0,0 @@ -import ast -import json - -import pycodestyle - -from gql_checker.__about__ import ( - __author__, __copyright__, __email__, __license__, __summary__, __title__, - __uri__, __version__ -) -from gql_checker.stdlib_list import STDLIB_NAMES -from graphql import Source, validate, parse, build_client_schema - - -__all__ = [ - "__title__", "__summary__", "__uri__", "__version__", "__author__", - "__email__", "__license__", "__copyright__", -] - -GQL_SYNTAX_ERROR = 'GQL100' -GQL_VALIDATION_ERROR = 'GQL101' - -class ImportVisitor(ast.NodeVisitor): - """ - This class visits all the gql calls. - """ - - def __init__(self, filename, options): - self.filename = filename - self.options = options or {} - self.calls = [] - - def visit_Call(self, node): # noqa - if node.func.id == 'gql': - self.calls.append(node) - - def node_query(self, node): - """ - Return the query for the gql call node - """ - - if isinstance(node, ast.Call): - assert node.args - arg = node.args[0] - if not isinstance(arg, ast.Str): - return - else: - raise TypeError(type(node)) - - return arg.s - - -class ImportOrderChecker(object): - visitor_class = ImportVisitor - options = None - - def __init__(self, filename, tree): - self.tree = tree - self.filename = filename - self.lines = None - - def load_file(self): - if self.filename in ("stdin", "-", None): - self.filename = "stdin" - self.lines = pycodestyle.stdin_get_value().splitlines(True) - else: - self.lines = pycodestyle.readlines(self.filename) - - if not self.tree: - self.tree = ast.parse("".join(self.lines)) - - def get_schema(self): - gql_introspection_schema = self.options.get('gql_introspection_schema') - if gql_introspection_schema: - try: - with open(gql_introspection_schema) as data_file: - introspection_schema = json.load(data_file) - return build_client_schema(introspection_schema) - except IOError as e: - raise Exception(f"Cannot find the provided introspection schema. {e}") - - schema = self.options.get('schema') - assert schema, 'Need to provide schema' - - def validation_errors(self, ast): - return validate(self.get_schema(), ast) - - def error(self, node, code, message): - raise NotImplemented() - - def check_gql(self): - if not self.tree or not self.lines: - self.load_file() - - visitor = self.visitor_class(self.filename, self.options) - visitor.visit(self.tree) - - for node in visitor.calls: - # Lines with the noqa flag are ignored entirely - if pycodestyle.noqa(self.lines[node.lineno - 1]): - continue - - query = visitor.node_query(node) - if not query: - continue - - try: - source = Source(query, 'gql query') - ast = parse(source) - except Exception as e: - message = str(e) - yield self.error(node, GQL_SYNTAX_ERROR, message) - continue - - validation_errors = self.validation_errors(ast) - if validation_errors: - for error in validation_errors: - message = str(error) - yield self.error(node, GQL_VALIDATION_ERROR, message) diff --git a/gql-checker/gql_checker/flake8_linter.py b/gql-checker/gql_checker/flake8_linter.py deleted file mode 100644 index 009421c1..00000000 --- a/gql-checker/gql_checker/flake8_linter.py +++ /dev/null @@ -1,50 +0,0 @@ -from __future__ import absolute_import - -import gql_checker -from gql_checker import ImportOrderChecker - - -class Linter(ImportOrderChecker): - name = "gql" - version = gql_checker.__version__ - - def __init__(self, tree, filename): - super(Linter, self).__init__(filename, tree) - - @classmethod - def add_options(cls, parser): - # List of application import names. They go last. - parser.add_option( - "--gql-introspection-schema", - metavar="FILE", - help="Import names to consider as application specific" - ) - parser.add_option( - "--gql-typedef-schema", - default='', - action="store", - type="string", - help=("Style to follow. Available: " - "cryptography, google, smarkets, pep8") - ) - parser.config_options.append("gql-introspection-schema") - parser.config_options.append("gql-typedef-schema") - - @classmethod - def parse_options(cls, options): - optdict = {} - - optdict = dict( - gql_introspection_schema=options.gql_introspection_schema, - gql_typedef_schema=options.gql_typedef_schema, - ) - - cls.options = optdict - - def error(self, node, code, message): - lineno, col_offset = node.lineno, node.col_offset - return lineno, col_offset, f'{code} {message}', Linter - - def run(self): - for error in self.check_gql(): - yield error diff --git a/gql-checker/gql_checker/pylama_linter.py b/gql-checker/gql_checker/pylama_linter.py deleted file mode 100644 index 994e6e19..00000000 --- a/gql-checker/gql_checker/pylama_linter.py +++ /dev/null @@ -1,36 +0,0 @@ -from __future__ import absolute_import - -from pylama.lint import Linter as BaseLinter - -import gql_checker -from gql_checker import ImportOrderChecker - - -class Linter(ImportOrderChecker, BaseLinter): - name = "gql" - version = gql_checker.__version__ - - def __init__(self): - super(Linter, self).__init__(None, None) - - def allow(self, path): - return path.endswith(".py") - - def error(self, node, code, message): - lineno, col_offset = node.lineno, node.col_offset - return { - "lnum": lineno, - "col": col_offset, - "text": message, - "type": code - } - - def run(self, path, **meta): - self.filename = path - self.tree = None - self.options = dict( - {'schema': ''}, - **meta) - - for error in self.check_gql(): - yield error diff --git a/gql-checker/gql_checker/stdlib_list.py b/gql-checker/gql_checker/stdlib_list.py deleted file mode 100644 index 4552d422..00000000 --- a/gql-checker/gql_checker/stdlib_list.py +++ /dev/null @@ -1,330 +0,0 @@ -STDLIB_NAMES = set(( - "AL", - "BaseHTTPServer", - "Bastion", - "Binary", - "Boolean", - "CGIHTTPServer", - "ColorPicker", - "ConfigParser", - "Cookie", - "DEVICE", - "DocXMLRPCServer", - "EasyDialogs", - "FL", - "FrameWork", - "GL", - "HTMLParser", - "MacOS", - "Mapping", - "MimeWriter", - "MiniAEFrame", - "Numeric", - "Queue", - "SUNAUDIODEV", - "ScrolledText", - "Sequence", - "Set", - "SimpleHTTPServer", - "SimpleXMLRPCServer", - "SocketServer", - "StringIO", - "Text", - "Tix", - "Tkinter", - "UserDict", - "UserList", - "UserString", - "__builtin__", - "__future__", - "__main__", - "_dummy_thread", - "_thread", - "abc", - "aepack", - "aetools", - "aetypes", - "aifc", - "al", - "anydbm", - "argparse", - "array", - "ast", - "asynchat", - "asyncio", - "asyncore", - "atexit", - "audioop", - "autoGIL", - "base64", - "bdb", - "binascii", - "binhex", - "bisect", - "bsddb", - "builtins", - "bz2", - "cPickle", - "cProfile", - "cStringIO", - "calendar", - "cd", - "cgi", - "cgitb", - "chunk", - "cmath", - "cmd", - "code", - "codecs", - "codeop", - "collections", - "collections.abc", - "colorsys", - "commands", - "compileall", - "concurrent.futures", - "configparser", - "contextlib", - "cookielib", - "copy", - "copy_reg", - "copyreg", - "crypt", - "csv", - "ctypes", - "curses", - "curses.ascii", - "curses.panel", - "curses.textpad", - "curses.wrapper", - "datetime", - "dbhash", - "dbm", - "decimal", - "difflib", - "dircache", - "dis", - "distutils", - "dl", - "doctest", - "dumbdbm", - "dummy_thread", - "dummy_threading", - "email", - "ensurepip", - "enum", - "errno", - "faulthandler", - "fcntl", - "filecmp", - "fileinput", - "findertools", - "fl", - "flp", - "fm", - "fnmatch", - "formatter", - "fpectl", - "fpformat", - "fractions", - "ftplib", - "functools", - "future_builtins", - "gc", - "gdbm", - "gensuitemodule", - "getopt", - "getpass", - "gettext", - "gl", - "glob", - "grp", - "gzip", - "hashlib", - "heapq", - "hmac", - "hotshot", - "html", - "html.entities", - "html.parser", - "htmlentitydefs", - "htmllib", - "http", - "http.client", - "http.cookiejar", - "http.cookies", - "http.server", - "httplib", - "ic", - "imageop", - "imaplib", - "imgfile", - "imghdr", - "imp", - "importlib", - "imputil", - "inspect", - "io", - "ipaddress", - "itertools", - "jpeg", - "json", - "keyword", - "linecache", - "locale", - "logging", - "logging.config", - "logging.handlers", - "lzma", - "macostools", - "macpath", - "macurl2path", - "mailbox", - "mailcap", - "marshal", - "math", - "md5", - "mhlib", - "mimetools", - "mimetypes", - "mimify", - "mmap", - "modulefinder", - "msilib", - "multifile", - "multiprocessing", - "mutex", - "netrc", - "new", - "nis", - "nntplib", - "nturl2path", - "numbers", - "operator", - "optparse", - "os", - "os.path", - "ossaudiodev", - "parser", - "pathlib", - "pdb", - "pickle", - "pickletools", - "pipes", - "pkgutil", - "platform", - "plistlib", - "popen2", - "poplib", - "posix", - "posixfile", - "posixpath", - "pprint", - "profile", - "pstats", - "pty", - "pwd", - "py_compile", - "pyclbr", - "pydoc", - "queue", - "quopri", - "random", - "re", - "readline", - "repr", - "reprlib", - "resource", - "rexec", - "rfc822", - "rlcompleter", - "robotparser", - "runpy", - "sched", - "select", - "sets", - "sgmllib", - "sha", - "shelve", - "shlex", - "shutil", - "signal", - "site", - "smtpd", - "smtplib", - "sndhdr", - "socket", - "socketserver", - "spwd", - "sqlite3", - "ssl", - "stat", - "statistics", - "statvfs", - "string", - "stringprep", - "struct", - "subprocess", - "sunau", - "sunaudiodev", - "symbol", - "symtable", - "sys", - "sysconfig", - "syslog", - "tabnanny", - "tarfile", - "telnetlib", - "tempfile", - "termios", - "test", - "test.support", - "test.test_support", - "textwrap", - "thread", - "threading", - "time", - "timeit", - "tkinter", - "tkinter.scrolledtext", - "tkinter.tix", - "tkinter.ttk", - "token", - "tokenize", - "trace", - "traceback", - "tracemalloc", - "ttk", - "tty", - "turtle", - "types", - "typing", - "unicodedata", - "unittest", - "unittest.mock", - "urllib", - "urllib.error", - "urllib.parse", - "urllib.request", - "urllib.response", - "urllib.robotparser", - "urllib2", - "urlparse", - "user", - "uu", - "uuid", - "venv", - "warnings", - "wave", - "weakref", - "webbrowser", - "whichdb", - "winsound", - "wsgiref", - "xdrlib", - "xml", - "xmlrpclib", - "zipfile", - "zipimport", - "zlib", -)) diff --git a/gql-checker/setup.cfg b/gql-checker/setup.cfg deleted file mode 100644 index 5e409001..00000000 --- a/gql-checker/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[wheel] -universal = 1 diff --git a/gql-checker/setup.py b/gql-checker/setup.py deleted file mode 100644 index 8ec1bf74..00000000 --- a/gql-checker/setup.py +++ /dev/null @@ -1,64 +0,0 @@ -import os -from setuptools import setup, find_packages - - -base_dir = os.path.dirname(__file__) - -about = {} -with open(os.path.join(base_dir, "gql_checker", "__about__.py")) as f: - exec(f.read(), about) - -with open(os.path.join(base_dir, "README.rst")) as f: - long_description = f.read() - - -setup( - name=about["__title__"], - version=about["__version__"], - - description=about["__summary__"], - long_description=long_description, - license=about["__license__"], - url=about["__uri__"], - author=about["__author__"], - author_email=about["__email__"], - - packages=find_packages(exclude=["tests", "tests.*"]), - zip_safe=False, - - install_requires=[ - "pycodestyle" - ], - - tests_require=[ - "pytest", - "flake8", - "pycodestyle", - "pylama" - ], - - py_modules=['gql_checker'], - entry_points={ - 'flake8.extension': [ - 'GQL = gql_checker.flake8_linter:Linter', - ], - 'pylama.linter': [ - 'gql_checker = gql_checker.pylama_linter:Linter' - ] - }, - - classifiers=[ - "Intended Audience :: Developers", - "Development Status :: 4 - Beta", - "License :: OSI Approved :: MIT License", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - ( - "License :: OSI Approved :: " - "GNU Lesser General Public License v3 (LGPLv3)" - ), - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: Software Development :: Quality Assurance", - "Operating System :: OS Independent" - ] -) diff --git a/gql-checker/tests/__init__.py b/gql-checker/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/gql-checker/tests/introspection_schema.json b/gql-checker/tests/introspection_schema.json deleted file mode 100644 index b4f5e0b4..00000000 --- a/gql-checker/tests/introspection_schema.json +++ /dev/null @@ -1 +0,0 @@ -{"__schema": {"queryType": {"name": "Query"}, "mutationType": null, "subscriptionType": null, "types": [{"kind": "OBJECT", "name": "Query", "description": null, "fields": [{"name": "droid", "description": null, "args": [{"name": "id", "description": "id of the droid", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "defaultValue": null}], "type": {"kind": "OBJECT", "name": "Droid", "ofType": null}, "isDeprecated": false, "deprecationReason": null}, {"name": "hero", "description": null, "args": [{"name": "episode", "description": "If omitted, returns the hero of the whole saga. If provided, returns the hero of that particular episode.", "type": {"kind": "ENUM", "name": "Episode", "ofType": null}, "defaultValue": null}], "type": {"kind": "INTERFACE", "name": "Character", "ofType": null}, "isDeprecated": false, "deprecationReason": null}, {"name": "human", "description": null, "args": [{"name": "id", "description": "id of the human", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "defaultValue": null}], "type": {"kind": "OBJECT", "name": "Human", "ofType": null}, "isDeprecated": false, "deprecationReason": null}], "inputFields": null, "interfaces": [], "enumValues": null, "possibleTypes": null}, {"kind": "SCALAR", "name": "String", "description": "The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.", "fields": null, "inputFields": null, "interfaces": null, "enumValues": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "Droid", "description": "A mechanical creature in the Star Wars universe.", "fields": [{"name": "appearsIn", "description": "Which movies they appear in.", "args": [], "type": {"kind": "LIST", "name": null, "ofType": {"kind": "ENUM", "name": "Episode", "ofType": null}}, "isDeprecated": false, "deprecationReason": null}, {"name": "friends", "description": "The friends of the droid, or an empty list if they have none.", "args": [], "type": {"kind": "LIST", "name": null, "ofType": {"kind": "INTERFACE", "name": "Character", "ofType": null}}, "isDeprecated": false, "deprecationReason": null}, {"name": "id", "description": "The id of the droid.", "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "isDeprecated": false, "deprecationReason": null}, {"name": "name", "description": "The name of the droid.", "args": [], "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "isDeprecated": false, "deprecationReason": null}, {"name": "primaryFunction", "description": "The primary function of the droid.", "args": [], "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "isDeprecated": false, "deprecationReason": null}], "inputFields": null, "interfaces": [{"kind": "INTERFACE", "name": "Character", "ofType": null}], "enumValues": null, "possibleTypes": null}, {"kind": "INTERFACE", "name": "Character", "description": "A character in the Star Wars Trilogy", "fields": [{"name": "appearsIn", "description": "Which movies they appear in.", "args": [], "type": {"kind": "LIST", "name": null, "ofType": {"kind": "ENUM", "name": "Episode", "ofType": null}}, "isDeprecated": false, "deprecationReason": null}, {"name": "friends", "description": "The friends of the character, or an empty list if they have none.", "args": [], "type": {"kind": "LIST", "name": null, "ofType": {"kind": "INTERFACE", "name": "Character", "ofType": null}}, "isDeprecated": false, "deprecationReason": null}, {"name": "id", "description": "The id of the character.", "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "isDeprecated": false, "deprecationReason": null}, {"name": "name", "description": "The name of the character.", "args": [], "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "isDeprecated": false, "deprecationReason": null}], "inputFields": null, "interfaces": null, "enumValues": null, "possibleTypes": [{"kind": "OBJECT", "name": "Droid", "ofType": null}, {"kind": "OBJECT", "name": "Human", "ofType": null}]}, {"kind": "ENUM", "name": "Episode", "description": "One of the films in the Star Wars Trilogy", "fields": null, "inputFields": null, "interfaces": null, "enumValues": [{"name": "EMPIRE", "description": "Released in 1980.", "isDeprecated": false, "deprecationReason": null}, {"name": "JEDI", "description": "Released in 1983.", "isDeprecated": false, "deprecationReason": null}, {"name": "NEWHOPE", "description": "Released in 1977.", "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "OBJECT", "name": "Human", "description": "A humanoid creature in the Star Wars universe.", "fields": [{"name": "appearsIn", "description": "Which movies they appear in.", "args": [], "type": {"kind": "LIST", "name": null, "ofType": {"kind": "ENUM", "name": "Episode", "ofType": null}}, "isDeprecated": false, "deprecationReason": null}, {"name": "friends", "description": "The friends of the human, or an empty list if they have none.", "args": [], "type": {"kind": "LIST", "name": null, "ofType": {"kind": "INTERFACE", "name": "Character", "ofType": null}}, "isDeprecated": false, "deprecationReason": null}, {"name": "homePlanet", "description": "The home planet of the human, or null if unknown.", "args": [], "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "isDeprecated": false, "deprecationReason": null}, {"name": "id", "description": "The id of the human.", "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "isDeprecated": false, "deprecationReason": null}, {"name": "name", "description": "The name of the human.", "args": [], "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "isDeprecated": false, "deprecationReason": null}], "inputFields": null, "interfaces": [{"kind": "INTERFACE", "name": "Character", "ofType": null}], "enumValues": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__Schema", "description": "A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query, mutation and subscription operations.", "fields": [{"name": "types", "description": "A list of all types supported by this server.", "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}}}, "isDeprecated": false, "deprecationReason": null}, {"name": "queryType", "description": "The type that query operations will be rooted at.", "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}, "isDeprecated": false, "deprecationReason": null}, {"name": "mutationType", "description": "If this server supports mutation, the type that mutation operations will be rooted at.", "args": [], "type": {"kind": "OBJECT", "name": "__Type", "ofType": null}, "isDeprecated": false, "deprecationReason": null}, {"name": "subscriptionType", "description": "If this server support subscription, the type that subscription operations will be rooted at.", "args": [], "type": {"kind": "OBJECT", "name": "__Type", "ofType": null}, "isDeprecated": false, "deprecationReason": null}, {"name": "directives", "description": "A list of all directives supported by this server.", "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Directive", "ofType": null}}}}, "isDeprecated": false, "deprecationReason": null}], "inputFields": null, "interfaces": [], "enumValues": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__Type", "description": "The fundamental unit of any GraphQL Schema is the type. There are many kinds of types in GraphQL as represented by the `__TypeKind` enum.\n\nDepending on the kind of a type, certain fields describe information about that type. Scalar types provide no information beyond a name and description, while Enum types provide their values. Object and Interface types provide the fields they describe. Abstract types, Union and Interface, provide the Object types possible at runtime. List and NonNull types compose other types.", "fields": [{"name": "kind", "description": null, "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "ENUM", "name": "__TypeKind", "ofType": null}}, "isDeprecated": false, "deprecationReason": null}, {"name": "name", "description": null, "args": [], "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "isDeprecated": false, "deprecationReason": null}, {"name": "description", "description": null, "args": [], "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "isDeprecated": false, "deprecationReason": null}, {"name": "fields", "description": null, "args": [{"name": "includeDeprecated", "description": null, "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "defaultValue": "false"}], "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Field", "ofType": null}}}, "isDeprecated": false, "deprecationReason": null}, {"name": "interfaces", "description": null, "args": [], "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}}, "isDeprecated": false, "deprecationReason": null}, {"name": "possibleTypes", "description": null, "args": [], "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}}, "isDeprecated": false, "deprecationReason": null}, {"name": "enumValues", "description": null, "args": [{"name": "includeDeprecated", "description": null, "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "defaultValue": "false"}], "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__EnumValue", "ofType": null}}}, "isDeprecated": false, "deprecationReason": null}, {"name": "inputFields", "description": null, "args": [], "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__InputValue", "ofType": null}}}, "isDeprecated": false, "deprecationReason": null}, {"name": "ofType", "description": null, "args": [], "type": {"kind": "OBJECT", "name": "__Type", "ofType": null}, "isDeprecated": false, "deprecationReason": null}], "inputFields": null, "interfaces": [], "enumValues": null, "possibleTypes": null}, {"kind": "ENUM", "name": "__TypeKind", "description": "An enum describing what kind of type a given `__Type` is", "fields": null, "inputFields": null, "interfaces": null, "enumValues": [{"name": "SCALAR", "description": "Indicates this type is a scalar.", "isDeprecated": false, "deprecationReason": null}, {"name": "OBJECT", "description": "Indicates this type is an object. `fields` and `interfaces` are valid fields.", "isDeprecated": false, "deprecationReason": null}, {"name": "INTERFACE", "description": "Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.", "isDeprecated": false, "deprecationReason": null}, {"name": "UNION", "description": "Indicates this type is a union. `possibleTypes` is a valid field.", "isDeprecated": false, "deprecationReason": null}, {"name": "ENUM", "description": "Indicates this type is an enum. `enumValues` is a valid field.", "isDeprecated": false, "deprecationReason": null}, {"name": "INPUT_OBJECT", "description": "Indicates this type is an input object. `inputFields` is a valid field.", "isDeprecated": false, "deprecationReason": null}, {"name": "LIST", "description": "Indicates this type is a list. `ofType` is a valid field.", "isDeprecated": false, "deprecationReason": null}, {"name": "NON_NULL", "description": "Indicates this type is a non-null. `ofType` is a valid field.", "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Boolean", "description": "The `Boolean` scalar type represents `true` or `false`.", "fields": null, "inputFields": null, "interfaces": null, "enumValues": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__Field", "description": "Object and Interface types are described by a list of Fields, each of which has a name, potentially a list of arguments, and a return type.", "fields": [{"name": "name", "description": null, "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "isDeprecated": false, "deprecationReason": null}, {"name": "description", "description": null, "args": [], "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "isDeprecated": false, "deprecationReason": null}, {"name": "args", "description": null, "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__InputValue", "ofType": null}}}}, "isDeprecated": false, "deprecationReason": null}, {"name": "type", "description": null, "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}, "isDeprecated": false, "deprecationReason": null}, {"name": "isDeprecated", "description": null, "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "isDeprecated": false, "deprecationReason": null}, {"name": "deprecationReason", "description": null, "args": [], "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "isDeprecated": false, "deprecationReason": null}], "inputFields": null, "interfaces": [], "enumValues": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__InputValue", "description": "Arguments provided to Fields or Directives and the input fields of an InputObject are represented as Input Values which describe their type and optionally a default value.", "fields": [{"name": "name", "description": null, "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "isDeprecated": false, "deprecationReason": null}, {"name": "description", "description": null, "args": [], "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "isDeprecated": false, "deprecationReason": null}, {"name": "type", "description": null, "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}, "isDeprecated": false, "deprecationReason": null}, {"name": "defaultValue", "description": null, "args": [], "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "isDeprecated": false, "deprecationReason": null}], "inputFields": null, "interfaces": [], "enumValues": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__EnumValue", "description": "One possible value for a given Enum. Enum values are unique values, not a placeholder for a string or numeric value. However an Enum value is returned in a JSON response as a string.", "fields": [{"name": "name", "description": null, "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "isDeprecated": false, "deprecationReason": null}, {"name": "description", "description": null, "args": [], "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "isDeprecated": false, "deprecationReason": null}, {"name": "isDeprecated", "description": null, "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "isDeprecated": false, "deprecationReason": null}, {"name": "deprecationReason", "description": null, "args": [], "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "isDeprecated": false, "deprecationReason": null}], "inputFields": null, "interfaces": [], "enumValues": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__Directive", "description": "A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.\n\nIn some cases, you need to provide options to alter GraphQL's execution behavior in ways field arguments will not suffice, such as conditionally including or skipping a field. Directives provide this by describing additional information to the executor.", "fields": [{"name": "name", "description": null, "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "isDeprecated": false, "deprecationReason": null}, {"name": "description", "description": null, "args": [], "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "isDeprecated": false, "deprecationReason": null}, {"name": "locations", "description": null, "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "ENUM", "name": "__DirectiveLocation", "ofType": null}}}}, "isDeprecated": false, "deprecationReason": null}, {"name": "args", "description": null, "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__InputValue", "ofType": null}}}}, "isDeprecated": false, "deprecationReason": null}, {"name": "onOperation", "description": null, "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "isDeprecated": true, "deprecationReason": "Use `locations`."}, {"name": "onFragment", "description": null, "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "isDeprecated": true, "deprecationReason": "Use `locations`."}, {"name": "onField", "description": null, "args": [], "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "isDeprecated": true, "deprecationReason": "Use `locations`."}], "inputFields": null, "interfaces": [], "enumValues": null, "possibleTypes": null}, {"kind": "ENUM", "name": "__DirectiveLocation", "description": "A Directive can be adjacent to many parts of the GraphQL language, a __DirectiveLocation describes one such possible adjacencies.", "fields": null, "inputFields": null, "interfaces": null, "enumValues": [{"name": "QUERY", "description": "Location adjacent to a query operation.", "isDeprecated": false, "deprecationReason": null}, {"name": "MUTATION", "description": "Location adjacent to a mutation operation.", "isDeprecated": false, "deprecationReason": null}, {"name": "SUBSCRIPTION", "description": "Location adjacent to a subscription operation.", "isDeprecated": false, "deprecationReason": null}, {"name": "FIELD", "description": "Location adjacent to a field.", "isDeprecated": false, "deprecationReason": null}, {"name": "FRAGMENT_DEFINITION", "description": "Location adjacent to a fragment definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "FRAGMENT_SPREAD", "description": "Location adjacent to a fragment spread.", "isDeprecated": false, "deprecationReason": null}, {"name": "INLINE_FRAGMENT", "description": "Location adjacent to an inline fragment.", "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}], "directives": [{"name": "include", "description": null, "locations": ["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"], "args": [{"name": "if", "description": "Included when true.", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "defaultValue": null}]}, {"name": "skip", "description": null, "locations": ["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"], "args": [{"name": "if", "description": "Skipped when true.", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "defaultValue": null}]}]}} \ No newline at end of file diff --git a/gql-checker/tests/test_cases/bad_query.py b/gql-checker/tests/test_cases/bad_query.py deleted file mode 100644 index e2cf2705..00000000 --- a/gql-checker/tests/test_cases/bad_query.py +++ /dev/null @@ -1,7 +0,0 @@ -from gql import gql - -gql(''' -{ - id -} -''') # GQL101: Cannot query field "id" on type "Query". diff --git a/gql-checker/tests/test_cases/noqa.py b/gql-checker/tests/test_cases/noqa.py deleted file mode 100644 index d3b35d37..00000000 --- a/gql-checker/tests/test_cases/noqa.py +++ /dev/null @@ -1,3 +0,0 @@ -from gql import gql - -gql(''' wrong query ''') # noqa diff --git a/gql-checker/tests/test_cases/syntax_error.py b/gql-checker/tests/test_cases/syntax_error.py deleted file mode 100644 index 945ec000..00000000 --- a/gql-checker/tests/test_cases/syntax_error.py +++ /dev/null @@ -1,3 +0,0 @@ -from gql import gql - -gql(''' wrong query ''') # GQL100 diff --git a/gql-checker/tests/test_cases/validation.py b/gql-checker/tests/test_cases/validation.py deleted file mode 100644 index 503b2f94..00000000 --- a/gql-checker/tests/test_cases/validation.py +++ /dev/null @@ -1,78 +0,0 @@ -from gql import gql - - -gql(''' - query NestedQueryWithFragment { - hero { - ...NameAndAppearances - friends { - ...NameAndAppearances - friends { - ...NameAndAppearances - } - } - } - } - fragment NameAndAppearances on Character { - name - appearsIn - } -''') - -gql(''' - query HeroSpaceshipQuery { - hero { - favoriteSpaceship - } - } -''') # GQL101: Cannot query field "favoriteSpaceship" on type "Character". - -gql(''' - query HeroNoFieldsQuery { - hero - } -''') # GQL101: Field "hero" of type "Character" must have a sub selection. - - -gql(''' - query HeroFieldsOnScalarQuery { - hero { - name { - firstCharacterOfName - } - } - } -''') # GQL101: Field "name" of type "String" must not have a sub selection. - - -gql(''' - query DroidFieldOnCharacter { - hero { - name - primaryFunction - } - } -''') # GQL101: Cannot query field "primaryFunction" on type "Character". However, this field exists on "Droid". Perhaps you meant to use an inline fragment? - -gql(''' - query DroidFieldInFragment { - hero { - name - ...DroidFields - } - } - fragment DroidFields on Droid { - primaryFunction - } -''') - -gql(''' - query DroidFieldInFragment { - hero { - name - ... on Droid { - primaryFunction - } - } - } -''') diff --git a/gql-checker/tests/test_flake8_linter.py b/gql-checker/tests/test_flake8_linter.py deleted file mode 100644 index 7ed3c659..00000000 --- a/gql-checker/tests/test_flake8_linter.py +++ /dev/null @@ -1,56 +0,0 @@ -import ast -import re -import os - -import pycodestyle -import pytest - -from gql_checker.flake8_linter import Linter - -from tests.utils import extract_expected_errors - - -def load_test_cases(): - base_path = os.path.dirname(__file__) - test_case_path = os.path.join(base_path, "test_cases") - test_case_files = os.listdir(test_case_path) - - test_cases = [] - - for fname in test_case_files: - if not fname.endswith(".py"): - continue - - fullpath = os.path.join(test_case_path, fname) - data = open(fullpath).read() - tree = ast.parse(data, fullpath) - codes, messages = extract_expected_errors(data) - - test_cases.append((tree, fullpath, codes, messages)) - - return test_cases - - -@pytest.mark.parametrize( - "tree, filename, expected_codes, expected_messages", - load_test_cases() -) -def test_expected_error(tree, filename, expected_codes, expected_messages): - argv = [ - "--gql-introspection-schema=./tests/introspection_schema.json" - ] - - parser = pycodestyle.get_parser('', '') - Linter.add_options(parser) - options, args = parser.parse_args(argv) - Linter.parse_options(options) - - checker = Linter(tree, filename) - codes = [] - messages = [] - for lineno, col_offset, msg, instance in checker.run(): - code, message = msg.split(" ", 1) - codes.append(code) - messages.append(message) - assert codes == expected_codes - assert set(messages) >= set(expected_messages) diff --git a/gql-checker/tests/test_pylama_linter.py b/gql-checker/tests/test_pylama_linter.py deleted file mode 100644 index 8e942717..00000000 --- a/gql-checker/tests/test_pylama_linter.py +++ /dev/null @@ -1,50 +0,0 @@ -import ast -import os - -import pytest - -from gql_checker import pylama_linter - -from tests.utils import extract_expected_errors - - -def load_test_cases(): - base_path = os.path.dirname(__file__) - test_case_path = os.path.join(base_path, "test_cases") - test_case_files = os.listdir(test_case_path) - - test_cases = [] - - for fname in test_case_files: - if not fname.endswith(".py"): - continue - - fullpath = os.path.join(test_case_path, fname) - data = open(fullpath).read() - codes, messages = extract_expected_errors(data) - test_cases.append((fullpath, codes, messages)) - - return test_cases - - -@pytest.mark.parametrize( - "filename, expected_codes, expected_messages", - load_test_cases() -) -def test_expected_error(filename, expected_codes, expected_messages): - checker = pylama_linter.Linter() - assert checker.allow(filename) - - codes = [] - messages = [] - - options = { - "gql_introspection_schema": "./tests/introspection_schema.json" - } - - for error in checker.run(filename, **options): - codes.append(error['type']) - messages.append(error['text']) - - assert codes == expected_codes - assert set(messages) >= set(expected_messages) diff --git a/gql-checker/tests/utils.py b/gql-checker/tests/utils.py deleted file mode 100644 index e0fd9034..00000000 --- a/gql-checker/tests/utils.py +++ /dev/null @@ -1,19 +0,0 @@ -import re - - -ERROR_RX = re.compile("# ((GQL[0-9]+ ?)+)(: (.*))?$") - - -def extract_expected_errors(data): - lines = data.splitlines() - expected_codes = [] - expected_messages = [] - for line in lines: - match = ERROR_RX.search(line) - if match: - codes = match.group(1).split() - message = match.group(4) - expected_codes.extend(codes) - if message: - expected_messages.append(message) - return expected_codes, expected_messages diff --git a/gql-checker/tox.ini b/gql-checker/tox.ini deleted file mode 100644 index 0bbd2e81..00000000 --- a/gql-checker/tox.ini +++ /dev/null @@ -1,38 +0,0 @@ -[tox] -envlist = py26,py27,pypy,py33,py34,py35,pep8,py3pep8 - -[testenv] -deps = - coverage==3.7 - pytest - flake8 - pylama - pycodestyle>=2.0 -commands = - coverage run --source=gql_checker/,tests/ -m pytest --capture=no --strict {posargs} - coverage report -m - -# Temporarily disable coverage on pypy because of performance problems with -# coverage.py on pypy. -[testenv:pypy] -commands = py.test --capture=no --strict {posargs} - -[testenv:pep8] -deps = - flake8 - pep8-naming - flake8-import-order -commands = flake8 gql_checker/ - -[testenv:py3pep8] -basepython = python3.3 -deps = - flake8 - pep8-naming - flake8-import-order -commands = flake8 gql_checker/ - -[flake8] -exclude = .tox,*.egg -select = E,W,F,N,I -application-import-names = gql_checker,tests