diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fd6d18c..3585a85 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,20 +22,58 @@ jobs: strategy: fail-fast: false matrix: - cfengine: [ "lucee@5", "lucee@6", "adobe@2018", "adobe@2021" ] + cfengine: [ "lucee@5", "lucee@6" ,"adobe@2018", "adobe@2021", "adobe@2023", "adobe@2025", "boxlang-cfml@1" ] + coldboxVersion: [ "^6.0.0", "^7.0.0", "^8.0.0" ] experimental: [ false ] include: - - cfengine: "boxlang@1" + - coldboxVersion: "^8.0.0" + cfengine: "boxlang@1" + experimental: false + - coldboxVersion: "be" + cfengine: "lucee@5" + experimental: true + - coldboxVersion: "be" + cfengine: "lucee@6" + experimental: true + - coldboxVersion: "be" + cfengine: "lucee@be" + experimental: true + - coldboxVersion: "be" + cfengine: "adobe@2018" + experimental: true + - coldboxVersion: "be" + cfengine: "adobe@2021" + experimental: true + - coldboxVersion: "be" + cfengine: "adobe@2023" + experimental: true + - coldboxVersion: "be" + cfengine: "adobe@2025" + experimental: true + - coldboxVersion: "be" + cfengine: "adobe@be" + experimental: true + - coldboxVersion: "be" + cfengine: "boxlang@1" + experimental: true + - coldboxVersion: "be" + cfengine: "boxlang@be" + experimental: true + - coldboxVersion: "be" + cfengine: "boxlang-cfml@1" + experimental: true + - coldboxVersion: "be" + cfengine: "boxlang-cfml@be" experimental: true steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v5 - name: Setup Java - uses: actions/setup-java@v2 + uses: actions/setup-java@v5 with: - distribution: "adopt" - java-version: "11" + distribution: "temurin" + java-version: 21 - name: Cache CommandBox Dependencies uses: actions/cache@v4 @@ -46,28 +84,22 @@ jobs: restore-keys: | ${{ runner.OS }}-commandbox-cache-${{ hashFiles( 'box.json' ) }}-${{ hashFiles( 'test-harness/box.json' ) }} - - name: Setup CommandBox - uses: elpete/setup-commandbox@v1.0.0 - - - name: Update Commandbox Boxlang Module - if: ${{ matrix.cfengine == 'boxlang@1' }} - run: - box install --force commandbox-boxlang + - name: Setup CommandBox CLI + uses: Ortus-Solutions/setup-commandbox@v2.0.1 + with: + install: commandbox-boxlang - - name: Install Test Harness Dependencies - working-directory: ./test-harness + - name: Install Test Harness with ColdBox ${{ matrix.coldboxVersion }} run: | box install + cd test-harness + box package set dependencies.coldbox=${{ matrix.coldboxVersion }} + box install - name: Start ${{ matrix.cfengine }} Server - working-directory: ./test-harness run: | echo "matrix.cfengine=${{ matrix.cfengine }}" > ./.env box server start serverConfigFile="server-${{ matrix.cfengine }}.json" --noSaveSettings --debug - # Install Adobe 2021 cfpm modules - if [[ "${{ matrix.cfengine }}" == "adobe@2021" ]] ; then - box run-script install:2021 - fi curl http://127.0.0.1:60299 - name: Run Tests @@ -125,17 +157,17 @@ jobs: build: name: Build & Publish needs: tests - runs-on: ubuntu-24.04 + runs-on: ubuntu-latest steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v5 with: fetch-depth: 0 - name: Setup Java - uses: actions/setup-java@v2 + uses: actions/setup-java@v5 with: - distribution: "adopt" + distribution: "temurin" java-version: "11" - name: Cache CommandBox Dependencies @@ -147,10 +179,11 @@ jobs: restore-keys: | ${{ runner.OS }}-commandbox-cache-${{ hashFiles( 'box.json' ) }}-${{ hashFiles( 'test-harness/box.json' ) }} - - name: Setup CommandBox - uses: elpete/setup-commandbox@v1.0.0 + - name: Setup CommandBox CLI + uses: Ortus-Solutions/setup-commandbox@v2.0.1 with: forgeboxAPIKey: ${{ secrets.FORGEBOX_TOKEN }} + install: commandbox-docbox - name: Setup Environment Variables For Build Process id: current_version @@ -167,7 +200,6 @@ jobs: - name: Build ${{ env.MODULE_ID }} run: | - box install commandbox-docbox box task run taskfile=build/Build target=run :version=${{ env.VERSION }} :projectName=${{ env.MODULE_ID }} :buildID=${{ github.run_number }} :branch=${{ env.BRANCH }} - name: Upload Build Artifacts diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index d338ab0..bfec95b 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -13,50 +13,83 @@ on: jobs: tests: name: Tests - runs-on: ubuntu-24.04 + runs-on: ubuntu-latest env: DB_USER: root DB_PASSWORD: root - continue-on-error: ${{ matrix.experimental }} + continue-on-error: ${{ matrix.experimental }} strategy: - fail-fast: true + fail-fast: false matrix: - cfengine: [ "lucee@5", "adobe@2018", "adobe@2021" ] + cfengine: [ "lucee@5", "lucee@6" ,"adobe@2018", "adobe@2021", "adobe@2023", "adobe@2025", "boxlang-cfml@1" ] + coldboxVersion: [ "^6.0.0", "^7.0.0", "^8.0.0" ] + experimental: [ false ] include: - - cfengine: "boxlang@1" + - coldboxVersion: "^8.0.0" + cfengine: "boxlang@1" + experimental: false + - coldboxVersion: "be" + cfengine: "lucee@5" + experimental: true + - coldboxVersion: "be" + cfengine: "lucee@6" + experimental: true + - coldboxVersion: "be" + cfengine: "lucee@be" + experimental: true + - coldboxVersion: "be" + cfengine: "adobe@2018" + experimental: true + - coldboxVersion: "be" + cfengine: "adobe@2021" + experimental: true + - coldboxVersion: "be" + cfengine: "adobe@2023" + experimental: true + - coldboxVersion: "be" + cfengine: "adobe@2025" + experimental: true + - coldboxVersion: "be" + cfengine: "adobe@be" + experimental: true + - coldboxVersion: "be" + cfengine: "boxlang@1" + experimental: true + - coldboxVersion: "be" + cfengine: "boxlang@be" + experimental: true + - coldboxVersion: "be" + cfengine: "boxlang-cfml@1" + experimental: true + - coldboxVersion: "be" + cfengine: "boxlang-cfml@be" experimental: true steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v5 - name: Setup Java - uses: actions/setup-java@v2 + uses: actions/setup-java@v5 with: - distribution: "adopt" - java-version: "11" - - - name: Setup CommandBox - uses: elpete/setup-commandbox@v1.0.0 + distribution: "temurin" + java-version: 21 - - name: Update Commandbox Boxlang Module - if: ${{ matrix.cfengine == 'boxlang@1' }} - run: - box install --force commandbox-boxlang + - name: Setup CommandBox CLI + uses: Ortus-Solutions/setup-commandbox@v2.0.1 + with: + install: commandbox-boxlang - - name: Install Test Harness Dependencies - working-directory: ./test-harness + - name: Install Test Harness with ColdBox ${{ matrix.coldboxVersion }} run: | box install + cd test-harness + box package set dependencies.coldbox=${{ matrix.coldboxVersion }} + box install - name: Start ${{ matrix.cfengine }} Server - working-directory: ./test-harness run: | echo "matrix.cfengine=${{ matrix.cfengine }}" > ./.env box server start serverConfigFile="server-${{ matrix.cfengine }}.json" --noSaveSettings --debug - # Install Adobe 2021 cfpm modules - if [[ "${{ matrix.cfengine }}" == "adobe@2021" ]] ; then - box run-script install:2021 - fi curl http://127.0.0.1:60299 - name: Run Tests @@ -81,22 +114,21 @@ jobs: format: name: Format - runs-on: ubuntu-24.04 + runs-on: ubuntu-latest steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v5 - name: Setup Java - uses: actions/setup-java@v2 + uses: actions/setup-java@v5 with: - distribution: "adopt" + distribution: "temurin" java-version: "11" - - name: Set Up CommandBox - uses: elpete/setup-commandbox@v1.0.0 - - - name: Install CFFormat - run: box install commandbox-cfformat + - name: Setup CommandBox CLI + uses: Ortus-Solutions/setup-commandbox@v2.0.1 + with: + install: commandbox-cfformat - name: Run CFFormat run: box run-script format diff --git a/.gitignore b/.gitignore index 92855d3..ce903b2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .artifacts/** .tmp/** +modules/ test-harness/.engine/** test-harness/.env @@ -11,6 +12,7 @@ test-harness/testbox/** test-harness/logs/** test-harness/modules/** test-harness/tests/resources/petstore/test.yaml +.engine/** # log files logs/** \ No newline at end of file diff --git a/ModuleConfig.cfc b/ModuleConfig.cfc index 795c6a6..6f3e900 100644 --- a/ModuleConfig.cfc +++ b/ModuleConfig.cfc @@ -6,21 +6,21 @@ component { // Module Properties - this.title = "ColdBox Swagger SDK"; - this.author = "Ortus Solutions"; - this.webURL = "https://www.ortussolutions.com"; - this.description = "Swagger SDK Module"; - this.version = "@build.version@+@build.number@"; - this.viewParentLookup = true; + this.title = "ColdBox Swagger SDK"; + this.author = "Ortus Solutions"; + this.webURL = "https://www.ortussolutions.com"; + this.description = "Swagger SDK Module"; + this.version = "@build.version@+@build.number@"; + this.viewParentLookup = true; this.layoutParentLookup = true; // Model Namespace - this.modelNamespace = "SwaggerSDK"; + this.modelNamespace = "SwaggerSDK"; // CF Mapping - this.cfmapping = "SwaggerSDK"; + this.cfmapping = "SwaggerSDK"; // Auto-map models - this.autoMapModels = false; + this.autoMapModels = false; // Module Dependencies That Must Be Loaded First, use internal names or aliases - this.dependencies = [ "cbjavaloader" ]; + this.dependencies = [ "cbjavaloader" ]; /** * Configure App @@ -33,14 +33,13 @@ component { */ function onLoad(){ // load jars - wirebox.getInstance( "loader@cbjavaloader" ) - .appendPaths( variables.modulePath & "/lib" ); + wirebox.getInstance( "loader@cbjavaloader" ).appendPaths( variables.modulePath & "/lib" ); /** - * Utilities - * - */ + * Utilities + * + */ // Open API Util binder @@ -51,9 +50,9 @@ component { /** - * Manual Instantiation Instances - * - */ + * Manual Instantiation Instances + * + */ // models.OpenAPI.Document binder diff --git a/box.json b/box.json index 1b22a4a..7ac2cb6 100644 --- a/box.json +++ b/box.json @@ -32,6 +32,12 @@ "*/.md" ], "scripts":{ - "toMaster":"recipe build/toMaster.boxr" + "toMaster":"recipe build/toMaster.boxr", + "format":"cfformat run models,test-harness/tests/resources/BaseOpenAPISpec.cfc,test-harness/tests/specs,ModuleConfig.cfc --overwrite", + "format:watch":"cfformat watch models,test-harness/tests/resources/BaseOpenAPISpec.cfc,test-harness/tests/specs,ModuleConfig.cfc ./.cfformat.json", + "format:check":"cfformat check models,test-harness/tests/resources/BaseOpenAPISpec.cfc,test-harness/tests/specs,ModuleConfig.cfc ./.cfformat.json", + }, + "installPaths":{ + "cbjavaloader":"modules/cbjavaloader/" } } diff --git a/models/OpenAPI/Document.cfc b/models/OpenAPI/Document.cfc index 3b514b5..f95baa0 100644 --- a/models/OpenAPI/Document.cfc +++ b/models/OpenAPI/Document.cfc @@ -20,8 +20,10 @@ component name="OpenAPIDocument" accessors="true" { * @param Doc The document representation * @param XPath The XPath of the document to zoom this Document object to **/ - Document function init( required struct Doc, required string XPath="" ){ - + Document function init( + required struct Doc, + required string XPath = "" + ){ // Scope the root Document to handle internal inheritance $refs setRootDocument( arguments.Doc ); @@ -29,31 +31,32 @@ component name="OpenAPIDocument" accessors="true" { setDocument( arguments.Doc ); // Zoom if requested - if( len( arguments.XPath ) ){ - arguments.XPath = arrayToList( listToArray( arguments.XPath, "/" ), "." ); - this - .setXPath( arguments.XPath ) - .zoomToXPath(); + if ( len( arguments.XPath ) ) { + arguments.XPath = arrayToList( + listToArray( arguments.XPath, "/" ), + "." + ); + this.setXPath( arguments.XPath ).zoomToXPath(); } return this; } /** - * Convenience methot for setting the XPath of the Document - * - * @param XPath The XPath to zoom the parsed document to during recursion - **/ + * Convenience methot for setting the XPath of the Document + * + * @param XPath The XPath to zoom the parsed document to during recursion + **/ Document function xPath( required string XPath ){ this.setXPath( arguments.XPath ); return this; } /** - * Zooms this Document instance to the XPath - **/ + * Zooms this Document instance to the XPath + **/ Document function zoomToXPath(){ - if( isNull( getXPath() ) ) return; + if ( isNull( getXPath() ) ) return; setDocument( locate( getXPath() ) ); @@ -71,7 +74,7 @@ component name="OpenAPIDocument" accessors="true" { * Convenience method to return a YAML string of the normalized document **/ function asYAML(){ - return variables.jLoader + return server.keyExists( "boxlang" ) ? yamlSerialize( getNormalizedDocument() ) : variables.jLoader .create( "org.yaml.snakeyaml.Yaml" ) .dump( getNormalizedDocument() ); } @@ -88,29 +91,39 @@ component name="OpenAPIDocument" accessors="true" { * * @param APIDoc The document to normalized. Defaults to the entity document **/ - function getNormalizedDocument( any APIDoc=this.getDocument() ){ - if( isArray( arguments.APIDoc ) ){ - return arrayMap( arguments.APIDoc, function( item ) { - return getNormalizedDocument( item ); - } ); - } else if ( isObject( arguments.APIDoc ) && findNoCase( "Parser", getMetaData( arguments.APIDoc ).name ) ) { - if ( !structKeyExists( arguments.APIDoc, "getDocumentObject" ) ) { - throwForeignObjectTypeException( arguments.APIDoc ); - throw( - type = "SwaggerSDK.NormalizationException", - message = "SwaggerSDK doesn't know what do with an object of type #getMetaData( arguments.APIDoc ).name#." - ); - } - - return arguments.APIDoc.getDocumentObject().getNormalizedDocument(); - } else if ( isStruct( arguments.APIDoc ) ) { - return structMap( arguments.APIDoc, function( key, value ) { + function getNormalizedDocument( any APIDoc = this.getDocument() ){ + if ( isArray( arguments.APIDoc ) ) { + return arrayMap( arguments.APIDoc, function( item ){ + return getNormalizedDocument( item ); + } ); + } else if ( + isObject( arguments.APIDoc ) && findNoCase( + "Parser", + getMetadata( arguments.APIDoc ).name + ) + ) { + if ( + !structKeyExists( + arguments.APIDoc, + "getDocumentObject" + ) + ) { + throwForeignObjectTypeException( arguments.APIDoc ); + throw( + type = "SwaggerSDK.NormalizationException", + message = "SwaggerSDK doesn't know what do with an object of type #getMetadata( arguments.APIDoc ).name#." + ); + } + + return arguments.APIDoc.getDocumentObject().getNormalizedDocument(); + } else if ( isStruct( arguments.APIDoc ) ) { + return structMap( arguments.APIDoc, function( key, value ){ // allow explicit nulls in sample docs to pass through - return !isNull( value ) ? getNormalizedDocument( value ) : javacast( "null", 0 ); - } ); - } + return !isNull( value ) ? getNormalizedDocument( value ) : javacast( "null", 0 ); + } ); + } - return arguments.APIDoc; + return arguments.APIDoc; } /** @@ -123,12 +136,17 @@ component name="OpenAPIDocument" accessors="true" { any function locate( string key ){ var rootDocument = this.getRootDocument(); - if( structKeyExists( rootDocument, arguments.key ) ){ + if ( structKeyExists( rootDocument, arguments.key ) ) { return rootDocument[ arguments.key ]; - } else if( isDefined( 'rootDocument.#arguments.key#' ) ){ - return evaluate( 'rootDocument.#arguments.key#' ); + } else if ( isDefined( "rootDocument.#arguments.key#" ) ) { + return evaluate( "rootDocument.#arguments.key#" ); } else { - return { "$ref" : "##/#arrayToList( listToArray( arguments.key, "." ), "/" )#"}; + return { + "$ref" : "##/#arrayToList( + listToArray( arguments.key, "." ), + "/" + )#" + }; } } @@ -137,13 +155,13 @@ component name="OpenAPIDocument" accessors="true" { /********************************************************************************/ /** - * Throws a foreign object type exception if detected when normalizing a document - * @param UnKnownObject The foreign object detected - **/ + * Throws a foreign object type exception if detected when normalizing a document + * @param UnKnownObject The foreign object detected + **/ private function throwForeignObjectTypeException( required any UnKnownObject ){ throw( - type="SwaggerSDK.ForeignObjectException", - message="SwaggerSDK doesn't know what do with an object of type #getMetaData( UnKnownObject ).name#." + type = "SwaggerSDK.ForeignObjectException", + message = "SwaggerSDK doesn't know what do with an object of type #getMetadata( UnKnownObject ).name#." ); } diff --git a/models/OpenAPI/Parser.cfc b/models/OpenAPI/Parser.cfc index fb10dcd..0b9fe40 100644 --- a/models/OpenAPI/Parser.cfc +++ b/models/OpenAPI/Parser.cfc @@ -1,99 +1,106 @@ /** -* Copyright Ortus Solutions, Corp, All rights reserved -* www.ortussolutions.com -* --- -* Open API Parser -*/ + * Copyright Ortus Solutions, Corp, All rights reserved + * www.ortussolutions.com + * --- + * Open API Parser + */ component name="OpenAPIParser" accessors="true" { - //the base path of the APIDoc + + // the base path of the APIDoc property name="DocumentObject"; property name="baseDocumentPath"; property name="schemaType"; property name="Wirebox" inject="wirebox"; property name="jLoader" inject="loader@cbjavaloader"; - property name="Utils" inject="OpenAPIUtil@SwaggerSDK"; + property name="Utils" inject="OpenAPIUtil@SwaggerSDK"; /** - * Constructor - * @param APIDocPath The path of the top-level API description file. Valid extensions: .json, .yaml, .json.cfm - **/ + * Constructor + * @param APIDocPath The path of the top-level API description file. Valid extensions: .json, .yaml, .json.cfm + **/ public function init( string APIDocPath ){ - var refArray = listToArray( arguments.APIDocPath, chr( 35 ) ); var DocPath = refArray[ 1 ]; - if( arrayLen( refArray ) > 1 ) { + if ( arrayLen( refArray ) > 1 ) { var XPath = refArray[ 2 ]; } else { - XPath=""; + XPath = ""; } - if( left( DocPath, 4 ) != 'http' && !fileExists( DocPath ) ) { - throw( type="SwaggerSDK.ParserException", message="The APIDoc file #arguments.APIDocPath# does not exist." ); + if ( left( DocPath, 4 ) != "http" && !fileExists( DocPath ) ) { + throw( + type = "SwaggerSDK.ParserException", + message = "The APIDoc file #arguments.APIDocPath# does not exist." + ); } setBaseDocumentPath( DocPath ); - setSchemaType( ucase( listLast( DocPath, '.' ) ) ); + setSchemaType( uCase( listLast( DocPath, "." ) ) ); var documentContent = ""; - switch( getSchemaType() ){ + switch ( getSchemaType() ) { case "cfm": savecontent variable="documentContent" { include APath; } - if( !isJSON( trim( documentContent ) ) ) throwInvalidJSONException( documentContent ); + if ( !isJSON( trim( documentContent ) ) ) throwInvalidJSONException( documentContent ); documentContent = serializeJSON( trim( documentContent ) ); break; - case "yaml": case "yml": - - var YAMLLoader = jLoader.create( "org.yaml.snakeyaml.Yaml" ); - var IOFile = jLoader.create( "java.io.File" ).init( DocPath ); - var InputStream = jLoader.create( "java.io.FileInputStream" ).init( IOFile ); - - documentContent = getUtils().toCF( YAMLLoader.load( InputStream ) ); - + if ( server.keyExists( "boxlang" ) ) { + documentContent = yamlDeserialize( fileRead( DocPath ) ); + } else { + var YAMLLoader = jLoader.create( "org.yaml.snakeyaml.Yaml" ); + var IOFile = jLoader.create( "java.io.File" ).init( DocPath ); + var InputStream = jLoader.create( "java.io.FileInputStream" ).init( IOFile ); + + documentContent = getUtils().toCF( YAMLLoader.load( InputStream ) ); + } break; - case "json": - if( left( DocPath, 4 ) == 'http' ){ + if ( left( DocPath, 4 ) == "http" ) { var req = new http(); req.setMethod( "GET" ); req.setURL( DocPath ); documentContent = req.send().getPrefix().filecontent; - } else{ + } else { documentContent = fileRead( DocPath ); } - if( !isJSON( documentContent ) ) throwInvalidJSONException( documentContent ); + if ( !isJSON( documentContent ) ) throwInvalidJSONException( documentContent ); - documentContent = deSerializeJSON( documentContent ); + documentContent = deserializeJSON( documentContent ); break; - default: throw( - type="SwaggerSDK.ParserException", - message="SwaggerSDK does not support schema using the .#lcase(getSchemaType())# file extension." + type = "SwaggerSDK.ParserException", + message = "SwaggerSDK does not support schema using the .#lCase( getSchemaType() )# file extension." ); } - return parse( documentContent , XPath ); + return parse( documentContent, XPath ); } /** - * Parses an API Document recursively - * - * @param APIDoc The struct representation of the API Document - * @param [XPath] The XPath to zoom the parsed document to during recursion - **/ - public function parse( required struct APIDoc, required string XPath="" ){ - setDocumentObject( getWirebox().getInstance( "OpenAPIDocument@SwaggerSDK" ).init( arguments.APIDoc, arguments.XPath) ); + * Parses an API Document recursively + * + * @param APIDoc The struct representation of the API Document + * @param [XPath] The XPath to zoom the parsed document to during recursion + **/ + public function parse( + required struct APIDoc, + required string XPath = "" + ){ + setDocumentObject( + getWirebox().getInstance( "OpenAPIDocument@SwaggerSDK" ).init( arguments.APIDoc, arguments.XPath ) + ); parseDocumentInheritance( parseDocumentReferences( getDocumentObject().getDocument() ) ); @@ -101,194 +108,191 @@ component name="OpenAPIParser" accessors="true" { } /** - * Loads a linked hash map from a JSON file - * - * @param JSONData The raw JSON string - **/ + * Loads a linked hash map from a JSON file + * + * @param JSONData The raw JSON string + **/ private function loadAsLinkedHashMap( required string JSONData ){ - - var JSONFactory = jLoader.create("com.fasterxml.jackson.core.JsonFactory" ); - var Codec = jLoader.create( "com.fasterxml.jackson.core.ObjectCodec" ); - var CodecProxy = createObject("java", "coldfusion.runtime.java.JavaProxy" ).init( Codec ); - - var Parser = JSONFactory.createParser( arguments.JSONData ); - var Mapper = jLoader.create( "java.util.Map" ); + var JSONFactory = jLoader.create( "com.fasterxml.jackson.core.JsonFactory" ); + var Codec = jLoader.create( "com.fasterxml.jackson.core.ObjectCodec" ); + var CodecProxy = createObject( + "java", + "coldfusion.runtime.java.JavaProxy" + ).init( Codec ); + + var Parser = JSONFactory.createParser( arguments.JSONData ); + var Mapper = jLoader.create( "java.util.Map" ); var HashMap = structNew( "ordered" ); - HashMap.putAll( deSerializeJSON( JSONData ) ); + HashMap.putAll( deserializeJSON( JSONData ) ); } /** - * Parses API Document $ref notations recursively - * - * @param APIDoc The struct representation of the API Document - * @param [XPath] The XPath to zoom the parsed document to during recursion - **/ + * Parses API Document $ref notations recursively + * + * @param APIDoc The struct representation of the API Document + * @param [XPath] The XPath to zoom the parsed document to during recursion + **/ public function parseDocumentReferences( required any DocItem ){ - - if( isArray( DocItem ) ) { - for( var i = 1; i <= arrayLen( DocItem ); i++){ + if ( isArray( DocItem ) ) { + for ( var i = 1; i <= arrayLen( DocItem ); i++ ) { DocItem[ i ] = parseDocumentReferences( DocItem[ i ] ); } - } else if( isStruct( DocItem ) ) { - - //handle top-level values, if they exist - if( structKeyExists( DocItem, "$ref" ) ) { - // special handling for double pound signs - if( left( DocItem[ "$ref" ], 2 ) == chr( 35 ) & chr( 35 ) ) { - DocItem[ "$ref" ] = right( DocItem[ "$ref" ], ( len( DocItem[ "$ref" ] ) - 1 ) ); - return DocItem; - } - return fetchDocumentReference( DocItem[ "$ref" ] ); - } - - for( var key in DocItem){ + } else if ( isStruct( DocItem ) ) { + // handle top-level values, if they exist + if ( structKeyExists( DocItem, "$ref" ) ) { + // special handling for double pound signs + if ( left( DocItem[ "$ref" ], 2 ) == chr( 35 ) & chr( 35 ) ) { + DocItem[ "$ref" ] = right( + DocItem[ "$ref" ], + ( len( DocItem[ "$ref" ] ) - 1 ) + ); + return DocItem; + } + return fetchDocumentReference( DocItem[ "$ref" ] ); + } - if( isNull( docItem[ key ] ) ){ + for ( var key in DocItem ) { + if ( isNull( docItem[ key ] ) ) { DocItem[ key ] = nullValue(); continue; } - // If `DocItem[ key ]` is an instance of Parser, we need to flattin it to a CFML struct + // If `DocItem[ key ]` is an instance of Parser, we need to flattin it to a CFML struct if ( isStruct( DocItem[ key ] ) && - findNoCase( "Parser", getMetaData( DocItem[ key ] ).name ) + structKeyExists( + getMetadata( DocItem[ key ] ), + "name" + ) && + findNoCase( + "Parser", + getMetadata( DocItem[ key ] ).name + ) ) { DocItem[ key ] = DocItem[ key ].getNormalizedDocument(); } - if ( + if ( isStruct( DocItem[ key ] ) && structKeyExists( DocItem[ key ], "$ref" ) ) { - DocItem[ key ] = parseDocumentReferences( fetchDocumentReference( DocItem[ key ][ "$ref" ] ) ); - - } else if( isStruct( DocItem[ key ] ) || isArray( DocItem[ key ] ) ){ - + } else if ( isStruct( DocItem[ key ] ) || isArray( DocItem[ key ] ) ) { DocItem[ key ] = parseDocumentReferences( DocItem[ key ] ); - } - } } return DocItem; - } - /** - * Parses API Document $extend notations recursively - * - * @param APIDoc The struct representation of the API Document - * @param [XPath] The XPath to zoom the parsed document to during recursion - **/ + /** + * Parses API Document $extend notations recursively + * + * @param APIDoc The struct representation of the API Document + * @param [XPath] The XPath to zoom the parsed document to during recursion + **/ public function parseDocumentInheritance( required any DocItem ){ + // If `DocItem` is an instance of Parser, we need to flattin it to a CFML struct + if ( + isStruct( DocItem ) && + structKeyExists( getMetadata( DocItem ), "name" ) && + findNoCase( + "Parser", + getMetadata( DocItem ).name + ) + ) { + DocItem = DocItem.getNormalizedDocument(); + } - // If `DocItem` is an instance of Parser, we need to flattin it to a CFML struct - if ( - isStruct( DocItem ) && - findNoCase( "Parser", getMetaData( DocItem ).name ) - ) { - DocItem = DocItem.getNormalizedDocument(); - } - - if( isArray( DocItem ) ) { - for( var i = 1; i <= arrayLen( DocItem ); i++){ + if ( isArray( DocItem ) ) { + for ( var i = 1; i <= arrayLen( DocItem ); i++ ) { DocItem[ i ] = parseDocumentInheritance( DocItem[ i ] ); } - } else if( isStruct( DocItem ) ) { - - // handle top-level extension - if( structKeyExists( DocItem, "$extend" ) ) { - return extendObject( parseDocumentInheritance( DocItem[ "$extend" ] ) ); - } - - for( var key in DocItem ){ + } else if ( isStruct( DocItem ) ) { + // handle top-level extension + if ( structKeyExists( DocItem, "$extend" ) ) { + return extendObject( parseDocumentInheritance( DocItem[ "$extend" ] ) ); + } - if( isNull( docItem[ key ] ) ){ + for ( var key in DocItem ) { + if ( isNull( docItem[ key ] ) ) { DocItem[ key ] = nullValue(); continue; } - if( isStruct( DocItem[ key ] ) || isArray( DocItem[ key ] ) ){ - DocItem[ key ] = parseDocumentInheritance( DocItem[ key ] ); - } - - } - + if ( isStruct( DocItem[ key ] ) || isArray( DocItem[ key ] ) ) { + DocItem[ key ] = parseDocumentInheritance( DocItem[ key ] ); + } + } } return DocItem; - } - /** - * Extends schema definitions based on the passed array of schema objects - * Note: Ignores CFML objects (non-structs) because sometimes the parser gets passed in here for some reason - * - * @objects - */ - function extendObject( array objects ) { - - var output = {}; - objects.each( function( item, index ) { - if ( isStruct( item ) ) { - item.each( function( key, value ) { - - if ( - output.keyExists( key ) && - isStruct( output[ key ] ) - ) { - output[ key ].append( value, true ); - } else { - output[ key ] = value - } - - } ); - } - } ); + /** + * Extends schema definitions based on the passed array of schema objects + * Note: Ignores CFML objects (non-structs) because sometimes the parser gets passed in here for some reason + * + * @objects + */ + function extendObject( array objects ){ + var output = {}; + objects.each( function( item, index ){ + if ( isStruct( item ) ) { + item.each( function( key, value ){ + if ( + output.keyExists( key ) && + isStruct( output[ key ] ) + ) { + output[ key ].append( value, true ); + } else { + output[ key ] = value + } + } ); + } + } ); - return output; - } + return output; + } /** - * Retrieves the value from a nested struct when given an XPath argument - * - * @param XPath The XPath to zoom the parsed document to during recursion - **/ + * Retrieves the value from a nested struct when given an XPath argument + * + * @param XPath The XPath to zoom the parsed document to during recursion + **/ public function getInternalXPath( required string XPath ){ var PathArray = listToArray( XPath, "/" ); return getDocumentObject().locate( arrayToList( PathArray, "." ) ); } /** - * Convenience method to return the fully normalize document - **/ + * Convenience method to return the fully normalize document + **/ public function getNormalizedDocument(){ return getDocumentObject().getNormalizedDocument(); } /** - * Fetches a document $ref object - * @param $ref The $ref value - **/ + * Fetches a document $ref object + * @param $ref The $ref value + **/ private function fetchDocumentReference( required string $ref ){ - - // double pound ## means we want to preserve the swagger $ref pointer (just remove the extra #) - if( left( $ref, 2 ) == chr( 35 ) & chr( 35 ) ){ - return { "$ref": right( $ref, ( len( $ref ) - 1 ) ) }; - //resolve internal refrences before looking for externals - } else if( left( $ref, 1 ) == chr( 35 )){ + // double pound ## means we want to preserve the swagger $ref pointer (just remove the extra #) + if ( left( $ref, 2 ) == chr( 35 ) & chr( 35 ) ) { + return { "$ref" : right( $ref, ( len( $ref ) - 1 ) ) }; + // resolve internal refrences before looking for externals + } else if ( left( $ref, 1 ) == chr( 35 ) ) { var FilePath = ""; - var XPath = right( $ref, len( $ref ) - 1 ); + var XPath = right( $ref, len( $ref ) - 1 ); } else { var refArray = listToArray( $ref, chr( 35 ) ); var FilePath = refArray[ 1 ]; - if( arrayLen( refArray ) > 1 ) { + if ( arrayLen( refArray ) > 1 ) { var XPath = refArray[ 2 ]; - if( left( XPath, 1 ) == '/' ){ + if ( left( XPath, 1 ) == "/" ) { XPath = right( XPath, len( XPath ) - 1 ); } } @@ -296,60 +300,60 @@ component name="OpenAPIParser" accessors="true" { var ReferenceDocument = {}; - try{ - - //Files receive a parser reference - if( left( FilePath, 4 ) == 'http' ){ - - ReferenceDocument = Wirebox.getInstance( "OpenAPIParser@SwaggerSDK" ).init( $ref ); - - } else if( len( FilePath ) && fileExists( getDirectoryFromPath( getBaseDocumentPath() ) & FilePath )){ - - ReferenceDocument = Wirebox.getInstance( "OpenAPIParser@SwaggerSDK" ).init( getDirectoryFromPath( getBaseDocumentPath() ) & $ref ); - - } else if( len( FilePath ) && fileExists( expandPath( FilePath ) ) ) { - - ReferenceDocument = Wirebox.getInstance( "OpenAPIParser@SwaggerSDK" ).init( expandPath( FilePath ) & ( !isNull( xPath ) ? "##" & xPath : "" ) ); - - } else if( len( FilePath ) && !fileExists( getDirectoryFromPath( getBaseDocumentPath() ) & FilePath )) { - - throw( type="SwaggerSDK.ParserException", message="File #( getDirectoryFromPath( getBaseDocumentPath() ) & FilePath )# does not exist" ); - - } else if( !isNull( XPath ) && len( XPath ) ) { - + try { + // Files receive a parser reference + if ( left( FilePath, 4 ) == "http" ) { + ReferenceDocument = Wirebox.getInstance( "OpenAPIParser@SwaggerSDK" ).init( $ref ); + } else if ( len( FilePath ) && fileExists( getDirectoryFromPath( getBaseDocumentPath() ) & FilePath ) ) { + ReferenceDocument = Wirebox + .getInstance( "OpenAPIParser@SwaggerSDK" ) + .init( getDirectoryFromPath( getBaseDocumentPath() ) & $ref ); + } else if ( len( FilePath ) && fileExists( expandPath( FilePath ) ) ) { + ReferenceDocument = Wirebox + .getInstance( "OpenAPIParser@SwaggerSDK" ) + .init( expandPath( FilePath ) & ( !isNull( xPath ) ? "##" & xPath : "" ) ); + } else if ( len( FilePath ) && !fileExists( getDirectoryFromPath( getBaseDocumentPath() ) & FilePath ) ) { + throw( + type = "SwaggerSDK.ParserException", + message = "File #( getDirectoryFromPath( getBaseDocumentPath() ) & FilePath )# does not exist" + ); + } else if ( !isNull( XPath ) && len( XPath ) ) { ReferenceDocument = getInternalXPath( XPath ); - } else { - - throw( type="SwaggerSDK.ParserException", message="The $ref #$ref# could not be resolved as either an internal or external reference"); - + throw( + type = "SwaggerSDK.ParserException", + message = "The $ref #$ref# could not be resolved as either an internal or external reference" + ); + } + } catch ( any e ) { + // if this is a known exception or occured via recursion, rethrow the exception so the user knows which JSON file triggered it + if ( + listFindNoCase( + "SwaggerSDK.ParserException,CBSwagger.InvalidReferenceDocumentException", + e.type + ) + ) { + rethrow; } - } catch( any e ){ - - // if this is a known exception or occured via recursion, rethrow the exception so the user knows which JSON file triggered it - if ( listFindNoCase( "SwaggerSDK.ParserException,CBSwagger.InvalidReferenceDocumentException", e.type ) ) { - rethrow; - } - - throw( - type="CBSwagger.InvalidReferenceDocumentException", - message="The $ref file pointer of #$ref# could not be loaded and parsed as a valid object. If your $ref file content is an array, please nest the array within an object as a named key. The message received was: #e.message# #e.detail#" + throw( + type = "CBSwagger.InvalidReferenceDocumentException", + message = "The $ref file pointer of #$ref# could not be loaded and parsed as a valid object. If your $ref file content is an array, please nest the array within an object as a named key. The message received was: #e.message# #e.detail#" ); - } - return ReferenceDocument; + return ReferenceDocument; } /** - * Multi-use error throw - * @param InvalidContent The content which cause the exception - **/ + * Multi-use error throw + * @param InvalidContent The content which cause the exception + **/ private function throwInvalidJSONException( required string InvalidContent ){ - - throw( type="SwaggerSDK.ParserException", message="The API Document Provided: #getBaseDocumentPath()# could not be converted to valid JSON" ); - + throw( + type = "SwaggerSDK.ParserException", + message = "The API Document Provided: #getBaseDocumentPath()# could not be converted to valid JSON" + ); } } diff --git a/models/OpenAPI/Util.cfc b/models/OpenAPI/Util.cfc index b76df0e..5ddd0f5 100644 --- a/models/OpenAPI/Util.cfc +++ b/models/OpenAPI/Util.cfc @@ -1,9 +1,9 @@ /** -* Copyright Ortus Solutions, Corp, All rights reserved -* www.ortussolutions.com -* --- -* Open API Utilities -*/ + * Copyright Ortus Solutions, Corp, All rights reserved + * www.ortussolutions.com + * --- + * Open API Utilities + */ component name="OpenAPIUtil" accessors="true" { /** @@ -18,27 +18,27 @@ component name="OpenAPIUtil" accessors="true" { */ any function newTemplate(){ // We need to use Linked Hashmaps to maintain struct order for serialization and deserialization - var template = structNew( "ordered" ); - var templateDefaults = [ - { "openapi" : "3.0.2" }, + var template = structNew( "ordered" ); + var templateDefaults = [ + { "openapi" : "3.0.2" }, { - "info" : { - "version" : "", - "title" : "", - "description" : "", - "termsOfService" : "", - "license" : structNew( "ordered" ), - "contact" : structNew( "ordered" ) - } + "info" : { + "version" : "", + "title" : "", + "description" : "", + "termsOfService" : "", + "license" : structNew( "ordered" ), + "contact" : structNew( "ordered" ) + } }, - { "servers" : [] }, - { "paths" : structNew( "ordered" ) }, - { "components" : structNew( "ordered" ) }, - { "security" : [] }, - { "tags" : [] } + { "servers" : [] }, + { "paths" : structNew( "ordered" ) }, + { "components" : structNew( "ordered" ) }, + { "security" : [] }, + { "tags" : [] } ]; - for( var templateDefault in templateDefaults ){ + for ( var templateDefault in templateDefaults ) { template.putAll( templateDefault ); } @@ -49,26 +49,22 @@ component name="OpenAPIUtil" accessors="true" { * Create a new method representation */ any function newMethod(){ - var method = structNew( "ordered" ); + var method = structNew( "ordered" ); var descMap = structNew( "ordered" ); descMap.put( "description", "" ); - //Other supported options are requestBody and tag will be added runtime - var methodDefaults = [ - { "summary" : "" }, - { "tags" : [] }, - { "description" : "" }, - { "operationId" : "" }, - { "parameters" : [] }, - { - "responses" : { - "default": descMap - } - } + // Other supported options are requestBody and tag will be added runtime + var methodDefaults = [ + { "summary" : "" }, + { "tags" : [] }, + { "description" : "" }, + { "operationId" : "" }, + { "parameters" : [] }, + { "responses" : { "default" : descMap } } ]; - for( var methodDefault in methodDefaults ){ + for ( var methodDefault in methodDefaults ) { method.putAll( methodDefault ); } @@ -79,7 +75,14 @@ component name="OpenAPIUtil" accessors="true" { * Get an array of default methods */ array function defaultMethods(){ - return [ "GET", "PUT", "POST" , "PATCH" , "DELETE" , "HEAD" ]; + return [ + "GET", + "PUT", + "POST", + "PATCH", + "DELETE", + "HEAD" + ]; } /** @@ -95,15 +98,14 @@ component name="OpenAPIUtil" accessors="true" { * @URLPath */ string function translatePath( required string URLPath ){ - var pathArray = listToArray( arguments.URLPath, '/' ); - for( var i=1; i <= arrayLen( pathArray ); i++ ){ - if( left( pathArray[ i ], 1 ) == ':' ){ + var pathArray = listToArray( arguments.URLPath, "/" ); + for ( var i = 1; i <= arrayLen( pathArray ); i++ ) { + if ( left( pathArray[ i ], 1 ) == ":" ) { pathArray[ i ] = "{" & replace( pathArray[ i ], ":", "" ) & "}"; } } return "/" & arrayToList( pathArray, "/" ); - } /** @@ -112,38 +114,32 @@ component name="OpenAPIUtil" accessors="true" { * @param Object Map The Java map object or array to be converted */ function toCF( map ){ + if ( isNull( arguments.map ) ) return; - if( isNull( arguments.map ) ) return; + // if we're in a loop iteration and the array item is simple, return it + if ( isSimpleValue( arguments.map ) ) return arguments.map; - //if we're in a loop iteration and the array item is simple, return it - if( isSimpleValue( arguments.map ) ) return arguments.map; - - if( isArray( map ) ){ + if ( isArray( map ) ) { var cfObj = []; - for( var obj in arguments.map ){ + for ( var obj in arguments.map ) { arrayAppend( cfObj, toCF( obj ) ); } - } else { - var cfObj = {}; - try{ + try { cfObj.putAll( arguments.map ); - - } catch ( any e ){ - + } catch ( any e ) { return arguments.map; } // loop our keys to ensure first-level items with sub-documents objects are converted - for( var key in cfObj ){ - - if( + for ( var key in cfObj ) { + if ( !isNull( cfObj[ key ] ) && ( isArray( cfObj[ key ] ) || isStruct( cfObj[ key ] ) ) - ){ + ) { cfObj[ key ] = toCF( cfObj[ key ] ); } } diff --git a/test-harness/server-adobe@2018.json b/server-adobe@2018.json similarity index 77% rename from test-harness/server-adobe@2018.json rename to server-adobe@2018.json index 7583bbe..036b5a4 100644 --- a/test-harness/server-adobe@2018.json +++ b/server-adobe@2018.json @@ -11,9 +11,14 @@ "rewrites":{ "enable":"true" }, + "webroot":"test-harness", "aliases":{ "/moduleroot/swagger-sdk":"../" } + }, + "jvm":{ + "heapSize":"1024", + "javaVersion":"openjdk8_jre" }, "openBrowser":"false" } \ No newline at end of file diff --git a/test-harness/server-adobe@2021.json b/server-adobe@2021.json similarity index 64% rename from test-harness/server-adobe@2021.json rename to server-adobe@2021.json index faf1764..86bdf44 100644 --- a/test-harness/server-adobe@2021.json +++ b/server-adobe@2021.json @@ -11,9 +11,17 @@ "rewrites":{ "enable":true }, + "webroot":"test-harness", "aliases":{ "/moduleroot/swagger-sdk":"../" } }, - "openBrowser":true + "jvm":{ + "heapSize":"1024", + "javaVersion":"openjdk11_jre" + }, + "openBrowser":true, + "scripts" : { + "onServerInstall" : "cfpm install zip" + } } \ No newline at end of file diff --git a/server-adobe@2023.json b/server-adobe@2023.json new file mode 100644 index 0000000..2c83d3f --- /dev/null +++ b/server-adobe@2023.json @@ -0,0 +1,23 @@ +{ + "name":"swagger-sdk-adobe@2023", + "app":{ + "serverHomeDirectory":".engine/adobe2023", + "cfengine":"adobe@2023" + }, + "web":{ + "http":{ + "port":"60299" + }, + "rewrites":{ + "enable":true + }, + "webroot":"test-harness", + "aliases":{ + "/moduleroot/swagger-sdk":"../" + } + }, + "openBrowser":true, + "scripts" : { + "onServerInstall" : "cfpm install zip" + } +} \ No newline at end of file diff --git a/server-adobe@2025.json b/server-adobe@2025.json new file mode 100644 index 0000000..ad1859f --- /dev/null +++ b/server-adobe@2025.json @@ -0,0 +1,27 @@ +{ + "name":"swagger-sdk-adobe@2025", + "app":{ + "serverHomeDirectory":".engine/adobe2025", + "cfengine":"adobe@2025" + }, + "web":{ + "http":{ + "port":"60299" + }, + "rewrites":{ + "enable":true + }, + "webroot":"test-harness", + "aliases":{ + "/moduleroot/swagger-sdk":"../" + } + }, + "jvm":{ + "heapSize":"1024", + "javaVersion":"openjdk21_jre" + }, + "openBrowser":true, + "scripts" : { + "onServerInstall" : "cfpm install zip" + } +} \ No newline at end of file diff --git a/server-adobe@be.json b/server-adobe@be.json new file mode 100644 index 0000000..b1a6e9f --- /dev/null +++ b/server-adobe@be.json @@ -0,0 +1,27 @@ +{ + "name":"swagger-sdk-adobe@be", + "app":{ + "serverHomeDirectory":".engine/adobeBE", + "cfengine":"adobe@be" + }, + "web":{ + "http":{ + "port":"60299" + }, + "rewrites":{ + "enable":true + }, + "webroot":"test-harness", + "aliases":{ + "/moduleroot/swagger-sdk":"../" + } + }, + "jvm":{ + "heapSize":"1024", + "javaVersion":"openjdk21_jre" + }, + "openBrowser":true, + "scripts" : { + "onServerInstall" : "cfpm install zip" + } +} \ No newline at end of file diff --git a/server-boxlang-cfml@1.json b/server-boxlang-cfml@1.json new file mode 100644 index 0000000..0c5c129 --- /dev/null +++ b/server-boxlang-cfml@1.json @@ -0,0 +1,28 @@ +{ + "app":{ + "cfengine":"boxlang@^1", + "serverHomeDirectory":".engine/boxlangCFML1" + }, + "name":"swagger-sdk-boxlang-cfml@1", + "force":true, + "openBrowser":false, + "web":{ + "directoryBrowsing":true, + "http":{ + "port":"60299" + }, + "rewrites":{ + "enable":"true" + }, + "webroot":"test-harness", + "aliases":{ + "/moduleroot/swagger-sdk":"./" + } + }, + "JVM":{ + "javaVersion":"openjdk21_jdk_x64" + }, + "scripts":{ + "onServerInitialInstall":"install bx-compat-cfml@be,bx-esapi,bx-unsafe-evaluate,bx-yaml --noSave" + } +} \ No newline at end of file diff --git a/server-boxlang-cfml@be.json b/server-boxlang-cfml@be.json new file mode 100644 index 0000000..5ad2686 --- /dev/null +++ b/server-boxlang-cfml@be.json @@ -0,0 +1,28 @@ +{ + "app":{ + "cfengine":"boxlang@be", + "serverHomeDirectory":".engine/boxlangCFMLBE" + }, + "name":"swagger-sdk-boxlang-cfml@be", + "force":true, + "openBrowser":false, + "web":{ + "directoryBrowsing":true, + "http":{ + "port":"60299" + }, + "rewrites":{ + "enable":"true" + }, + "webroot":"test-harness", + "aliases":{ + "/moduleroot/swagger-sdk":"./" + } + }, + "JVM":{ + "javaVersion":"openjdk21_jdk_x64" + }, + "scripts":{ + "onServerInitialInstall":"install bx-compat-cfml@be,bx-esapi,bx-unsafe-evaluate,bx-yaml --noSave" + } +} \ No newline at end of file diff --git a/server-boxlang@1.json b/server-boxlang@1.json index 6943c47..1b5a3f5 100644 --- a/server-boxlang@1.json +++ b/server-boxlang@1.json @@ -1,7 +1,7 @@ { "app":{ - "cfengine":"boxlang@1.0.0-snapshot", - "serverHomeDirectory":".engine/boxlang" + "cfengine":"boxlang@^1", + "serverHomeDirectory":".engine/boxlang1" }, "name":"swagger-sdk-boxlang@1", "force":true, @@ -20,10 +20,9 @@ } }, "JVM":{ - "javaVersion":"openjdk21_jdk_x64", - "args":"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9999 -Dboxlang.debugMode=true" + "javaVersion":"openjdk21_jdk_x64" }, "scripts":{ - "onServerInitialInstall":"install bx-compat-cfml@be,bx-esapi --noSave" + "onServerInitialInstall":"install bx-esapi,bx-unsafe-evaluate,bx-yaml --noSave" } } \ No newline at end of file diff --git a/server-boxlang@be.json b/server-boxlang@be.json new file mode 100644 index 0000000..3e2a28d --- /dev/null +++ b/server-boxlang@be.json @@ -0,0 +1,28 @@ +{ + "app":{ + "cfengine":"boxlang@be", + "serverHomeDirectory":".engine/boxlangBE" + }, + "name":"swagger-sdk-boxlang@be", + "force":true, + "openBrowser":false, + "web":{ + "directoryBrowsing":true, + "http":{ + "port":"60299" + }, + "rewrites":{ + "enable":"true" + }, + "webroot":"test-harness", + "aliases":{ + "/moduleroot/swagger-sdk":"./" + } + }, + "JVM":{ + "javaVersion":"openjdk21_jdk_x64" + }, + "scripts":{ + "onServerInitialInstall":"install bx-esapi,bx-unsafe-evaluate,bx-yaml --noSave" + } +} \ No newline at end of file diff --git a/test-harness/server-lucee@5.json b/server-lucee@5.json similarity index 92% rename from test-harness/server-lucee@5.json rename to server-lucee@5.json index 8342e4a..0a45909 100644 --- a/test-harness/server-lucee@5.json +++ b/server-lucee@5.json @@ -11,6 +11,7 @@ "rewrites":{ "enable":"true" }, + "webroot":"test-harness", "aliases":{ "/moduleroot/swagger-sdk":"../" } diff --git a/test-harness/server-lucee@6.json b/server-lucee@6.json similarity index 80% rename from test-harness/server-lucee@6.json rename to server-lucee@6.json index 4976372..0993f37 100644 --- a/test-harness/server-lucee@6.json +++ b/server-lucee@6.json @@ -1,7 +1,7 @@ { "name":"swagger-sdk-lucee@6", "app":{ - "serverHomeDirectory":".engine/lucee5", + "serverHomeDirectory":".engine/lucee6", "cfengine":"lucee@6" }, "web":{ @@ -11,6 +11,7 @@ "rewrites":{ "enable":"true" }, + "webroot":"test-harness", "aliases":{ "/moduleroot/swagger-sdk":"../" } diff --git a/server-lucee@be.json b/server-lucee@be.json new file mode 100644 index 0000000..c0ae7d5 --- /dev/null +++ b/server-lucee@be.json @@ -0,0 +1,20 @@ +{ + "name":"swagger-sdk-lucee@be", + "app":{ + "serverHomeDirectory":".engine/luceeBE", + "cfengine":"lucee@6" + }, + "web":{ + "http":{ + "port":"60299" + }, + "rewrites":{ + "enable":"true" + }, + "webroot":"test-harness", + "aliases":{ + "/moduleroot/swagger-sdk":"../" + } + }, + "openBrowser":"false" +} \ No newline at end of file diff --git a/test-harness/box.json b/test-harness/box.json index 5ee690d..d155848 100644 --- a/test-harness/box.json +++ b/test-harness/box.json @@ -19,9 +19,5 @@ "testbox":{ "runner":"http://localhost:60299/tests/runner.cfm" }, - "scripts":{ - "cfpm":"echo '\".engine/adobe2021/WEB-INF/cfusion/bin/cfpm.sh\"' | run", - "cfpm:install":"echo '\".engine/adobe2021/WEB-INF/cfusion/bin/cfpm.sh\" install ${1}' | run", - "install:2021":"run-script cfpm:install zip" - } + "scripts":{} } \ No newline at end of file diff --git a/test-harness/tests/specs/BaseOpenAPISpec.cfc b/test-harness/tests/resources/BaseOpenAPISpec.cfc similarity index 72% rename from test-harness/tests/specs/BaseOpenAPISpec.cfc rename to test-harness/tests/resources/BaseOpenAPISpec.cfc index 634afd1..c8345d2 100644 --- a/test-harness/tests/specs/BaseOpenAPISpec.cfc +++ b/test-harness/tests/resources/BaseOpenAPISpec.cfc @@ -5,7 +5,7 @@ component extends="coldbox.system.testing.BaseTestCase" appmapping="/root" { property name="TestJSONFile"; property name="TestYAMLFile"; - this.loadColdbox = true; + this.loadColdbox = true; this.unloadColdBox = false; public function beforeAll(){ @@ -19,35 +19,25 @@ component extends="coldbox.system.testing.BaseTestCase" appmapping="/root" { "The test JSON API directory does not exist. Could not continue." ); - expect( - fileExists( - TestJSONAPIDirectory & "/" & listLast( TestJSONAPIDirectory, "/\" ) & ".json" - ) - ).toBeTrue( + expect( fileExists( TestJSONAPIDirectory & "/" & listLast( TestJSONAPIDirectory, "/\" ) & ".json" ) ).toBeTrue( "A JSON API file named #listLast( TestJSONAPIDirectory, "/\" ) & ".json"# does not exist in the #TestJSONAPIDirectory# directory. Could not continue." ); - VARIABLES.testJSONFile = TestJSONAPIDirectory & "/" & listLast( - TestJSONAPIDirectory, - "/\" - ) & ".json"; + VARIABLES.testJSONFile = TestJSONAPIDirectory & "/" & listLast( TestJSONAPIDirectory, "/\" ) & ".json"; - expect( - fileExists( - testYAMLAPIDirectory & "/" & listLast( testYAMLAPIDirectory, "/\" ) & ".yaml" - ) - ).toBeTrue( + expect( fileExists( testYAMLAPIDirectory & "/" & listLast( testYAMLAPIDirectory, "/\" ) & ".yaml" ) ).toBeTrue( "A YML API file named #listLast( testYAMLAPIDirectory, "/\" ) & ".yaml"# does not exist in the #testYAMLAPIDirectory# directory. Could not continue." ); - VARIABLES.testYAMLFile = testYAMLAPIDirectory & "/" & listLast( - TestYAMLAPIDirectory, - "/\" - ) & ".yaml"; + VARIABLES.testYAMLFile = testYAMLAPIDirectory & "/" & listLast( TestYAMLAPIDirectory, "/\" ) & ".yaml"; } public function afterAll(){ super.afterAll(); } + function run(){ + throw( "Must be implemented in a concrete spec" ); + } + } diff --git a/test-harness/tests/resources/petstore/petstore.yaml b/test-harness/tests/resources/petstore/petstore.yaml index 731c8f1..2b96b52 100644 --- a/test-harness/tests/resources/petstore/petstore.yaml +++ b/test-harness/tests/resources/petstore/petstore.yaml @@ -16,6 +16,7 @@ servers: paths: /pets: get: + summary: List all pets description: | Returns all pets from the system that the user has access to Nam sed condimentum est. Maecenas tempor sagittis sapien, nec rhoncus sem sagittis sit amet. Aenean at gravida augue, ac iaculis sem. Curabitur odio lorem, ornare eget elementum nec, cursus id lectus. Duis mi turpis, pulvinar ac eros ac, tincidunt varius justo. In hac habitasse platea dictumst. Integer at adipiscing ante, a sagittis ligula. Aenean pharetra tempor ante molestie imperdiet. Vivamus id aliquam diam. Cras quis velit non tortor eleifend sagittis. Praesent at enim pharetra urna volutpat venenatis eget eget mauris. In eleifend fermentum facilisis. Praesent enim enim, gravida ac sodales sed, placerat id erat. Suspendisse lacus dolor, consectetur non augue vel, vehicula interdum libero. Morbi euismod sagittis libero sed lacinia. @@ -55,6 +56,7 @@ paths: schema: $ref: "#/components/schemas/Error" post: + summary: Create a pet description: Creates a new pet in the store. Duplicates are allowed operationId: addPet requestBody: @@ -79,6 +81,8 @@ paths: $ref: "#/components/schemas/Error" /pet/{petId}: get: + summary: Find pet by ID + description: Returns a user based on a single ID, if the user does not have access to the pet operationId: find pet by id parameters: @@ -102,7 +106,39 @@ paths: application/json: schema: $ref: "#/components/schemas/Error" + post: + tags: + - pet + summary: Updates a pet in the store with form data + + operationId: updatePetWithForm + parameters: + - name: petId + in: path + description: ID of pet that needs to be updated + required: true + schema: + type: integer + format: int64 + - name: name + in: query + description: Name of pet that needs to be updated + schema: + type: string + - name: status + in: query + description: Status of pet that needs to be updated + schema: + type: string + responses: + "405": + description: Invalid Input" + security: + - petstore_auth: + - write:pets + - read:pets delete: + summary: Deletes a pet description: deletes a single pet based on the ID supplied operationId: deletePet parameters: diff --git a/test-harness/tests/specs/ColdboxSpec.cfc b/test-harness/tests/specs/ColdboxSpec.cfc index 891d7dd..da136c1 100644 --- a/test-harness/tests/specs/ColdboxSpec.cfc +++ b/test-harness/tests/specs/ColdboxSpec.cfc @@ -1,107 +1,116 @@ /** -* My BDD Test -*/ -component extends="BaseOpenAPISpec"{ + * My BDD Test + */ +component extends="tests.resources.BaseOpenAPISpec" { - public function beforeAll(){ - super.beforeAll(); + public function beforeAll(){ + super.beforeAll(); - variables.testJSONAPIDIrectory = expandPath( "/tests/resources/coldboxRest" ); + variables.testJSONAPIDIrectory = expandPath( "/tests/resources/coldboxRest" ); - expect( directoryExists( testJSONAPIDIrectory ) ).toBeTrue( - "The test JSON API directory does not exist. Could not continue." - ); + expect( directoryExists( testJSONAPIDIrectory ) ).toBeTrue( + "The test JSON API directory does not exist. Could not continue." + ); - expect( - fileExists( - testJSONAPIDIrectory & "/" & listLast( testJSONAPIDIrectory, "/\" ) & ".json" - ) - ).toBeTrue( - "A JSON API file named #listLast( testJSONAPIDIrectory, "/\" ) & ".json"# does not exist in the #testJSONAPIDIrectory# directory. Could not continue." - ); + expect( fileExists( testJSONAPIDIrectory & "/" & listLast( testJSONAPIDIrectory, "/\" ) & ".json" ) ).toBeTrue( + "A JSON API file named #listLast( testJSONAPIDIrectory, "/\" ) & ".json"# does not exist in the #testJSONAPIDIrectory# directory. Could not continue." + ); - VARIABLES.testJSONFile = testJSONAPIDIrectory & "/" & listLast( - testJSONAPIDIrectory, - "/\" - ) & ".json"; - } + VARIABLES.testJSONFile = testJSONAPIDIrectory & "/" & listLast( testJSONAPIDIrectory, "/\" ) & ".json"; + } - struct function parseApiDoc() { - var parser = getInstance( "OpenAPIParser@SwaggerSDK" ).init( VARIABLES.TestJSONFile ); - var parserDoc = parser.getDocumentObject(); - return parserDoc.getNormalizedDocument(); - } + struct function parseApiDoc(){ + var parser = getInstance( "OpenAPIParser@SwaggerSDK" ).init( VARIABLES.TestJSONFile ); + var parserDoc = parser.getDocumentObject(); + return parserDoc.getNormalizedDocument(); + } -/*********************************** BDD SUITES ***********************************/ + /*********************************** BDD SUITES ***********************************/ function run(){ // all your suites go here. - describe( "Performs and tests common Coldbox Restful app functionality" ,function(){ - - beforeEach(function( currentSpec ){ + describe( "Performs and tests common Coldbox Restful app functionality", function(){ + beforeEach( function( currentSpec ){ setup(); - }); + } ); it( "Can parse the apiDoc", function(){ var apiDoc = parseApiDoc(); - // it can have multiple servers - expect( apiDoc ).toHaveKey( "servers" ); - expect( apiDoc.servers ).toBeArray(); - expect( apiDoc.servers.len() ).toBe( 2 ); - - // it has multiple paths produced by $extend - expect( apiDoc ).toHaveKey( "paths" ); - expect( apiDoc.paths ).toHaveKey( "/users" ); - expect( apiDoc.paths ).toHaveKey( "/posts" ); - - // schema: expectations - expect( apiDoc.components ).toHaveKey( "schemas" ); - expect( apiDoc.components.schemas ).toHaveKey( "Pagination" ); - expect( apiDoc.components.schemas ).toHaveKey( "User" ); - expect( apiDoc.components.schemas ).toHaveKey( "Post" ); - expect( apiDoc.components.schemas ).toHaveKey( "Media" ); - - // schema inherited objects via `allOf` - var childObjects = [ "BookMedia", "MusicMedia" ]; - - for ( var item in ChildObjects ) { - expect( apiDoc.components.schemas ).toHaveKey( item ); - expect( apiDoc.components.schemas[ item ] ).toHaveKey( "allOf" ); - expect( apiDoc.components.schemas[ item ].allOf ).toBeArray(); - expect( apiDoc.components.schemas[ item ].allOf[ 1 ] ).toBeStruct(); - expect( apiDoc.components.schemas[ item ].allOf[ 1 ] ).toHaveKey( "$ref" ); - expect( apiDoc.components.schemas[ item ].allOf[ 1 ][ "$ref" ] ).toBe( "##/components/schemas/Media" ); - } - - // users.index intentionally doesn't use components/schema. Check for existence of $ref object - expect( apiDoc.paths[ "/users" ] ).toHaveKey( "get" ); - expect( apiDoc.paths[ "/users" ].get ).toHaveKey( "responses" ); - expect( apiDoc.paths[ "/users" ].get.responses ).toHaveKey( "200" ); - expect( apiDoc.paths[ "/users" ].get.responses[ "200" ] ).toHaveKey( "content" ); - expect( apiDoc.paths[ "/users" ].get.responses[ "200" ].content ).toHaveKey( "application/json" ); - expect( apiDoc.paths[ "/users" ].get.responses[ "200" ].content[ "application/json" ] ).toHaveKey( "schema" ); - expect( apiDoc.paths[ "/users" ].get.responses[ "200" ].content[ "application/json" ].schema ).toHaveKey( "properties" ); - expect( apiDoc.paths[ "/users" ].get.responses[ "200" ].content[ "application/json" ].schema.properties ).toHaveKey( "data" ); - expect( apiDoc.paths[ "/users" ].get.responses[ "200" ].content[ "application/json" ].schema.properties.data ).toHaveKey( "properties" ); - expect( apiDoc.paths[ "/users" ].get.responses[ "200" ].content[ "application/json" ].schema.properties.data.properties ).toHaveKey( "results" ); - expect( apiDoc.paths[ "/users" ].get.responses[ "200" ].content[ "application/json" ].schema.properties.data.properties ).toHaveKey( "pagination" ); - expect( apiDoc.paths[ "/users" ].get.responses[ "200" ].content[ "application/json" ].schema.properties.data.properties.results ).toHaveKey( "items" ); - expect( apiDoc.paths[ "/users" ].get.responses[ "200" ].content[ "application/json" ].schema.properties.data.properties.results.items ).toHaveKey( "properties" ); - - var expectedKeys = [ "id", "firstName", "lastName" ]; - - for ( var item in expectedKeys ) { - expect( apiDoc.paths[ "/users" ].get.responses[ "200" ].content[ "application/json" ].schema.properties.data.properties.results.items.properties ).toHaveKey( item ); - } - - // expect the requestBody reference to have one pound sign - expect( apiDoc.paths[ "/posts" ].post.requestBody ).toHaveKey( "$ref" ); - expect( left( apiDoc.paths[ "/posts" ].post.requestBody[ '$ref' ], 2 ) ).toBe( "#chr( 35 )#/" ); - - }); - - }); + // it can have multiple servers + expect( apiDoc ).toHaveKey( "servers" ); + expect( apiDoc.servers ).toBeArray(); + expect( apiDoc.servers.len() ).toBe( 2 ); + + // it has multiple paths produced by $extend + expect( apiDoc ).toHaveKey( "paths" ); + expect( apiDoc.paths ).toHaveKey( "/users" ); + expect( apiDoc.paths ).toHaveKey( "/posts" ); + + // schema: expectations + expect( apiDoc.components ).toHaveKey( "schemas" ); + expect( apiDoc.components.schemas ).toHaveKey( "Pagination" ); + expect( apiDoc.components.schemas ).toHaveKey( "User" ); + expect( apiDoc.components.schemas ).toHaveKey( "Post" ); + expect( apiDoc.components.schemas ).toHaveKey( "Media" ); + + // schema inherited objects via `allOf` + var childObjects = [ "BookMedia", "MusicMedia" ]; + + for ( var item in ChildObjects ) { + expect( apiDoc.components.schemas ).toHaveKey( item ); + expect( apiDoc.components.schemas[ item ] ).toHaveKey( "allOf" ); + expect( apiDoc.components.schemas[ item ].allOf ).toBeArray(); + expect( apiDoc.components.schemas[ item ].allOf[ 1 ] ).toBeStruct(); + expect( apiDoc.components.schemas[ item ].allOf[ 1 ] ).toHaveKey( "$ref" ); + expect( apiDoc.components.schemas[ item ].allOf[ 1 ][ "$ref" ] ).toBe( "##/components/schemas/Media" ); + } + + // users.index intentionally doesn't use components/schema. Check for existence of $ref object + expect( apiDoc.paths[ "/users" ] ).toHaveKey( "get" ); + expect( apiDoc.paths[ "/users" ].get ).toHaveKey( "responses" ); + expect( apiDoc.paths[ "/users" ].get.responses ).toHaveKey( "200" ); + expect( apiDoc.paths[ "/users" ].get.responses[ "200" ] ).toHaveKey( "content" ); + expect( apiDoc.paths[ "/users" ].get.responses[ "200" ].content ).toHaveKey( "application/json" ); + expect( apiDoc.paths[ "/users" ].get.responses[ "200" ].content[ "application/json" ] ).toHaveKey( "schema" ); + expect( apiDoc.paths[ "/users" ].get.responses[ "200" ].content[ "application/json" ].schema ).toHaveKey( "properties" ); + expect( + apiDoc.paths[ "/users" ].get.responses[ "200" ].content[ "application/json" ].schema.properties + ).toHaveKey( "data" ); + expect( + apiDoc.paths[ "/users" ].get.responses[ "200" ].content[ "application/json" ].schema.properties.data + ).toHaveKey( "properties" ); + expect( + apiDoc.paths[ "/users" ].get.responses[ "200" ].content[ "application/json" ].schema.properties.data.properties + ).toHaveKey( "results" ); + expect( + apiDoc.paths[ "/users" ].get.responses[ "200" ].content[ "application/json" ].schema.properties.data.properties + ).toHaveKey( "pagination" ); + expect( + apiDoc.paths[ "/users" ].get.responses[ "200" ].content[ "application/json" ].schema.properties.data.properties.results + ).toHaveKey( "items" ); + expect( + apiDoc.paths[ "/users" ].get.responses[ "200" ].content[ "application/json" ].schema.properties.data.properties.results.items + ).toHaveKey( "properties" ); + + var expectedKeys = [ "id", "firstName", "lastName" ]; + + for ( var item in expectedKeys ) { + expect( + apiDoc.paths[ "/users" ].get.responses[ "200" ].content[ "application/json" ].schema.properties.data.properties.results.items.properties + ).toHaveKey( item ); + } + + // expect the requestBody reference to have one pound sign + expect( apiDoc.paths[ "/posts" ].post.requestBody ).toHaveKey( "$ref" ); + expect( + left( + apiDoc.paths[ "/posts" ].post.requestBody[ "$ref" ], + 2 + ) + ).toBe( "#chr( 35 )#/" ); + } ); + } ); } } diff --git a/test-harness/tests/specs/DocumentSpec.cfc b/test-harness/tests/specs/DocumentSpec.cfc index 753e1d3..cd4a614 100644 --- a/test-harness/tests/specs/DocumentSpec.cfc +++ b/test-harness/tests/specs/DocumentSpec.cfc @@ -1,57 +1,52 @@ /** -* My BDD Test -*/ -component extends="BaseOpenAPISpec"{ + * My BDD Test + */ +component extends="tests.resources.BaseOpenAPISpec" { -/*********************************** LIFE CYCLE Methods ***********************************/ + /*********************************** LIFE CYCLE Methods ***********************************/ function beforeAll(){ super.beforeAll(); VARIABLES.testDocument = deserializeJSON( fileRead( VARIABLES.TestJSONFile ) ); - }; -/*********************************** BDD SUITES ***********************************/ + /*********************************** BDD SUITES ***********************************/ function run(){ - describe( "Performs tests on document instantiation", function(){ - - - beforeEach(function( currentSpec ){ + beforeEach( function( currentSpec ){ setup(); - }); + } ); - it( "Tests the ability to instantiate an OpenAPI Document Object", function( ){ + it( "Tests the ability to instantiate an OpenAPI Document Object", function(){ var DocumentObject = getInstance( "OpenAPIDocument@SwaggerSDK" ).init( VARIABLES.testDocument ); - expect( DocumentObject ) - .toBeComponent() - .toHaveKey( "getDocument" ); + expect( DocumentObject ).toBeComponent().toHaveKey( "getDocument" ); // test that path items have resource IDs var instanceDoc = DocumentObject.getNormalizedDocument(); - expect( instanceDoc ).toHaveKey( "openapi" ) - .toHaveKey( "info" ) - .toHaveKey( "paths" ) - .toHaveKey( "servers" ) - .toHaveKey( "tags" ); + expect( instanceDoc ) + .toHaveKey( "openapi" ) + .toHaveKey( "info" ) + .toHaveKey( "paths" ) + .toHaveKey( "servers" ) + .toHaveKey( "tags" ); } ); it( "can be coverted to json", function(){ var doc = getInstance( "OpenAPIDocument@SwaggerSDK" ).init( VARIABLES.testDocument ); expect( doc.asJson() ).toBeJSON(); - }); + } ); it( "can be coverted to struct", function(){ var doc = getInstance( "OpenAPIDocument@SwaggerSDK" ).init( VARIABLES.testDocument ); expect( doc.asStruct() ).toBeStruct(); - }); + } ); it( "can be coverted to yaml", function(){ - var doc = getInstance( "OpenAPIDocument@SwaggerSDK" ).init( VARIABLES.testDocument ); + var doc = getInstance( "OpenAPIDocument@SwaggerSDK" ).init( VARIABLES.testDocument ); var outYaml = expandPath( "/tests/resources/petstore/test.yaml" ); fileWrite( outYaml, doc.asYaml() ); @@ -60,26 +55,20 @@ component extends="BaseOpenAPISpec"{ var outDoc = getInstance( "OpenAPIParser@SwaggerSDK" ).init( outYaml ); // If we got here, it parsed correctly - - }); - + } ); } ); describe( "Core functionality tests", function(){ - it( "Tests that an attempt to locate an invalid path with return a $ref object", function(){ var DocumentObject = getInstance( "OpenAPIDocument@SwaggerSDK" ).init( VARIABLES.testDocument ); - expect( DocumentObject ) - .toBeComponent() - .toHaveKey( "getDocument" ); + expect( DocumentObject ).toBeComponent().toHaveKey( "getDocument" ); var invalidPath = DocumentObject.locate( "foo.bar" ); expect( invalidPath ).toBeStruct().toHaveKey( "$ref" ); expect( invalidPath[ "$ref" ] ).toBe( "##/foo/bar" ); - - }) - }) + } ) + } ) } } diff --git a/test-harness/tests/specs/ParserSpec.cfc b/test-harness/tests/specs/ParserSpec.cfc index fc5c8a1..e83ba3c 100644 --- a/test-harness/tests/specs/ParserSpec.cfc +++ b/test-harness/tests/specs/ParserSpec.cfc @@ -1,112 +1,92 @@ -/** -* My BDD Test -*/ -component extends="BaseOpenAPISpec"{ - - -/*********************************** BDD SUITES ***********************************/ +component extends="tests.resources.BaseOpenAPISpec" { function run(){ - // all your suites go here. - describe( "Performs and tests general OpenAPIParser operations" ,function(){ - - beforeEach(function( currentSpec ){ + describe( "Performs and tests general OpenAPIParser operations", function(){ + beforeEach( function(){ setup(); - }); + } ); it( "Tests the ability instantiate the parser using a JSON file", function(){ var JSONParser = getInstance( "OpenAPIParser@SwaggerSDK" ).init( VARIABLES.TestJSONFile ); runParserTypeChecks( JSONParser ); - - describe( "Performs recursion checks on parsed JSON document", function(){ - runParserRecursionTests( JSONParser, true ); - }); - - describe( "Performs cross-conversion tests on the the parsed JSON document",function(){ - runParserConversionTests( JSONParser ); - }); - - }); + runParserRecursionTests( JSONParser, true ); + } ); it( "Tests the ability instantiate the parser using a YAML file", function(){ var YAMLParser = getInstance( "OpenAPIParser@SwaggerSDK" ).init( VARIABLES.TestYAMLFile ); runParserTypeChecks( YAMLParser ); - - describe( "Performs recursion checks on parsed YAML document", function(){ - runParserRecursionTests( YAMLParser ); - }); - - }); - - }); + runParserRecursionTests( YAMLParser ); + } ); + } ); } function runParserTypeChecks( required Parser ){ - - // Note: We can't the type tests because ACF and Lucee don't read the metadata the same way + // Note: We can"t the type tests because ACF and Lucee don"t read the metadata the same way expect( ARGUMENTS.Parser ).toBeInstanceOf( "Parser" ); expect( ARGUMENTS.Parser ).toHaveKey( "getDocumentObject" ); - //expect( ARGUMENTS.Parser.getDocumentObject() ).toBeInstanceOf( "SwaggerSDK.models.OpenAPI.Document" ); expect( ARGUMENTS.Parser ).toHaveKey( "getSchemaType" ); expect( ARGUMENTS.Parser.getSchemaType() ).toBeString(); expect( ARGUMENTS.Parser ).toHaveKey( "getBaseDocumentPath" ); expect( ARGUMENTS.Parser.getBaseDocumentPath() ).toBeString(); - } - function runParserRecursionTests( required Parser, required boolean testObjects=false ){ - if( ARGUMENTS.testObjects ){ - - it( "Tests for the recursive presence of structs within Parser #Parser.getSchemaType()# document object" , function(){ - var ParserDoc = Parser.getDocumentObject(); - expect( ParserDoc ).toBeInstanceOf( "Document" ); - expect( ParserDoc ).toHaveKey( "getDocument" ); - var APIDoc = ParserDoc.getDocument(); - expect( APIDoc ).toBeStruct(); - expect( APIDoc ).toHaveKey( "paths" ); - expect( APIDoc.paths ).toBeStruct(); - expect( APIDoc.paths ).toHaveKey( "/pets" ); - }); - + function runParserRecursionTests( + required Parser, + required boolean testObjects = false + ){ + if ( arguments.testObjects ) { + var ParserDoc = arguments.Parser.getDocumentObject(); + expect( ParserDoc ).toBeInstanceOf( "Document" ); + expect( ParserDoc ).toHaveKey( "getDocument" ); + var APIDoc = ParserDoc.getDocument(); + expect( APIDoc ).toBeStruct(); + expect( APIDoc ).toHaveKey( "paths" ); + expect( APIDoc.paths ).toBeStruct(); + expect( APIDoc.paths ).toHaveKey( "/pets" ); } - it( "Tests the ability to fully normalize the parsed #Parser.getSchemaType()# document" ,function( ){ - var NormalizedDocument = Parser.getNormalizedDocument(); - - expect( NormalizedDocument ).toBeStruct(); - expect( NormalizedDocument ).toHaveKey( "openapi" ); - expect( NormalizedDocument ).toHaveKey( "servers" ); - expect( NormalizedDocument ).toHaveKey( "info" ); - - if(Parser.getSchemaType() eq "YAML") - expect( NormalizedDocument ).toHaveKey( "components" ); - - expect( NormalizedDocument ).toHaveKey( "paths" ); - - expect( NormalizedDocument ).toHaveDeepKey( "/pets" ); - expect( NormalizedDocument.paths[ '/pets' ] ).toBeStruct(); - expect( NormalizedDocument.paths[ '/pets' ] ).toHaveDeepKey( "description" ); - expect( NormalizedDocument.paths[ '/pets' ] ).toHaveDeepKey( "parameters" ); - expect( NormalizedDocument.paths[ '/pets' ] ).toHaveDeepKey( "responses" ); + var NormalizedDocument = arguments.Parser.getNormalizedDocument(); - expect( NormalizedDocument ).toHaveDeepKey( "/pet/{petId}" ); - expect( NormalizedDocument.paths[ '/pet/{petId}' ] ).toBeStruct(); - expect( NormalizedDocument.paths[ '/pet/{petId}' ] ).toHaveDeepKey( "description" ); - expect( NormalizedDocument.paths[ '/pet/{petId}' ] ).toHaveDeepKey( "parameters" ); - expect( NormalizedDocument.paths[ '/pet/{petId}' ] ).toHaveDeepKey( "responses" ); + expect( NormalizedDocument ).toBeStruct(); + expect( NormalizedDocument ).toHaveKey( "openapi" ); + expect( NormalizedDocument ).toHaveKey( "servers" ); + expect( NormalizedDocument ).toHaveKey( "info" ); - expect( arrayLen( structFindKey( NormalizedDocument, "$ref" ) ) ).toBe( 0 ); - expect( arrayLen( structFindKey( NormalizedDocument, "$extend" ) ) ).toBe( 0 ); - - }); - - } - - function runParserConversionTests(required Parser){ - it( "Tests the parsers ability to perform cross-MIME type conversions on the parsed #Parser.getSchemaType()# document.",function(){ + if ( arguments.Parser.getSchemaType() == "YAML" ) { + expect( NormalizedDocument ).toHaveKey( "components" ); + } - }); + expect( NormalizedDocument ).toHaveKey( "paths" ); + + expect( NormalizedDocument.paths ).toHaveKey( "/pets" ); + expect( NormalizedDocument.paths[ "/pets" ] ).toBeStruct(); + expect( NormalizedDocument.paths[ "/pets" ] ).toHaveKey( "get" ); + expect( NormalizedDocument.paths[ "/pets" ][ "get" ] ).toHaveKey( "summary" ); + expect( NormalizedDocument.paths[ "/pets" ][ "get" ] ).toHaveKey( "parameters" ); + expect( NormalizedDocument.paths[ "/pets" ][ "get" ] ).toHaveKey( "responses" ); + expect( NormalizedDocument.paths[ "/pets" ] ).toHaveKey( "post" ); + expect( NormalizedDocument.paths[ "/pets" ][ "post" ] ).toHaveKey( "summary" ); + expect( NormalizedDocument.paths[ "/pets" ][ "post" ] ).toHaveKey( "requestBody" ); + expect( NormalizedDocument.paths[ "/pets" ][ "post" ] ).toHaveKey( "responses" ); + + expect( NormalizedDocument.paths ).toHaveKey( "/pet/{petId}" ); + expect( NormalizedDocument.paths[ "/pet/{petId}" ] ).toBeStruct(); + expect( NormalizedDocument.paths[ "/pet/{petId}" ] ).toHaveKey( "get" ); + expect( NormalizedDocument.paths[ "/pet/{petId}" ][ "get" ] ).toHaveKey( "summary" ); + expect( NormalizedDocument.paths[ "/pet/{petId}" ][ "get" ] ).toHaveKey( "parameters" ); + expect( NormalizedDocument.paths[ "/pet/{petId}" ][ "get" ] ).toHaveKey( "responses" ); + expect( NormalizedDocument.paths[ "/pet/{petId}" ] ).toHaveKey( "post" ); + expect( NormalizedDocument.paths[ "/pet/{petId}" ][ "post" ] ).toHaveKey( "summary" ); + expect( NormalizedDocument.paths[ "/pet/{petId}" ][ "post" ] ).toHaveKey( "parameters" ); + expect( NormalizedDocument.paths[ "/pet/{petId}" ][ "post" ] ).toHaveKey( "responses" ); + expect( NormalizedDocument.paths[ "/pet/{petId}" ] ).toHaveKey( "delete" ); + expect( NormalizedDocument.paths[ "/pet/{petId}" ][ "delete" ] ).toHaveKey( "summary" ); + expect( NormalizedDocument.paths[ "/pet/{petId}" ][ "delete" ] ).toHaveKey( "parameters" ); + expect( NormalizedDocument.paths[ "/pet/{petId}" ][ "delete" ] ).toHaveKey( "responses" ); + + expect( arrayLen( structFindKey( NormalizedDocument, "$ref" ) ) ).toBe( 0 ); + expect( arrayLen( structFindKey( NormalizedDocument, "$extend" ) ) ).toBe( 0 ); } } diff --git a/test-harness/tests/specs/UtilitySpec.cfc b/test-harness/tests/specs/UtilitySpec.cfc deleted file mode 100644 index 5f55098..0000000 --- a/test-harness/tests/specs/UtilitySpec.cfc +++ /dev/null @@ -1,15 +0,0 @@ -/** -* My BDD Test -*/ -component extends="BaseOpenAPISpec"{ - -/*********************************** LIFE CYCLE Methods ***********************************/ - - -/*********************************** BDD SUITES ***********************************/ - - function run(){ - // all your suites go here. - } - -}