/**
 * Created by eddy spreeuwers on 14-02-18.
 */ import * as fs from "fs" ; import * as ts from "typescript" ; import { XsdGrammar } from "../src/xsd-grammar" ; import { DOMParser } from "xmldom-reborn" ; describe ( "grammar" , ( ) => { let simpleClassXsd = "" ; let simpleInheritedClassXsd = "" ; let importedClassXsd = "" ; let formXsd = "" ; let typesXsd = "" ; let groupXsd = "" ; let elmXsd = "" ; let simpleTypeXsd = "" ; let singleElmXsd = "" ; beforeEach ( ( ) => { simpleClassXsd = fs . readFileSync ( './test/xsd/simpleClass.xsd' ) . toString ( ) ; simpleInheritedClassXsd = fs . readFileSync ( './test/xsd/simpleInheritedClass.xsd' ) . toString ( ) ; importedClassXsd = fs . readFileSync ( './test/xsd/importedClass.xsd' ) . toString ( ) ; formXsd = fs . readFileSync ( "./test/xsd/xep-004.xsd" ) . toString ( ) ; typesXsd = fs . readFileSync ( "./test/xsd/types.xsd" ) . toString ( ) ; groupXsd = fs . readFileSync ( "./test/xsd/group.xsd" ) . toString ( ) ; elmXsd = fs . readFileSync ( "./test/xsd/element.xsd" ) . toString ( ) ; singleElmXsd = fs . readFileSync ( "./test/xsd/singleElm.xsd" ) . toString ( ) ; simpleTypeXsd = fs . readFileSync ( "./test/xsd/simpletype.xsd" ) . toString ( ) ; } ) ; it ( " can parse a single elements  " , ( ) => { let ast = testGrammar ( singleElmXsd ) ; expect ( ( ast ) . children . length ) . toBe ( 1 ) ; expect ( ( ast ) . children [ 0 ] . nodeType ) . toBe ( 'AliasType' ) ; expect ( ( ast ) . children [ 0 ] . name ) . toBe ( "naam" ) ; expect ( ( ast ) . children [ 0 ] . attr . type ) . toBe ( "xs:string" ) ; } ) ; it ( " can parse a simple class starting with Element " , ( ) => { let ast = testGrammar ( elmXsd ) ; expect ( ast . children . length ) . toBe ( 7 ) ; expect ( ast . children [ 0 ] . nodeType ) . toBe ( 'Class' ) ; expect ( ast . children [ 0 ] . name ) . toBe ( 'Classname' ) ; expect ( ast . children [ 0 ] . children ) . toBeDefined ( ) ; expect ( ast . children [ 0 ] . children [ 0 ] . nodeType ) . toBe ( 'Field' ) ; expect ( ast . children [ 0 ] . children [ 0 ] . attr . fieldName ) . toBe ( 'intField' ) ; expect ( ast . children [ 0 ] . children [ 0 ] . attr . fieldType ) . toBe ( 'number' ) ; expect ( ast . children [ 0 ] . children [ 1 ] . nodeType ) . toBe ( 'Field' ) ; expect ( ast . children [ 0 ] . children [ 1 ] . attr . fieldName ) . toBe ( 'dateField' ) ; expect ( ast . children [ 0 ] . children [ 1 ] . attr . fieldType ) . toBe ( 'Date' ) ; expect ( ast . children [ 0 ] . children [ 2 ] . nodeType ) . toBe ( 'Field' ) ; expect ( ast . children [ 0 ] . children [ 2 ] . attr . fieldName ) . toBe ( 'things' ) ; expect ( ast . children [ 0 ] . children [ 2 ] . attr . fieldType ) . toBe ( 'Things' ) ; expect ( ast . children [ 2 ] . children [ 0 ] . nodeType ) . toBe ( 'Field' ) ; expect ( ast . children [ 2 ] . children [ 0 ] . attr . fieldName ) . toBe ( 'show?' ) ; expect ( ast . children [ 2 ] . children [ 0 ] . attr . fieldType ) . toBe ( 'Show[]' ) ; expect ( ast . children [ 6 ] . nodeType ) . toBe ( 'AliasType' ) ; expect ( ast . children [ 6 ] . attr . type ) . toBe ( 'xs:string' ) ; expect ( ast . children [ 6 ] . attr . element ) . toBe ( 'true' ) ; expect ( ast . children [ 6 ] . name ) . toBe ( 'xxx' ) ; } ) ; it ( " can parse a simple class starting with complexType" , ( ) => { let ast = testGrammar ( simpleClassXsd ) ; expect ( ast . children . length ) . toBe ( 2 ) ; expect ( ast . children [ 0 ] . nodeType ) . toBe ( 'AliasType' ) ; expect ( ast . children [ 0 ] . name ) . toBe ( 'test' ) ; expect ( ast . children [ 1 ] . nodeType ) . toBe ( 'Class' ) ; expect ( ast . children [ 1 ] . name ) . toBe ( 'Test' ) ; expect ( ast . children [ 1 ] . children ) . toBeDefined ( ) ; expect ( ast . children [ 1 ] . children [ 0 ] . nodeType ) . toBe ( 'Field' ) ; expect ( ast . children [ 1 ] . children [ 0 ] . attr . fieldName ) . toBe ( 'intField' ) ; expect ( ast . children [ 1 ] . children [ 0 ] . attr . fieldType ) . toBe ( 'number' ) ; } ) ; it ( " can parse a simple class starting with an imported type namspace" , ( ) => { let ast = testGrammar ( importedClassXsd ) ; expect ( ast . children . length ) . toBe ( 1 ) ; expect ( ast . children [ 0 ] . nodeType ) . toBe ( 'Class' ) ; expect ( ast . children [ 0 ] . name ) . toBe ( 'Test' ) ; expect ( ast . children [ 0 ] . children ) . toBeDefined ( ) ; expect ( ast . children [ 0 ] . children [ 0 ] . nodeType ) . toBe ( 'Field' ) ; expect ( ast . children [ 0 ] . children [ 0 ] . attr . fieldName ) . toBe ( 'firstName' ) ; expect ( ast . children [ 0 ] . children [ 0 ] . attr . fieldType ) . toBe ( 'string' ) ; expect ( ast . children [ 0 ] . children [ 2 ] . nodeType ) . toBe ( 'Field' ) ; expect ( ast . children [ 0 ] . children [ 2 ] . attr . fieldName ) . toBe ( 'imported' ) ; expect ( ast . children [ 0 ] . children [ 2 ] . attr . fieldType ) . toBe ( 'dep.Node' ) ; } ) ; it ( " can parse a simple simple Inherited Class" , ( ) => { let ast = testGrammar ( simpleInheritedClassXsd ) ; expect ( ast . children . length ) . toBe ( 2 ) ; expect ( ast . children [ 0 ] . nodeType ) . toBe ( 'Class' ) ; expect ( ast . children [ 0 ] . name ) . toBe ( 'InheridedClass' ) ; expect ( ast . children [ 0 ] . children ) . toBeDefined ( ) ; expect ( ast . children [ 0 ] . children [ 0 ] . nodeType ) . toBe ( 'Field' ) ; expect ( ast . children [ 0 ] . children [ 0 ] . attr . fieldName ) . toBe ( 'nestedFields' ) ; expect ( ast . children [ 0 ] . children [ 0 ] . attr . fieldType ) . toBe ( 'NestedFields' ) ; expect ( ast . children [ 0 ] . children [ 2 ] . nodeType ) . toBe ( 'Field' ) ; expect ( ast . children [ 0 ] . children [ 2 ] . attr . fieldName ) . toBe ( 'dateField' ) ; expect ( ast . children [ 0 ] . children [ 2 ] . attr . fieldType ) . toBe ( 'Date' ) ; } ) ; it ( " can parse a simple enumeration and simpletypes starting with element" , ( ) => { let ast = testGrammar ( simpleTypeXsd ) ; expect ( ast . children [ 0 ] . nodeType ) . toBe ( 'AliasType' ) ; expect ( ast . children [ 0 ] . name ) . toBe ( 'age1' ) ; expect ( ast . children [ 0 ] . attr . type ) . toBe ( 'number' ) ; expect ( ast . children [ 1 ] . nodeType ) . toBe ( 'AliasType' ) ; expect ( ast . children [ 1 ] . name ) . toBe ( 'age2' ) ; expect ( ast . children [ 1 ] . attr . type ) . toBe ( 'number' ) ; expect ( ast . children [ 2 ] . nodeType ) . toBe ( 'Enumeration' ) ; expect ( ast . children [ 2 ] . name ) . toBe ( 'option' ) ; expect ( ast . children [ 2 ] . attr . values ) . toBeDefined ( ) ; expect ( ast . children [ 2 ] . attr . values [ 0 ] . attr . value ) . toBe ( 'A' ) ; expect ( ast . children [ 2 ] . attr . values [ 1 ] . attr . value ) . toBe ( 'B' ) ; } ) ; it ( " can parse a group tag" , ( ) => { let ast = testGrammar ( groupXsd ) ; expect ( ast . children [ 0 ] . nodeType ) . toBe ( 'Group' ) ; expect ( ast . children [ 0 ] . name ) . toBe ( 'custGroup' ) ; expect ( ast . children [ 1 ] . nodeType ) . toBe ( 'AliasType' ) ; expect ( ast . children [ 1 ] . name ) . toBe ( 'order' ) ; expect ( ast . children [ 2 ] . nodeType ) . toBe ( 'Class' ) ; expect ( ast . children [ 2 ] . name ) . toBe ( 'Ordertype' ) ; } ) ; it ( " can parse an attribute group tag" , ( ) => { let ast = testGrammar ( typesXsd ) ; expect ( ast . children [ 0 ] . nodeType ) . toBe ( 'Group' ) ; expect ( ast . children [ 0 ] . name ) . toBe ( 'BaseView' ) ; expect ( ast . children [ 1 ] . nodeType ) . toBe ( 'Class' ) ; expect ( ast . children [ 1 ] . name ) . toBe ( 'View' ) ; } ) ; } ) ; function printFile ( fname ) { const s = fs . readFileSync ( fname ) . toString ( ) ; console . log ( s ) ; } function testGrammar ( elmXsd ) { const grammar = new XsdGrammar ( "Schema" ) ; console . log ( 'src:' , elmXsd ) ; const xmlDom = new DOMParser ( ) . parseFromString ( elmXsd , 'application/xml' ) ; const xmlNode = xmlDom . documentElement ; let ast = grammar . parse ( xmlNode ) ; console . log ( '\n-----\nast:' , JSON . stringify ( ( ast || '' ) , null , ' ' ) ) ; expect ( ast ) . toBeDefined ( ) ; expect ( ast . nodeType ) . toBe ( 'schema' ) ; return ast ; } function compile ( tsFiles ) { _compile ( tsFiles , { module : ts . ModuleKind . CommonJS , noEmitOnError : true , noImplicitAny : false , target : ts . ScriptTarget . ES5 , } ) ; } function _compile ( fileNames , options ) { let program = ts . createProgram ( fileNames , options ) ; let emitResult = program . emit ( ) ; let allDiagnostics = ts . getPreEmitDiagnostics ( program ) . concat ( emitResult . diagnostics ) ; allDiagnostics . forEach ( diagnostic => { if ( diagnostic . file ) { let { line , character } = diagnostic . file . getLineAndCharacterOfPosition ( diagnostic . start ! ) ; let message = ts . flattenDiagnosticMessageText ( diagnostic . messageText , "\n" ) ; console . log ( `${ diagnostic . file . fileName } (${ line + 1 },${ character + 1 }): ${ message }` ) ; } else { console . log ( ts . flattenDiagnosticMessageText ( diagnostic . messageText , "\n" ) ) ; } } ) ; let exitCode = emitResult . emitSkipped ? 1 : 0 ; console . log ( `Process exiting with code '${ exitCode }'.` ) ; process . exit ( exitCode ) ; }