def test_alias(self): """ Tests that aliased datatypes are correctly generated. """ text = textwrap.dedent("""\ namespace test struct TestArg f String "test doc" example default f = "asdf" struct TestResult f String "test doc" example default f = "asdf" alias TestAlias = TestArg route TestRoute (TestAlias, TestResult, Void) "test doc" """) route_whitelist_filter = { "route_whitelist": {"test": ["TestRoute"]}, "datatype_whitelist": {} } api = specs_to_ir([('test.stone', text)], route_whitelist_filter=route_whitelist_filter) self._compare_namespace_names(api, ['test']) self._compare_datatype_names(api.namespaces['test'], ['TestArg', 'TestResult'])
def test_simple(self): """ Tests that route whitelisting can generate the right datatypes for a namespace. """ text = textwrap.dedent("""\ namespace test struct TestArg f String "test doc" example default f = "asdf" struct TestResult f String "test doc" example default f = "asdf" route TestRoute (TestArg, TestResult, Void) "test doc" """) route_whitelist_filter = { "route_whitelist": { "test": ["TestRoute"] }, "datatype_whitelist": {} } api = specs_to_ir([('test.stone', text)], route_whitelist_filter=route_whitelist_filter) self._compare_namespace_names(api, ['test']) self._compare_datatype_names(api.namespaces['test'], ['TestArg', 'TestResult'])
def test_alias(self): """ Tests that aliased datatypes are correctly generated. """ text = textwrap.dedent("""\ namespace test struct TestArg f String "test doc" example default f = "asdf" struct TestResult f String "test doc" example default f = "asdf" alias TestAlias = TestArg route TestRoute (TestAlias, TestResult, Void) "test doc" """) route_whitelist_filter = { "route_whitelist": { "test": ["TestRoute"] }, "datatype_whitelist": {} } api = specs_to_ir([('test.stone', text)], route_whitelist_filter=route_whitelist_filter) self._compare_namespace_names(api, ['test']) self._compare_datatype_names(api.namespaces['test'], ['TestArg', 'TestResult'])
def test_star(self): """ Tests that inputs with "*" work as expected. """ text = textwrap.dedent("""\ namespace test struct TestArg f String "test doc" example default f = "asdf" struct TestResult f String "test doc" example default f = "asdf" route TestRoute (TestArg, TestResult, Void) "test doc" struct TestArg2 f String "test doc" example default f = "asdf" struct TestResult2 f String "test doc" example default f = "asdf" route TestRoute:2 (TestArg2, TestResult2, Void) "test doc" """) route_whitelist_filter = { "route_whitelist": { "test": ["*"] }, "datatype_whitelist": {} } api = specs_to_ir([('test.stone', text)], route_whitelist_filter=route_whitelist_filter) self._compare_namespace_names(api, ['test']) self._compare_datatype_names( api.namespaces['test'], ['TestArg', 'TestArg2', 'TestResult', 'TestResult2'])
def test_builtin_types(self): """ Tests that builtin datatypes, like lists, maps, and unions, are correctly evaluated. """ text = textwrap.dedent("""\ namespace test union Foo a "test doc" example default a = null union Bar a "test doc" example default a = null struct TestArg f String "test doc" example default f = "asdf" struct TestResult f List(Foo) "test doc" b Map(String, Bar) "test doc" example default f = [default] b = {"test": default} route TestRoute (TestArg, TestResult, Void) "test doc" """) route_whitelist_filter = { "route_whitelist": { "test": ["TestRoute"] }, "datatype_whitelist": {} } api = specs_to_ir([('test.stone', text)], route_whitelist_filter=route_whitelist_filter) self._compare_namespace_names(api, ['test']) self._compare_datatype_names(api.namespaces['test'], ['TestArg', 'TestResult', 'Foo', 'Bar'])
def test_star(self): """ Tests that inputs with "*" work as expected. """ text = textwrap.dedent("""\ namespace test struct TestArg f String "test doc" example default f = "asdf" struct TestResult f String "test doc" example default f = "asdf" route TestRoute (TestArg, TestResult, Void) "test doc" struct TestArg2 f String "test doc" example default f = "asdf" struct TestResult2 f String "test doc" example default f = "asdf" route TestRoute:2 (TestArg2, TestResult2, Void) "test doc" """) route_whitelist_filter = { "route_whitelist": {"test": ["*"]}, "datatype_whitelist": {} } api = specs_to_ir([('test.stone', text)], route_whitelist_filter=route_whitelist_filter) self._compare_namespace_names(api, ['test']) self._compare_datatype_names(api.namespaces['test'], ['TestArg', 'TestArg2', 'TestResult', 'TestResult2'])
def test_builtin_types(self): """ Tests that builtin datatypes, like lists, maps, and unions, are correctly evaluated. """ text = textwrap.dedent("""\ namespace test union Foo a "test doc" example default a = null union Bar a "test doc" example default a = null struct TestArg f String "test doc" example default f = "asdf" struct TestResult f List(Foo) "test doc" b Map(String, Bar) "test doc" example default f = [default] b = {"test": default} route TestRoute (TestArg, TestResult, Void) "test doc" """) route_whitelist_filter = { "route_whitelist": {"test": ["TestRoute"]}, "datatype_whitelist": {} } api = specs_to_ir([('test.stone', text)], route_whitelist_filter=route_whitelist_filter) self._compare_namespace_names(api, ['test']) self._compare_datatype_names(api.namespaces['test'], ['TestArg', 'TestResult', 'Foo', 'Bar'])
def test_simple(self): """ Tests that route whitelisting can generate the right datatypes for a namespace. """ text = textwrap.dedent("""\ namespace test struct TestArg f String "test doc" example default f = "asdf" struct TestResult f String "test doc" example default f = "asdf" route TestRoute (TestArg, TestResult, Void) "test doc" struct TestArg2 f String "test doc" example default f = "asdf" struct TestResult2 f String "test doc" example default f = "asdf" route TestRoute:2 (TestArg2, TestResult2, Void) "test doc" """) route_whitelist_filter = { "route_whitelist": {"test": ["TestRoute:2"]}, "datatype_whitelist": {} } api = specs_to_ir([('test.stone', text)], route_whitelist_filter=route_whitelist_filter) self._compare_namespace_names(api, ['test']) self._compare_datatype_names(api.namespaces['test'], ['TestArg2', 'TestResult2'])
def test_imports(self): """ Tests that datatypes imported from another namespace are correctly included. """ text = textwrap.dedent("""\ namespace test struct TestArg f String "test doc" example default f = "asdf" struct TestResult f String "test doc" example default f = "asdf" """) text2 = textwrap.dedent("""\ namespace test2 import test route TestRoute (test.TestArg, test.TestResult, Void) "test doc" """) route_whitelist_filter = { "route_whitelist": { "test2": ["TestRoute"] }, "datatype_whitelist": {} } api = specs_to_ir([('test.stone', text), ('test2.stone', text2)], route_whitelist_filter=route_whitelist_filter) self._compare_namespace_names(api, ['test', 'test2']) self._compare_datatype_names(api.namespaces['test'], ['TestArg', 'TestResult']) self._compare_datatype_names(api.namespaces['test2'], [])
def test_imports(self): """ Tests that datatypes imported from another namespace are correctly included. """ text = textwrap.dedent("""\ namespace test struct TestArg f String "test doc" example default f = "asdf" struct TestResult f String "test doc" example default f = "asdf" """) text2 = textwrap.dedent("""\ namespace test2 import test route TestRoute (test.TestArg, test.TestResult, Void) "test doc" """) route_whitelist_filter = { "route_whitelist": {"test2": ["TestRoute"]}, "datatype_whitelist": {} } api = specs_to_ir([('test.stone', text), ('test2.stone', text2)], route_whitelist_filter=route_whitelist_filter) self._compare_namespace_names(api, ['test', 'test2']) self._compare_datatype_names(api.namespaces['test'], ['TestArg', 'TestResult']) self._compare_datatype_names(api.namespaces['test2'], [])
def generate_code(spec_root: str, gen_rust: bool, gen_test: bool): """ This is basically stone/stone/cli.py stripped down and customized to our needs. """ targets = ["rust"] if gen_rust else [] targets += ["test"] if gen_test else [] print("Generating [{}] from {}".format(", ".join(targets), spec_root)) specs = [] for path in spec_files(spec_root): with open(path) as f: specs.append((path, f.read())) try: api = specs_to_ir(specs) except InvalidSpec as e: print("{}:{}: error: {}".format(e.path, e.lineno, e.msg), file=sys.stderr) raise CodegenFailed sys.path.append("generator") for target in targets: print("Running generator for {}".format(target)) try: backend_module = imp.load_source( '{}_backend'.format(target), join("generator", "{}.stoneg.py".format(target))) except Exception: print( "error: Importing backend \"{}\" module raised an exception: ". format(target), file=sys.stderr) raise destination = { "rust": join("src", "generated"), "test": join("tests", "generated"), }[target] rmtree(destination, ignore_errors=True) c = Compiler(api, backend_module, [], destination) try: c.build() except BackendException as e: print("error: {} raised an exception:\n{}".format( e.backend_name, e.traceback), file=sys.stderr) raise CodegenFailed if os.linesep != "\n": # If this is Windows, rewrite the files to have the proper line ending. for dirent in os.scandir(destination): if dirent.is_file(): crlf_path = dirent.path + "_" with open(dirent.path) as lf, open(crlf_path, "w") as crlf: for line in lf: crlf.write(line) os.replace(crlf_path, dirent.path)
def test_doc_refs(self): """ Tests that datatypes referenced in documentation get generated. """ text = textwrap.dedent("""\ namespace test union Foo a "test doc" example default a = null union Bar a "test doc" example default a = null """) text2 = textwrap.dedent("""\ namespace test2 ":type:`test.Foo`" alias TestAlias = String ":field:`Baz.a`" struct TestStruct a TestAlias "test doc" example default a = "asdf" struct Baz a String "test doc :field:`TestStruct.a`" example default a = "asdf" struct TestArg f String "test doc" example default f = "asdf" struct TestResult f String "test doc" example default f = "asdf" route TestRoute (TestArg, TestResult, Void) ":type:`Baz` test doc" """) route_whitelist_filter = { "route_whitelist": {"test2": ["TestRoute"]}, "datatype_whitelist": {} } api = specs_to_ir([('test.stone', text), ('test2.stone', text2)], route_whitelist_filter=route_whitelist_filter) self._compare_namespace_names(api, ['test', 'test2']) self._compare_datatype_names(api.namespaces['test'], ['Foo']) self._compare_datatype_names(api.namespaces['test2'], ['TestArg', 'TestResult', 'TestStruct', 'Baz'])
def test_subtype(self): """ Tests that datatypes that inherit from others are correctly generated. """ text = textwrap.dedent("""\ namespace test union Foo a "test doc" example default a = null union Bar extends Foo b "test doc" example default a = null struct TestArg f String "test doc" example default f = "asdf" struct TestResult f Bar "test doc" example default f = default route TestRoute (TestArg, TestResult, Void) "test doc" """) route_whitelist_filter = { "route_whitelist": {"test": ["TestRoute"]}, "datatype_whitelist": {} } api = specs_to_ir([('test.stone', text)], route_whitelist_filter=route_whitelist_filter) self._compare_namespace_names(api, ['test']) self._compare_datatype_names(api.namespaces['test'], ['TestArg', 'TestResult', 'Foo', 'Bar']) # Test enumerated subtypes as well text = textwrap.dedent("""\ namespace test struct Foo union file File folder Folder path String "test doc" example default file = default example folder_default folder = default struct File extends Foo a String "test doc" example default a = "a" path = "a" struct Folder extends Foo b String "test doc" example default b = "b" path = "a" struct TestArg f Foo "test doc" example default f = default struct TestResult f String "test doc" example default f = "asdf" route TestRoute (TestArg, TestResult, Void) "test doc" """) route_whitelist_filter = { "route_whitelist": {"test": ["TestRoute"]}, "datatype_whitelist": {} } api = specs_to_ir([('test.stone', text)], route_whitelist_filter=route_whitelist_filter) self._compare_namespace_names(api, ['test']) self._compare_datatype_names(api.namespaces['test'], ['TestArg', 'TestResult', 'Foo', 'File', 'Folder'])
def test_doc_refs(self): """ Tests that datatypes referenced in documentation get generated. """ text = textwrap.dedent("""\ namespace test union Foo a "test doc" example default a = null union Bar a "test doc" example default a = null """) text2 = textwrap.dedent("""\ namespace test2 ":type:`test.Foo`" alias TestAlias = String ":field:`Baz.a`" struct TestStruct a TestAlias "test doc" example default a = "asdf" struct Baz a String "test doc :field:`TestStruct.a`" example default a = "asdf" struct TestArg f String "test doc" example default f = "asdf" struct TestResult f String "test doc" example default f = "asdf" route TestRoute (TestArg, TestResult, Void) ":type:`Baz` test doc" """) route_whitelist_filter = { "route_whitelist": { "test2": ["TestRoute"] }, "datatype_whitelist": {} } api = specs_to_ir([('test.stone', text), ('test2.stone', text2)], route_whitelist_filter=route_whitelist_filter) self._compare_namespace_names(api, ['test', 'test2']) self._compare_datatype_names(api.namespaces['test'], ['Foo']) self._compare_datatype_names( api.namespaces['test2'], ['TestArg', 'TestResult', 'TestStruct', 'Baz'])
def test_subtype(self): """ Tests that datatypes that inherit from others are correctly generated. """ text = textwrap.dedent("""\ namespace test union Foo a "test doc" example default a = null union Bar extends Foo b "test doc" example default a = null struct TestArg f String "test doc" example default f = "asdf" struct TestResult f Bar "test doc" example default f = default route TestRoute (TestArg, TestResult, Void) "test doc" """) route_whitelist_filter = { "route_whitelist": { "test": ["TestRoute"] }, "datatype_whitelist": {} } api = specs_to_ir([('test.stone', text)], route_whitelist_filter=route_whitelist_filter) self._compare_namespace_names(api, ['test']) self._compare_datatype_names(api.namespaces['test'], ['TestArg', 'TestResult', 'Foo', 'Bar']) # Test enumerated subtypes as well text = textwrap.dedent("""\ namespace test struct Foo union file File folder Folder path String "test doc" example default file = default example folder_default folder = default struct File extends Foo a String "test doc" example default a = "a" path = "a" struct Folder extends Foo b String "test doc" example default b = "b" path = "a" struct TestArg f Foo "test doc" example default f = default struct TestResult f String "test doc" example default f = "asdf" route TestRoute (TestArg, TestResult, Void) "test doc" """) route_whitelist_filter = { "route_whitelist": { "test": ["TestRoute"] }, "datatype_whitelist": {} } api = specs_to_ir([('test.stone', text)], route_whitelist_filter=route_whitelist_filter) self._compare_namespace_names(api, ['test']) self._compare_datatype_names( api.namespaces['test'], ['TestArg', 'TestResult', 'Foo', 'File', 'Folder'])