Repository: tech-teach/marshmallowjson

Issue:
validate json schema dependency order
Is necessary works with a valid json schema, so, to get this, create a json validator for this structure:
`{
    "Identifier": {
        "catalog": {
            "kind": "str",
            "required": true,
            "doc": "Que vaina es esto"
        },
        "entry": {
            "kind": "str",
            "required": true
        },
        "uuid": {
            "kind": "uuid",
            "required": true
        }
    },
    "General": {
        "identifier": {
            "kind": "object",
            "schema": "Identifier",
            "required": true
        },
        "title": {
            "kind": "str",
            "required": true
        },
        "keywords": {
            "kind": "list",
            "items": "str",
            "required": false
        }
    },
    "LearningObject": {
        "general": {
            "kind": "object",
            "schema": "General",
            "required": false
        }
    }
}
`

Discussion:

Patch:
diff --git a/.travis.yml b/.travis.yml
index 4f0901a..71234d5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,26 +1,29 @@
-# Config file for automatic testing at travis-ci.org
-# This file will be regenerated if you run travis_pypi_setup.py
-
-language: python
-python:
-  - 3.6
-  - 3.5
-
-# command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors
-install: pip install -U tox-travis
-
-# command to run tests, e.g. python setup.py test
-script: tox
-
-# After you create the Github repo and add it to Travis, run the
-# travis_pypi_setup.py script to finish PyPI deployment setup
+# This file was autogenerated and will overwrite each time you run travis_pypi_setup.py
 deploy:
+  password:
+    secure: !!binary |
+      VnZ0MytIcHhSRkxWdGFqYnd6WGo5eWZxN0E0UE9kRm5QNTFZR3FQcXQ3MFEvakp2OXhkMnZwbVcr
+      MElOVVNjZFVqdUljUUpCa2NrbXdPZUVzL1FuNThBRVhJRjhCMVNSL0FGTFV1bW9DTEU0YmgzcHgw
+      d2VSdk8rZXpkUFgxdmx0TFF4bWdLR2xHVG4yN3RlSEtTdVR6eVVWTkNzSGwrKzB5a0VSeFBPODBC
+      NDl4S0EvbjVPQk9YSkFYZzNXODUvaDRwUTQ0Z2NhSHg3bTdZSTBGSytRZGJTZHRWTjZrUEV1R3hJ
+      MlNSdkhQdVdmWjhhY0Q5eXJSVmtVRk5iUldzNTZUeEI3TUp0ajkxdEJTdGZLdTM0Z2ZITGNXdTNp
+      M1dQUVl3UmlZUFNFUjZvMnVZZzFsR1k3ZmJhM01ZZUVGdnRYZER3YndUcEh6T1kyYnlSd1ptSlhr
+      N3VCOUw1dlNLa1hyd0VOcXgyaU12Wm5jMVhNbkRqcTNnOHYvUk5XSWVoSnFoMWN4ZGtkNHhPREty
+      enpJMUNZbGc5b0FaL1JSYVVvR3ZuNkRtYVN5aTU2U2NZZTJWaUlld1E3Zm13eEpKQVBmRzBMY2RO
+      QUkrU0tCUmVqenl6bHlBSndwS20wRU1kOUx4dlRoQTVydzlwS0pVSkYzN20xWHJGUU9OK29nOUFU
+      YzZKK3puSUtQRmVXTWlHUU5xL1RRZUI5YTZPcnRZQmxZWjY2ZldhelppOEVXL01PSUlXQnNDU0Zm
+      VG9VSXNDSDAxTFNKczc0MzRjdVJORWZON1FhOVVDcnh0MGVNcnNDTVRGMWxyV28vbW9jODU0TXlZ
+      bmV2UlFtOHVxa0k4Q2JaTStvM0pDV2lCQXV6MStVZjdaR1R2OThlcFVvYkN1WGhZY00xTU1nd1E9
   provider: pypi
   distributions: sdist bdist_wheel
   user: odarbelaeze
-  password:
-    secure: PLEASE_REPLACE_ME
-  on:
-    tags: true
-    repo: odarbelaeze/marshmallowjson
+  true:
     python: 3.6
+    repo: odarbelaeze/marshmallowjson
+    tags: true
+install: pip install -U tox-travis
+language: python
+python:
+- 3.6
+- 3.5
+script: tox
diff --git a/marshmallowjson/cli.py b/marshmallowjson/cli.py
index 8cdfbe7..b19d723 100644
--- a/marshmallowjson/cli.py
+++ b/marshmallowjson/cli.py
@@ -1,14 +1,41 @@
 """Console script for marshmallowjson."""
 
 import click
+import collections
+import json
+import sys
+
+
+def fail(kind, type_, name):
+    click.echo(click.style(
+        '{kind} is not a known type in {type_}.{name}'.format(
+            kind=kind,
+            type_=type_,
+            name=name,
+        ),
+        fg='red'
+    ))
+    sys.exit(1)
 
 
 @click.command()
-def main(args=None):
-    """Console script for marshmallowjson."""
-    click.echo("Replace this message by putting your code into "
-               "marshmallowjson.cli.main")
-    click.echo("See click documentation at http://click.pocoo.org/")
+@click.argument('definition', type=click.File('r'))
+def main(definition):
+    """Validate an schema for marshmallow json"""
+    known = set('string boolean uuid number integer decimal'.split())
+    definitions = json.load(definition, object_pairs_hook=collections.OrderedDict)
+    for type_, schema in definitions.items():
+        for name, field in schema.items():
+            kind = field['kind']
+            if kind == 'list':
+                items = field['items']
+                if items not in known:
+                    fail(items, type_, name)
+                continue
+            if kind not in known:
+                fail(kind, type_, name)
+        known.add(type_)
+    click.echo(click.style('All clear', fg='green'))
 
 
 if __name__ == "__main__":


Test patch:
diff --git a/tests/data/basic.json b/tests/data/basic.json
new file mode 100644
index 0000000..93aaa83
--- /dev/null
+++ b/tests/data/basic.json
@@ -0,0 +1,20 @@
+{
+    "StringType": {
+        "field": {
+            "kind": "string",
+            "required": false
+        }
+    },
+    "NumberType": {
+        "field": {
+            "kind": "number",
+            "required": false
+        }
+    },
+    "BooleanType": {
+        "field": {
+            "kind": "boolean",
+            "required": false
+        }
+    }
+}
diff --git a/tests/data/list.json b/tests/data/list.json
new file mode 100644
index 0000000..a08f382
--- /dev/null
+++ b/tests/data/list.json
@@ -0,0 +1,15 @@
+{
+    "StringType": {
+        "field": {
+            "kind": "string",
+            "required": false
+        }
+    },
+    "ListOfString": {
+        "field": {
+            "kind": "list",
+            "items": "StringType",
+            "required": false
+        }
+    }
+}
diff --git a/tests/data/unknown.json b/tests/data/unknown.json
new file mode 100644
index 0000000..7bd8f98
--- /dev/null
+++ b/tests/data/unknown.json
@@ -0,0 +1,9 @@
+{
+    "Type": {
+        "field": {
+            "kind": "Unknown",
+            "required": false,
+            "doc": "Unknow is nowhere near the type definitions, that's an error"
+        }
+    }
+}
diff --git a/tests/test_marshmallowjson.py b/tests/test_marshmallowjson.py
index 8a3236c..62824c1 100644
--- a/tests/test_marshmallowjson.py
+++ b/tests/test_marshmallowjson.py
@@ -1,5 +1,6 @@
 """Tests for `marshmallowjson` package."""
 
+import os
 import pytest
 
 from click.testing import CliRunner
@@ -9,27 +10,45 @@ from marshmallowjson import cli
 
 
 @pytest.fixture
-def response():
-    """Sample pytest fixture.
+def unknown():
+    root = os.path.dirname(__file__)
+    return os.path.join(root, 'data/unknown.json')
 
-    See more at: http://doc.pytest.org/en/latest/fixture.html
-    """
-    # import requests
-    # return requests.get('https://github.com/audreyr/cookiecutter-pypackage')
+
+@pytest.fixture
+def basic():
+    root = os.path.dirname(__file__)
+    return os.path.join(root, 'data/basic.json')
+
+
+@pytest.fixture
+def list_schema():
+    root = os.path.dirname(__file__)
+    return os.path.join(root, 'data/list.json')
+
+
+def test_error_when_using_unknown_type(unknown):
+    runner = CliRunner()
+    result = runner.invoke(cli.main, [unknown])
+    assert result.exit_code == 1, result.output
+    assert 'Unknown is not a known type in Type.field' in result.output
+
+
+def test_all_basic_types_are_allowed(basic):
+    runner = CliRunner()
+    result = runner.invoke(cli.main, [basic])
+    assert result.exit_code == 0, result.output
 
 
-def test_content(response):
-    """Sample pytest test function with the pytest fixture as an argument."""
-    # from bs4 import BeautifulSoup
-    # assert 'GitHub' in BeautifulSoup(response.content).title.string
+def test_lists_are_allowed(list_schema):
+    runner = CliRunner()
+    result = runner.invoke(cli.main, [list_schema])
+    assert result.exit_code == 0, result.output
 
 
 def test_command_line_interface():
     """Test the CLI."""
     runner = CliRunner()
-    result = runner.invoke(cli.main)
-    assert result.exit_code == 0
-    assert 'marshmallowjson.cli.main' in result.output
     help_result = runner.invoke(cli.main, ['--help'])
     assert help_result.exit_code == 0
     assert '--help  Show this message and exit.' in help_result.output