diff --git a/.changes/next-release/feature-31e86dfd28fac45a68ff1389fe531b2416b0f660.json b/.changes/next-release/feature-31e86dfd28fac45a68ff1389fe531b2416b0f660.json new file mode 100644 index 00000000000..05b664b091d --- /dev/null +++ b/.changes/next-release/feature-31e86dfd28fac45a68ff1389fe531b2416b0f660.json @@ -0,0 +1,7 @@ +{ + "type": "feature", + "description": "Update smithy-rules-engine-tests with new std lib functions and bdd-based tests", + "pull_requests": [ + "[#2945](https://github.com/smithy-lang/smithy/pull/2945)" + ] +} diff --git a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/coalesce.smithy b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/coalesce.smithy new file mode 100644 index 00000000000..fd649d9465b --- /dev/null +++ b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/coalesce.smithy @@ -0,0 +1,167 @@ +$version: "2.0" + +namespace smithy.rules.tests + +use smithy.rules#clientContextParams +use smithy.rules#endpointRuleSet +use smithy.rules#endpointTests + +@suppress(["UnstableTrait", "RuleSetParameter.TestCase.Unused"]) +@clientContextParams( + TestCaseId: { type: "string", required: true, documentation: "Test case id used to select the test case to use" } + req1: { type: "string", documentation: "docs" } + req2: { type: "string", documentation: "docs" } + opt1: { type: "string", documentation: "always Some" } + opt2: { type: "string", documentation: "always Some" } +) +@endpointRuleSet({ + version: "1.1" + parameters: { + TestCaseId: { type: "string", required: true, documentation: "Test case id used to select the test case to use" } + req1: { type: "string", documentation: "req1", required: true, default: "req1Value" } + req2: { type: "string", documentation: "req2", required: true, default: "req2Value" } + opt1: { type: "string", documentation: "opt1" } + opt2: { type: "string", documentation: "opt2" } + } + rules: [ + { + documentation: "Two required" + conditions: [ + { + fn: "stringEquals" + argv: ["{TestCaseId}", "0"] + } + { + fn: "coalesce" + argv: [ + { + ref: "req1" + } + { + ref: "req2" + } + ] + assign: "req1req2" + } + ] + error: "The value is: {req1req2}" + type: "error" + } + { + documentation: "Two optional" + conditions: [ + { + fn: "stringEquals" + argv: ["{TestCaseId}", "1"] + } + { + fn: "coalesce" + argv: [ + { + ref: "opt1" + } + { + ref: "opt2" + } + ] + assign: "opt1opt2" + } + ] + error: "The value is: {opt1opt2}" + type: "error" + } + { + documentation: "Required then Optional" + conditions: [ + { + fn: "stringEquals" + argv: ["{TestCaseId}", "2"] + } + { + fn: "coalesce" + argv: [ + { + ref: "req1" + } + { + ref: "opt1" + } + ] + assign: "req1opt1" + } + ] + error: "The value is: {req1opt1}" + type: "error" + } + { + documentation: "Optional then Required" + conditions: [ + { + fn: "stringEquals" + argv: ["{TestCaseId}", "3"] + } + { + fn: "coalesce" + argv: [ + { + ref: "opt1" + } + { + ref: "req1" + } + ] + assign: "opt1req1" + } + ] + error: "The value is: {opt1req1}" + type: "error" + } + { + conditions: [] + documentation: "error fallthrough" + error: "endpoint error" + type: "error" + } + ] +}) +@endpointTests({ + version: "1.0" + testCases: [ + { + documentation: "Two required, first val returned" + params: { TestCaseId: "0" } + expect: { error: "The value is: req1Value" } + } + { + documentation: "Two optional, Some(opt1Value), Some(opt2Value), opt1Value returned" + params: { TestCaseId: "1", opt1: "opt1Value", opt2: "opt2Value" } + expect: { error: "The value is: opt1Value" } + } + { + documentation: "Two optional, None, Some(opt2Value), opt2Value returned" + params: { TestCaseId: "1", opt2: "opt2Value" } + expect: { error: "The value is: opt2Value" } + } + { + documentation: "Two optional, None, None, None returned" + params: { TestCaseId: "1" } + expect: { error: "endpoint error" } + } + { + documentation: "Required then Optional, required returned" + params: { TestCaseId: "2", opt1: "opt1Value" } + expect: { error: "The value is: req1Value" } + } + { + documentation: "Optional then Required, optional value returned" + params: { TestCaseId: "3", opt1: "opt1Value" } + expect: { error: "The value is: opt1Value" } + } + { + documentation: "Optional then Required, optional is none so required value returned" + params: { TestCaseId: "3" } + expect: { error: "The value is: req1Value" } + } + ] +}) +service CoalesceTest {} diff --git a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/default-values.smithy b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/default-values.smithy index 86235f15937..7f22822cb5d 100644 --- a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/default-values.smithy +++ b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/default-values.smithy @@ -8,98 +8,78 @@ use smithy.rules#endpointTests @suppress(["UnstableTrait"]) @clientContextParams( - bar: {type: "string", documentation: "a client string parameter"} - baz: {type: "string", documentation: "another client string parameter"} + bar: { type: "string", documentation: "a client string parameter" } + baz: { type: "string", documentation: "another client string parameter" } ) @endpointRuleSet({ - version: "1.0", + version: "1.0" parameters: { - bar: { - type: "string", - documentation: "docs" - } - baz: { - type: "string", - documentation: "docs" - required: true - default: "baz" - } - }, + bar: { type: "string", documentation: "docs" } + baz: { type: "string", documentation: "docs", required: true, default: "baz" } + } rules: [ { - "conditions": [ + conditions: [ { - "fn": "isSet", - "argv": [ + fn: "isSet" + argv: [ { - "ref": "bar" + ref: "bar" } ] } - ], - "endpoint": { - "url": "https://example.com/{baz}" - }, - "type": "endpoint" - }, + ] + endpoint: { url: "https://example.com/{baz}" } + type: "endpoint" + } { - "conditions": [], - "documentation": "error fallthrough", - "error": "endpoint error", - "type": "error" + conditions: [] + documentation: "error fallthrough" + error: "endpoint error" + type: "error" } ] }) @endpointTests({ - "version": "1.0", - "testCases": [ + version: "1.0" + testCases: [ { - "documentation": "Default value is used when parameter is unset", - "params": { - "bar": "a b", - } - "operationInputs": [{ - "operationName": "GetThing", - "clientParams": { - "bar": "a b" - } - }], - "expect": { - "endpoint": { - "url": "https://example.com/baz" + documentation: "Default value is used when parameter is unset" + params: { bar: "a b" } + operationInputs: [ + { + operationName: "GetThing" + clientParams: { bar: "a b" } } + ] + expect: { + endpoint: { url: "https://example.com/baz" } } - }, + } { - "documentation": "Default value is not used when the parameter is set", - "params": { - "bar": "a b", - "baz": "BIG" - } - "operationInputs": [{ - "operationName": "GetThing", - "clientParams": { - "bar": "a b", - "baz": "BIG" - } - }], - "expect": { - "endpoint": { - "url": "https://example.com/BIG" + documentation: "Default value is not used when the parameter is set" + params: { bar: "a b", baz: "BIG" } + operationInputs: [ + { + operationName: "GetThing" + clientParams: { bar: "a b", baz: "BIG" } } + ] + expect: { + endpoint: { url: "https://example.com/BIG" } } - }, + } { - "documentation": "a documentation string", - "expect": { - "error": "endpoint error" - } + documentation: "a documentation string" + expect: { error: "endpoint error" } } ] }) service DefaultValuesService { - version: "2022-01-01", - operations: [GetThing] + version: "2022-01-01" + operations: [ + GetThing + ] } operation GetThing { diff --git a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/endpoint-bindings.smithy b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/endpoint-bindings.smithy index 47d7d99c770..fa2f9135566 100644 --- a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/endpoint-bindings.smithy +++ b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/endpoint-bindings.smithy @@ -2,303 +2,240 @@ $version: "2.0" namespace smithy.rules.tests -use smithy.rules#endpointRuleSet -use smithy.rules#endpointTests -use smithy.rules#staticContextParams use smithy.rules#clientContextParams use smithy.rules#contextParam +use smithy.rules#endpointRuleSet +use smithy.rules#endpointTests use smithy.rules#operationContextParams +use smithy.rules#staticContextParams @suppress(["UnstableTrait"]) @clientContextParams( - bar: {type: "string", documentation: "a client string parameter"} - baz: {type: "string", documentation: "another client string parameter"} - booleanParam: {type: "boolean", documentation: "a client boolean parameter"} + bar: { type: "string", documentation: "a client string parameter" } + baz: { type: "string", documentation: "another client string parameter" } + booleanParam: { type: "boolean", documentation: "a client boolean parameter" } ) @endpointRuleSet({ - "version": "1.0", - "parameters": { - "bar": { - "required": false, - "documentation": "String parameter with no default value and client binding", - "type": "String" - }, - "baz": { - "required": true, - "default": "baz", - "documentation": "String parameter with default value and client binding", - "type": "String" - }, - "booleanParam": { - "required": true, - "default": true, - "documentation": "Boolean parameter with default value and client binding", - "type": "Boolean" - }, - "Endpoint": { - "builtIn": "SDK::Endpoint", - "required": false, - "documentation": "Override the endpoint used to send this request", - "type": "String" - } - }, - "rules": [ + version: "1.0" + parameters: { + bar: { required: false, documentation: "String parameter with no default value and client binding", type: "String" } + baz: { required: true, default: "baz", documentation: "String parameter with default value and client binding", type: "String" } + booleanParam: { required: true, default: true, documentation: "Boolean parameter with default value and client binding", type: "Boolean" } + Endpoint: { builtIn: "SDK::Endpoint", required: false, documentation: "Override the endpoint used to send this request", type: "String" } + } + rules: [ { - "conditions": [], - "rules": [ + conditions: [] + rules: [ { - "conditions": [ + conditions: [ { - "fn": "isSet", - "argv": [ + fn: "isSet" + argv: [ { - "ref": "Endpoint" + ref: "Endpoint" } ] } - ], - "endpoint": { - "url": { - "ref": "Endpoint" - }, - "properties": {}, - "headers": {} - }, - "type": "endpoint" - }, + ] + endpoint: { + url: { ref: "Endpoint" } + properties: {} + headers: {} + } + type: "endpoint" + } { - "conditions": [], - "rules": [ + conditions: [] + rules: [ { - "conditions": [ + conditions: [ { - "fn": "booleanEquals", - "argv": [ + fn: "booleanEquals" + argv: [ { - "ref": "booleanParam" - }, + ref: "booleanParam" + } true ] } - ], - "rules": [ + ] + rules: [ { - "conditions": [ + conditions: [ { - "fn": "isSet", - "argv": [ + fn: "isSet" + argv: [ { - "ref": "bar" + ref: "bar" } ] } - ], - "endpoint": { - "url": "https://{bar}.{baz}/set", - "properties": {}, - "headers": {} - }, - "type": "endpoint" - }, + ] + endpoint: { + url: "https://{bar}.{baz}/set" + properties: {} + headers: {} + } + type: "endpoint" + } { - "conditions": [], - "endpoint": { - "url": "https://{baz}/set", - "properties": {}, - "headers": {} - }, - "type": "endpoint" + conditions: [] + endpoint: { + url: "https://{baz}/set" + properties: {} + headers: {} + } + type: "endpoint" } - ], - "type": "tree" - }, + ] + type: "tree" + } { - "conditions": [], - "rules": [ + conditions: [] + rules: [ { - "conditions": [ + conditions: [ { - "fn": "isSet", - "argv": [ + fn: "isSet" + argv: [ { - "ref": "bar" + ref: "bar" } ] } - ], - "endpoint": { - "url": "https://{bar}.{baz}/unset", - "properties": {}, - "headers": {} - }, - "type": "endpoint" - }, + ] + endpoint: { + url: "https://{bar}.{baz}/unset" + properties: {} + headers: {} + } + type: "endpoint" + } { - "conditions": [], - "endpoint": { - "url": "https://{baz}/unset", - "properties": {}, - "headers": {} - }, - "type": "endpoint" + conditions: [] + endpoint: { + url: "https://{baz}/unset" + properties: {} + headers: {} + } + type: "endpoint" } - ], - "type": "tree" + ] + type: "tree" } - ], - "type": "tree" + ] + type: "tree" } - ], - "type": "tree" + ] + type: "tree" } ] }) @endpointTests({ - "version": "1.0", - "testCases": [ + version: "1.0" + testCases: [ { - "documentation": "Custom Endpoint used" - "params": { - "Endpoint": "https://custom-endpoint.com" + documentation: "Custom Endpoint used" + params: { Endpoint: "https://custom-endpoint.com" } + expect: { + endpoint: { url: "https://custom-endpoint.com" } } - "expect": { - "endpoint": { - "url": "https://custom-endpoint.com" - } - }, - "operationInputs": [ + operationInputs: [ { - "operationName": "NoBindingsOperation", - "builtInParams": { - "SDK::Endpoint": "https://custom-endpoint.com" - } + operationName: "NoBindingsOperation" + builtInParams: { "SDK::Endpoint": "https://custom-endpoint.com" } } ] - }, + } { - "documentation": "Default values used" - "params": {} - "expect": { - "endpoint": { - "url": "https://baz/set" - } - }, - "operationInputs": [ + documentation: "Default values used" + params: {} + expect: { + endpoint: { url: "https://baz/set" } + } + operationInputs: [ { - "operationName": "NoBindingsOperation" + operationName: "NoBindingsOperation" } ] - }, + } { - "documentation": "Client config used over default" - "params": { - "baz": "client-config" + documentation: "Client config used over default" + params: { baz: "client-config" } + expect: { + endpoint: { url: "https://client-config/set" } } - "expect": { - "endpoint": { - "url": "https://client-config/set" - } - }, - "operationInputs": [ + operationInputs: [ { - "operationName": "NoBindingsOperation", - "clientParams": { - "baz": "client-config" - } + operationName: "NoBindingsOperation" + clientParams: { baz: "client-config" } } ] - }, + } { - "documentation": "StaticContextParam values used" - "params": { - "bar": "static-context", - "booleanParam": false + documentation: "StaticContextParam values used" + params: { bar: "static-context", booleanParam: false } + expect: { + endpoint: { url: "https://static-context.baz/unset" } } - "expect": { - "endpoint": { - "url": "https://static-context.baz/unset" - } - }, - "operationInputs": [ + operationInputs: [ { - "operationName": "BindingsStaticContextOperation", + operationName: "BindingsStaticContextOperation" } ] - }, + } { - "documentation": "ContextParam values used over config and defaults" - "params": { - "bar": "context-bar", - "baz": "context-baz", - "booleanParam": false + documentation: "ContextParam values used over config and defaults" + params: { bar: "context-bar", baz: "context-baz", booleanParam: false } + expect: { + endpoint: { url: "https://context-bar.context-baz/unset" } } - "expect": { - "endpoint": { - "url": "https://context-bar.context-baz/unset" - } - }, - "operationInputs": [ + operationInputs: [ { - "operationName": "ContextParamsOperation", - "operationParams": { - "bar": "context-bar", - "baz": "context-baz", - "booleanParam": false - }, - "clientParams": { - "bar": "client-config" - } + operationName: "ContextParamsOperation" + operationParams: { bar: "context-bar", baz: "context-baz", booleanParam: false } + clientParams: { bar: "client-config" } } ] - }, + } { - "documentation": "OperationContextParam values used over config and defaults" - "params": { - "bar": "operation-context-bar", - "baz": "operation-context-baz", - "booleanParam": false + documentation: "OperationContextParam values used over config and defaults" + params: { bar: "operation-context-bar", baz: "operation-context-baz", booleanParam: false } + expect: { + endpoint: { url: "https://operation-context-bar.operation-context-baz/unset" } } - "expect": { - "endpoint": { - "url": "https://operation-context-bar.operation-context-baz/unset" - } - }, - "operationInputs": [ + operationInputs: [ { - "operationName": "OperationContextParamsOperation", - "operationParams": { - "nested": { - "bar": "operation-context-bar", - "baz": "operation-context-baz" - } - "booleanParam": false - }, - "clientParams": { - "bar": "client-config" + operationName: "OperationContextParamsOperation" + operationParams: { + nested: { bar: "operation-context-bar", baz: "operation-context-baz" } + booleanParam: false } + clientParams: { bar: "client-config" } } ] - }, + } ] }) service EndpointBindingService { - version: "2022-01-01", + version: "2022-01-01" operations: [ - NoBindingsOperation, - BindingsStaticContextOperation, - ContextParamsOperation, + NoBindingsOperation + BindingsStaticContextOperation + ContextParamsOperation OperationContextParamsOperation ] } operation NoBindingsOperation { - input:= {} + input := {} } @suppress(["UnstableTrait"]) @staticContextParams( - "bar": {value: "static-context"}, - "booleanParam": {value: false} + bar: { value: "static-context" } + booleanParam: { value: false } ) operation BindingsStaticContextOperation { input := {} @@ -307,10 +244,10 @@ operation BindingsStaticContextOperation { operation ContextParamsOperation { input := { @contextParam(name: "bar") - bar: String, + bar: String @contextParam(name: "baz") - baz: String, + baz: String @contextParam(name: "booleanParam") booleanParam: Boolean @@ -318,19 +255,19 @@ operation ContextParamsOperation { } @operationContextParams( - "bar": { path: "nested.bar" } - "baz": { path: "nested.baz" } - "booleanParam": {path: "booleanParam"} + bar: { path: "nested.bar" } + baz: { path: "nested.baz" } + booleanParam: { path: "booleanParam" } ) operation OperationContextParamsOperation { input := { - nested: Nested, + nested: Nested booleanParam: Boolean } } structure Nested { - bar: String, + bar: String baz: String } @@ -339,10 +276,10 @@ list ListOfObjects { } structure ObjectMember { - key: String, + key: String } map Map { - key: String, + key: String value: String } diff --git a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/endpoints-string-array.smithy b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/endpoints-string-array.smithy index 22e8b3da95f..d64c297148c 100644 --- a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/endpoints-string-array.smithy +++ b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/endpoints-string-array.smithy @@ -4,133 +4,123 @@ namespace smithy.rules.tests use smithy.rules#endpointRuleSet use smithy.rules#endpointTests -use smithy.rules#staticContextParams use smithy.rules#operationContextParams +use smithy.rules#staticContextParams @suppress(["UnstableTrait"]) @endpointRuleSet({ - version: "1.0", + version: "1.0" parameters: { stringArrayParam: { - type: "stringArray", - required: true, - default: ["defaultValue1", "defaultValue2"], + type: "stringArray" + required: true + default: ["defaultValue1", "defaultValue2"] documentation: "docs" } - }, + } rules: [ { - "documentation": "Template first array value into URI if set", - "conditions": [ + documentation: "Template first array value into URI if set" + conditions: [ { - "fn": "getAttr", - "argv": [ + fn: "getAttr" + argv: [ { - "ref": "stringArrayParam" - }, + ref: "stringArrayParam" + } "[0]" - ], - "assign": "arrayValue" + ] + assign: "arrayValue" } - ], - "endpoint": { - "url": "https://example.com/{arrayValue}" - }, - "type": "endpoint" - }, + ] + endpoint: { url: "https://example.com/{arrayValue}" } + type: "endpoint" + } { - "conditions": [], - "documentation": "error fallthrough", - "error": "no array values set", - "type": "error" + conditions: [] + documentation: "error fallthrough" + error: "no array values set" + type: "error" } ] }) @endpointTests({ - "version": "1.0", - "testCases": [ + version: "1.0" + testCases: [ { - "documentation": "Default array values used" - "params": {} - "expect": { - "endpoint": { - "url": "https://example.com/defaultValue1" - } - }, - "operationInputs": [ + documentation: "Default array values used" + params: {} + expect: { + endpoint: { url: "https://example.com/defaultValue1" } + } + operationInputs: [ { - "operationName": "NoBindingsOperation", + operationName: "NoBindingsOperation" } ] - }, + } { - "documentation": "Empty array", - "params": { - "stringArrayParam": [] + documentation: "Empty array" + params: { + stringArrayParam: [] } - "expect": { - "error": "no array values set" - }, - "operationInputs": [ + expect: { error: "no array values set" } + operationInputs: [ { - "operationName": "EmptyStaticContextOperation", + operationName: "EmptyStaticContextOperation" } ] - }, + } { - "documentation": "Static value", - "params": { - "stringArrayParam": ["staticValue1"] + documentation: "Static value" + params: { + stringArrayParam: ["staticValue1"] } - "expect": { - "endpoint": { - "url": "https://example.com/staticValue1" - } - }, - "operationInputs": [ + expect: { + endpoint: { url: "https://example.com/staticValue1" } + } + operationInputs: [ { - "operationName": "StaticContextOperation", + operationName: "StaticContextOperation" } ] - }, + } { - "documentation": "bound value from input", - "params": { - "stringArrayParam": ["key1"] + documentation: "bound value from input" + params: { + stringArrayParam: ["key1"] } - "expect": { - "endpoint": { - "url": "https://example.com/key1" - } - }, - "operationInputs": [ + expect: { + endpoint: { url: "https://example.com/key1" } + } + operationInputs: [ { - "operationName": "ListOfObjectsOperation", - "operationParams": { - "nested": { - "listOfObjects": [{"key": "key1"}] + operationName: "ListOfObjectsOperation" + operationParams: { + nested: { + listOfObjects: [ + { + key: "key1" + } + ] } - }, - }, + } + } { - "operationName": "MapOperation", - "operationParams": { - "map": { - "key1": "value1" - } + operationName: "MapOperation" + operationParams: { + map: { key1: "value1" } } - }, + } { - "operationName": "ListOfUnionsOperation", - "operationParams": { - "listOfUnions": [ + operationName: "ListOfUnionsOperation" + operationParams: { + listOfUnions: [ { - "string": "key1" - }, + string: "key1" + } { - "object": { - "key": "key2" - } + object: { key: "key2" } } ] } @@ -140,24 +130,26 @@ use smithy.rules#operationContextParams ] }) service EndpointStringArrayService { - version: "2022-01-01", + version: "2022-01-01" operations: [ - NoBindingsOperation, - EmptyStaticContextOperation, - StaticContextOperation, - ListOfObjectsOperation, - ListOfUnionsOperation, + NoBindingsOperation + EmptyStaticContextOperation + StaticContextOperation + ListOfObjectsOperation + ListOfUnionsOperation MapOperation ] } operation NoBindingsOperation { - input:= {} + input := {} } @suppress(["UnstableTrait"]) @staticContextParams( - "stringArrayParam": {value: []} + stringArrayParam: { + value: [] + } ) operation EmptyStaticContextOperation { input := {} @@ -165,7 +157,9 @@ operation EmptyStaticContextOperation { @suppress(["UnstableTrait"]) @staticContextParams( - "stringArrayParam": {value: ["staticValue1"]} + stringArrayParam: { + value: ["staticValue1"] + } ) operation StaticContextOperation { input := {} @@ -173,30 +167,30 @@ operation StaticContextOperation { @suppress(["UnstableTrait"]) @operationContextParams( - "stringArrayParam": {path: "nested.listOfObjects[*].key"} + stringArrayParam: { path: "nested.listOfObjects[*].key" } ) operation ListOfObjectsOperation { - input:= { + input := { nested: NestedStructure } } @suppress(["UnstableTrait"]) @operationContextParams( - "stringArrayParam": {path: "listOfUnions[*][string, object.key][]"} + stringArrayParam: { path: "listOfUnions[*][string, object.key][]" } ) operation ListOfUnionsOperation { -input:= { + input := { listOfUnions: ListOfUnions } } @suppress(["UnstableTrait"]) @operationContextParams( - "stringArrayParam": {path: "keys(map)"} + stringArrayParam: { path: "keys(map)" } ) operation MapOperation { - input:= { + input := { map: Map } } @@ -210,7 +204,7 @@ list ListOfObjects { } structure ObjectMember { - key: String, + key: String } list ListOfUnions { @@ -218,11 +212,11 @@ list ListOfUnions { } union UnionMember { - string: String, + string: String object: ObjectMember } map Map { - key: String, + key: String value: String } diff --git a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/get-attr.smithy b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/get-attr.smithy index e0d29517e4d..e3006ae87df 100644 --- a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/get-attr.smithy +++ b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/get-attr.smithy @@ -8,68 +8,56 @@ use smithy.rules#endpointTests @suppress(["UnstableTrait"]) @endpointRuleSet({ - "version": "1.0", - "parameters": { - "Bucket": { - "type": "string", - "documentation": "docs" - } - }, - "rules": [ + version: "1.0" + parameters: { + Bucket: { type: "string", documentation: "docs" } + } + rules: [ { - "documentation": "bucket is set, handle bucket specific endpoints", - "conditions": [ + documentation: "bucket is set, handle bucket specific endpoints" + conditions: [ { - "fn": "isSet", - "argv": [ + fn: "isSet" + argv: [ { - "ref": "Bucket" + ref: "Bucket" } ] - }, + } { - "fn": "parseURL", - "argv": [ - "{Bucket}" - ], - "assign": "bucketUrl" - }, + fn: "parseURL" + argv: ["{Bucket}"] + assign: "bucketUrl" + } { - "fn": "getAttr", - "argv": [ + fn: "getAttr" + argv: [ { - "ref": "bucketUrl" - }, + ref: "bucketUrl" + } "path" - ], - "assign": "path" + ] + assign: "path" } - ], - "endpoint": { - "url": "https://{bucketUrl#authority}{path}" - }, - "type": "endpoint" + ] + endpoint: { url: "https://{bucketUrl#authority}{path}" } + type: "endpoint" } ] }) - @endpointTests({ - "version": "1.0", - "testCases": [ + version: "1.0" + testCases: [ { - "documentation": "getAttr on top level values in function and template" - "params": { - "Bucket": "http://example.com/path" - } - "expect": { - "endpoint": { - "url": "https://example.com/path" - } + documentation: "getAttr on top level values in function and template" + params: { Bucket: "http://example.com/path" } + expect: { + endpoint: { url: "https://example.com/path" } } } ] }) @clientContextParams( - Bucket: {type: "string", documentation: "docs"} + Bucket: { type: "string", documentation: "docs" } ) service GetAttrService {} diff --git a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/headers.smithy b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/headers.smithy index d26842c785a..05bcf35d409 100644 --- a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/headers.smithy +++ b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/headers.smithy @@ -8,67 +8,52 @@ use smithy.rules#endpointTests @suppress(["UnstableTrait"]) @endpointRuleSet({ - "version": "1.0", - "parameters": { - "Region": { - "type": "string", - "documentation": "The region to dispatch this request, eg. `us-east-1`." - } - }, - "rules": [ + version: "1.0" + parameters: { + Region: { type: "string", documentation: "The region to dispatch this request, eg. `us-east-1`." } + } + rules: [ { - "documentation": "Template the region into the URI when region is set", - "conditions": [ + documentation: "Template the region into the URI when region is set" + conditions: [ { - "fn": "isSet", - "argv": [ + fn: "isSet" + argv: [ { - "ref": "Region" + ref: "Region" } ] } - ], - "endpoint": { - "url": "https://{Region}.amazonaws.com", - "headers": { - "x-amz-region": [ - "{Region}" - ], - "x-amz-multi": [ - "*", - "{Region}" - ] + ] + endpoint: { + url: "https://{Region}.amazonaws.com" + headers: { + "x-amz-region": ["{Region}"] + "x-amz-multi": ["*", "{Region}"] } - }, - "type": "endpoint" - }, + } + type: "endpoint" + } { - "documentation": "fallback when region is unset", - "conditions": [], - "error": "Region must be set to resolve a valid endpoint", - "type": "error" + documentation: "fallback when region is unset" + conditions: [] + error: "Region must be set to resolve a valid endpoint" + type: "error" } ] }) @endpointTests( - "version": "1.0", - "testCases": [ + version: "1.0" + testCases: [ { - "documentation": "header set to region", - "params": { - "Region": "us-east-1" - }, - "expect": { - "endpoint": { - "url": "https://us-east-1.amazonaws.com", - "headers": { - "x-amz-region": [ - "us-east-1" - ], - "x-amz-multi": [ - "*", - "us-east-1" - ] + documentation: "header set to region" + params: { Region: "us-east-1" } + expect: { + endpoint: { + url: "https://us-east-1.amazonaws.com" + headers: { + "x-amz-region": ["us-east-1"] + "x-amz-multi": ["*", "us-east-1"] } } } @@ -76,6 +61,6 @@ use smithy.rules#endpointTests ] ) @clientContextParams( - Region: {type: "string", documentation: "docs"} + Region: { type: "string", documentation: "docs" } ) service HeadersService {} diff --git a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/ite.smithy b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/ite.smithy new file mode 100644 index 00000000000..e1544e6787f --- /dev/null +++ b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/ite.smithy @@ -0,0 +1,77 @@ +$version: "2.0" + +namespace smithy.rules.tests + +use smithy.rules#clientContextParams +use smithy.rules#endpointRuleSet +use smithy.rules#endpointTests + +@clientContextParams( + useFips: { type: "boolean", documentation: "Use FIPS endpoints" } +) +@endpointRuleSet({ + version: "1.1" + parameters: { + useFips: { type: "boolean", documentation: "Use FIPS endpoints", default: false, required: true } + } + rules: [ + { + documentation: "Use ite to select endpoint suffix" + conditions: [ + { + fn: "ite" + argv: [ + { + ref: "useFips" + } + "-fips" + "" + ] + assign: "suffix" + } + ] + endpoint: { url: "https://example{suffix}.com" } + type: "endpoint" + } + ] +}) +@endpointTests({ + version: "1.0" + testCases: [ + { + documentation: "When useFips is true, returns trueValue" + params: { useFips: true } + operationInputs: [ + { + operationName: "GetThing" + } + ] + expect: { + endpoint: { url: "https://example-fips.com" } + } + } + { + documentation: "When useFips is false, returns falseValue" + params: { useFips: false } + operationInputs: [ + { + operationName: "GetThing" + } + ] + expect: { + endpoint: { url: "https://example.com" } + } + } + ] +}) +@suppress(["UnstableTrait.smithy"]) +service IteTest { + version: "2022-01-01" + operations: [ + GetThing + ] +} + +operation GetThing { + input := {} +} diff --git a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/manifest b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/manifest index 11d3889e933..ac85466d3b6 100644 --- a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/manifest +++ b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/manifest @@ -1,10 +1,13 @@ +coalesce.smithy default-values.smithy endpoint-bindings.smithy endpoints-string-array.smithy get-attr.smithy headers.smithy +ite.smithy manifest parse-url.smithy +split.smithy substring.smithy url-encode.smithy valid-hostlabel.smithy diff --git a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/parse-url.smithy b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/parse-url.smithy index db15667c232..87f65bb1471 100644 --- a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/parse-url.smithy +++ b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/parse-url.smithy @@ -8,258 +8,183 @@ use smithy.rules#endpointTests @suppress(["UnstableTrait"]) @endpointRuleSet({ - "version": "1.0", - "parameters": { - "Endpoint": { - "type": "string", - "documentation": "docs" - } - }, - "rules": [ - { - "documentation": "endpoint is set and is a valid URL", - "conditions": [ + version: "1.0" + parameters: { + Endpoint: { type: "string", documentation: "docs" } + } + rules: [ + { + documentation: "endpoint is set and is a valid URL" + conditions: [ { - "fn": "isSet", - "argv": [ + fn: "isSet" + argv: [ { - "ref": "Endpoint" + ref: "Endpoint" } ] - }, + } { - "fn": "parseURL", - "argv": [ - "{Endpoint}" - ], - "assign": "url" + fn: "parseURL" + argv: ["{Endpoint}"] + assign: "url" } - ], - "rules": [ + ] + rules: [ { - "conditions": [ + conditions: [ { - "fn": "booleanEquals", - "argv": [ + fn: "booleanEquals" + argv: [ { - "fn": "getAttr", - "argv": [ + fn: "getAttr" + argv: [ { - "ref": "url" - }, + ref: "url" + } "isIp" ] - }, + } true ] } - ], - "endpoint": { - "url": "{url#scheme}://{url#authority}{url#normalizedPath}is-ip-addr" - }, - "type": "endpoint" - }, + ] + endpoint: { url: "{url#scheme}://{url#authority}{url#normalizedPath}is-ip-addr" } + type: "endpoint" + } { - "conditions": [ + conditions: [ { - "fn": "stringEquals", - "argv": [ - "{url#path}", - "/port" - ] + fn: "stringEquals" + argv: ["{url#path}", "/port"] } - ], - "endpoint": { - "url": "{url#scheme}://{url#authority}/uri-with-port" - }, - "type": "endpoint" - }, + ] + endpoint: { url: "{url#scheme}://{url#authority}/uri-with-port" } + type: "endpoint" + } { - "conditions": [ + conditions: [ { - "fn": "stringEquals", - "argv": [ - "{url#normalizedPath}", - "/" - ] + fn: "stringEquals" + argv: ["{url#normalizedPath}", "/"] } - ], - "endpoint": { - "url": "https://{url#scheme}-{url#authority}-nopath.example.com" - }, - "type": "endpoint" - }, + ] + endpoint: { url: "https://{url#scheme}-{url#authority}-nopath.example.com" } + type: "endpoint" + } { - "conditions": [], - "endpoint": { - "url": "https://{url#scheme}-{url#authority}.example.com/path-is{url#path}" - }, - "type": "endpoint" + conditions: [] + endpoint: { url: "https://{url#scheme}-{url#authority}.example.com/path-is{url#path}" } + type: "endpoint" } - ], - "type": "tree" - }, + ] + type: "tree" + } { - "error": "endpoint was invalid", - "conditions": [], - "type": "error" + error: "endpoint was invalid" + conditions: [] + type: "error" } ] }) @endpointTests( - version: "1.0", + version: "1.0" testCases: [ { - "documentation": "simple URL parsing", - "params": { - "Endpoint": "https://authority.com/custom-path" - }, - "expect": { - "endpoint": { - "url": "https://https-authority.com.example.com/path-is/custom-path" - } + documentation: "simple URL parsing" + params: { Endpoint: "https://authority.com/custom-path" } + expect: { + endpoint: { url: "https://https-authority.com.example.com/path-is/custom-path" } } - }, + } { - "documentation": "empty path no slash", - "params": { - "Endpoint": "https://authority.com" - }, - "expect": { - "endpoint": { - "url": "https://https-authority.com-nopath.example.com" - } + documentation: "empty path no slash" + params: { Endpoint: "https://authority.com" } + expect: { + endpoint: { url: "https://https-authority.com-nopath.example.com" } } - }, + } { - "documentation": "empty path with slash", - "params": { - "Endpoint": "https://authority.com/" - }, - "expect": { - "endpoint": { - "url": "https://https-authority.com-nopath.example.com" - } + documentation: "empty path with slash" + params: { Endpoint: "https://authority.com/" } + expect: { + endpoint: { url: "https://https-authority.com-nopath.example.com" } } - }, + } { - "documentation": "authority with port", - "params": { - "Endpoint": "https://authority.com:8000/port" - }, - "expect": { - "endpoint": { - "url": "https://authority.com:8000/uri-with-port" - } + documentation: "authority with port" + params: { Endpoint: "https://authority.com:8000/port" } + expect: { + endpoint: { url: "https://authority.com:8000/uri-with-port" } } - }, + } { - "documentation": "http schemes", - "params": { - "Endpoint": "http://authority.com:8000/port" - }, - "expect": { - "endpoint": { - "url": "http://authority.com:8000/uri-with-port" - } + documentation: "http schemes" + params: { Endpoint: "http://authority.com:8000/port" } + expect: { + endpoint: { url: "http://authority.com:8000/uri-with-port" } } - }, + } { - "documentation": "arbitrary schemes are not supported", - "params": { - "Endpoint": "acbd://example.com" - }, - "expect": { - "error": "endpoint was invalid" - } - }, + documentation: "arbitrary schemes are not supported" + params: { Endpoint: "acbd://example.com" } + expect: { error: "endpoint was invalid" } + } { - "documentation": "host labels are not validated", - "params": { - "Endpoint": "http://99_ab.com" - }, - "expect": { - "endpoint": { - "url": "https://http-99_ab.com-nopath.example.com" - } + documentation: "host labels are not validated" + params: { Endpoint: "http://99_ab.com" } + expect: { + endpoint: { url: "https://http-99_ab.com-nopath.example.com" } } - }, + } { - "documentation": "host labels are not validated", - "params": { - "Endpoint": "http://99_ab-.com" - }, - "expect": { - "endpoint": { - "url": "https://http-99_ab-.com-nopath.example.com" - } + documentation: "host labels are not validated" + params: { Endpoint: "http://99_ab-.com" } + expect: { + endpoint: { url: "https://http-99_ab-.com-nopath.example.com" } } - }, + } { - "documentation": "invalid URL", - "params": { - "Endpoint": "http://abc.com:a/foo" - }, - "expect": { - "error": "endpoint was invalid" - } - }, + documentation: "invalid URL" + params: { Endpoint: "http://abc.com:a/foo" } + expect: { error: "endpoint was invalid" } + } { - "documentation": "IP Address", - "params": { - "Endpoint": "http://192.168.1.1/foo/" - }, - "expect": { - "endpoint": { - "url": "http://192.168.1.1/foo/is-ip-addr" - } + documentation: "IP Address" + params: { Endpoint: "http://192.168.1.1/foo/" } + expect: { + endpoint: { url: "http://192.168.1.1/foo/is-ip-addr" } } - }, + } { - "documentation": "IP Address with port", - "params": { - "Endpoint": "http://192.168.1.1:1234/foo/" - }, - "expect": { - "endpoint": { - "url": "http://192.168.1.1:1234/foo/is-ip-addr" - } + documentation: "IP Address with port" + params: { Endpoint: "http://192.168.1.1:1234/foo/" } + expect: { + endpoint: { url: "http://192.168.1.1:1234/foo/is-ip-addr" } } - }, + } { - "documentation": "IPv6 Address", - "params": { - "Endpoint": "https://[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443" - }, - "expect": { - "endpoint": { - "url": "https://[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443/is-ip-addr" - } + documentation: "IPv6 Address" + params: { Endpoint: "https://[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443" } + expect: { + endpoint: { url: "https://[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443/is-ip-addr" } } - }, + } { - "documentation": "weird DNS name", - "params": { - "Endpoint": "https://999.999.abc.blah" - }, - "expect": { - "endpoint": { - "url": "https://https-999.999.abc.blah-nopath.example.com" - } + documentation: "weird DNS name" + params: { Endpoint: "https://999.999.abc.blah" } + expect: { + endpoint: { url: "https://https-999.999.abc.blah-nopath.example.com" } } - }, + } { - "documentation": "query in resolved endpoint is not supported", - "params": { - "Endpoint": "https://example.com/path?query1=foo" - }, - "expect": { - "error": "endpoint was invalid" - } + documentation: "query in resolved endpoint is not supported" + params: { Endpoint: "https://example.com/path?query1=foo" } + expect: { error: "endpoint was invalid" } } ] ) @clientContextParams( - Endpoint: {type: "string", documentation: "docs"} + Endpoint: { type: "string", documentation: "docs" } ) service ParseUrlService {} diff --git a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/split.smithy b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/split.smithy new file mode 100644 index 00000000000..dc59e518590 --- /dev/null +++ b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/split.smithy @@ -0,0 +1,799 @@ +$version: "2.0" + +namespace smithy.rules.tests + +use smithy.rules#clientContextParams +use smithy.rules#endpointRuleSet +use smithy.rules#endpointTests + +@endpointRuleSet({ + version: "1.3" + parameters: { + Input: { type: "string", required: true, documentation: "The input string to split" } + Delimiter: { type: "string", required: true, documentation: "The delimiter to split by" } + Limit: { type: "string", required: true, documentation: "The split limit as a string" } + } + rules: [ + { + documentation: "Split with limit 0 (unlimited)" + conditions: [ + { + fn: "stringEquals" + argv: ["{Limit}", "0"] + } + { + fn: "split" + argv: ["{Input}", "{Delimiter}", 0] + assign: "parts" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[0]" + ] + } + "" + ] + assign: "part1" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[1]" + ] + } + "" + ] + assign: "part2" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[2]" + ] + } + "" + ] + assign: "part3" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[3]" + ] + } + "" + ] + assign: "part4" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[4]" + ] + } + "" + ] + assign: "part5" + } + ] + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1={part1}; p2={part2}; p3={part3}; p4={part4}; p5={part5}" } + } + type: "endpoint" + } + { + documentation: "Split with limit 1 (no split)" + conditions: [ + { + fn: "stringEquals" + argv: ["{Limit}", "1"] + } + { + fn: "split" + argv: ["{Input}", "{Delimiter}", 1] + assign: "parts" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[0]" + ] + } + "" + ] + assign: "part1" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[1]" + ] + } + "" + ] + assign: "part2" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[2]" + ] + } + "" + ] + assign: "part3" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[3]" + ] + } + "" + ] + assign: "part4" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[4]" + ] + } + "" + ] + assign: "part5" + } + ] + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1={part1}; p2={part2}; p3={part3}; p4={part4}; p5={part5}" } + } + type: "endpoint" + } + { + documentation: "Split with limit 2" + conditions: [ + { + fn: "stringEquals" + argv: ["{Limit}", "2"] + } + { + fn: "split" + argv: ["{Input}", "{Delimiter}", 2] + assign: "parts" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[0]" + ] + } + "" + ] + assign: "part1" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[1]" + ] + } + "" + ] + assign: "part2" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[2]" + ] + } + "" + ] + assign: "part3" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[3]" + ] + } + "" + ] + assign: "part4" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[4]" + ] + } + "" + ] + assign: "part5" + } + ] + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1={part1}; p2={part2}; p3={part3}; p4={part4}; p5={part5}" } + } + type: "endpoint" + } + { + documentation: "Split with limit 3" + conditions: [ + { + fn: "stringEquals" + argv: ["{Limit}", "3"] + } + { + fn: "split" + argv: ["{Input}", "{Delimiter}", 3] + assign: "parts" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[0]" + ] + } + "" + ] + assign: "part1" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[1]" + ] + } + "" + ] + assign: "part2" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[2]" + ] + } + "" + ] + assign: "part3" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[3]" + ] + } + "" + ] + assign: "part4" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[4]" + ] + } + "" + ] + assign: "part5" + } + ] + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1={part1}; p2={part2}; p3={part3}; p4={part4}; p5={part5}" } + } + type: "endpoint" + } + { + documentation: "Split with limit 4" + conditions: [ + { + fn: "stringEquals" + argv: ["{Limit}", "4"] + } + { + fn: "split" + argv: ["{Input}", "{Delimiter}", 4] + assign: "parts" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[0]" + ] + } + "" + ] + assign: "part1" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[1]" + ] + } + "" + ] + assign: "part2" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[2]" + ] + } + "" + ] + assign: "part3" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[3]" + ] + } + "" + ] + assign: "part4" + } + { + fn: "coalesce" + argv: [ + { + fn: "getAttr" + argv: [ + { + ref: "parts" + } + "[4]" + ] + } + "" + ] + assign: "part5" + } + ] + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1={part1}; p2={part2}; p3={part3}; p4={part4}; p5={part5}" } + } + type: "endpoint" + } + { + conditions: [] + documentation: "error fallthrough" + error: "endpoint error" + type: "error" + } + ] +}) +@endpointTests( + version: "1.0" + testCases: [ + // Limit 0 tests + { + documentation: "basic three-part split" + params: { Input: "a--b--c", Delimiter: "--", Limit: "0" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=a; p2=b; p3=c; p4=; p5=" } + } + } + } + { + documentation: "empty string returns single empty element" + params: { Input: "", Delimiter: "--", Limit: "0" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=; p2=; p3=; p4=; p5=" } + } + } + } + { + documentation: "delimiter not found returns original string" + params: { Input: "no-delimiter", Delimiter: "--", Limit: "0" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=no-delimiter; p2=; p3=; p4=; p5=" } + } + } + } + { + documentation: "leading delimiter creates empty first element" + params: { Input: "--leading", Delimiter: "--", Limit: "0" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=; p2=leading; p3=; p4=; p5=" } + } + } + } + { + documentation: "trailing delimiter creates empty last element" + params: { Input: "trailing--", Delimiter: "--", Limit: "0" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=trailing; p2=; p3=; p4=; p5=" } + } + } + } + { + documentation: "adjacent delimiters create empty element" + params: { Input: "----", Delimiter: "--", Limit: "0" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=; p2=; p3=; p4=; p5=" } + } + } + } + { + documentation: "delimiter equals input creates two empty strings" + params: { Input: "--", Delimiter: "--", Limit: "0" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=; p2=; p3=; p4=; p5=" } + } + } + } + { + documentation: "overlapping delimiter pattern" + params: { Input: "aaaa", Delimiter: "aa", Limit: "0" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=; p2=; p3=; p4=; p5=" } + } + } + } + { + documentation: "overlapping delimiter with odd remainder" + params: { Input: "aaa", Delimiter: "aa", Limit: "0" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=; p2=a; p3=; p4=; p5=" } + } + } + } + { + documentation: "multi-character delimiter" + params: { Input: "foo<=>bar<=>baz", Delimiter: "<=>", Limit: "0" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=foo; p2=bar; p3=baz; p4=; p5=" } + } + } + } + { + documentation: "multi-character delimiter with limit" + params: { Input: "foo<=>bar<=>baz", Delimiter: "<=>", Limit: "2" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=foo; p2=bar<=>baz; p3=; p4=; p5=" } + } + } + } + { + documentation: "both leading and trailing delimiters" + params: { Input: "--both--", Delimiter: "--", Limit: "0" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=; p2=both; p3=; p4=; p5=" } + } + } + } + { + documentation: "both leading and trailing with limit" + params: { Input: "--both--", Delimiter: "--", Limit: "2" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=; p2=both--; p3=; p4=; p5=" } + } + } + } + // Limit 1 tests (no split) + { + documentation: "limit 1 returns original string" + params: { Input: "a--b--c", Delimiter: "--", Limit: "1" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=a--b--c; p2=; p3=; p4=; p5=" } + } + } + } + { + documentation: "limit 1 with no delimiter" + params: { Input: "no-delimiter", Delimiter: "--", Limit: "1" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=no-delimiter; p2=; p3=; p4=; p5=" } + } + } + } + // Limit 2 tests + { + documentation: "limit 2 splits once" + params: { Input: "a--b--c", Delimiter: "--", Limit: "2" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=a; p2=b--c; p3=; p4=; p5=" } + } + } + } + { + documentation: "limit 2 with leading delimiter" + params: { Input: "--x-s3--azid", Delimiter: "--", Limit: "2" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=; p2=x-s3--azid; p3=; p4=; p5=" } + } + } + } + // Limit 3 tests + { + documentation: "limit 3 exact match" + params: { Input: "a--b--c", Delimiter: "--", Limit: "3" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=a; p2=b; p3=c; p4=; p5=" } + } + } + } + { + documentation: "limit 3 with remainder" + params: { Input: "a--b--c--d", Delimiter: "--", Limit: "3" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=a; p2=b; p3=c--d; p4=; p5=" } + } + } + } + // Limit 4 tests + { + documentation: "S3 Express bucket pattern" + params: { Input: "--x-s3--azid--suffix", Delimiter: "--", Limit: "4" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=; p2=x-s3; p3=azid; p4=suffix; p5=" } + } + } + } + { + documentation: "limit 4 stops at 4 parts" + params: { Input: "a--b--c--d--e", Delimiter: "--", Limit: "4" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=a; p2=b; p3=c; p4=d--e; p5=" } + } + } + } + // Unicode tests + { + documentation: "unicode emoji delimiter" + params: { Input: "a🌟b🌟c", Delimiter: "🌟", Limit: "0" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=a; p2=b; p3=c; p4=; p5=" } + } + } + } + // Regex treated literally + { + documentation: "regex-like pattern treated literally" + params: { Input: "a.*b.*c", Delimiter: ".*", Limit: "0" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=a; p2=b; p3=c; p4=; p5=" } + } + } + } + { + documentation: "pipe delimiter" + params: { Input: "a|b|c|d|e", Delimiter: "|", Limit: "0" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=a; p2=b; p3=c; p4=d; p5=e" } + } + } + } + // Edge cases + { + documentation: "delimiter longer than input" + params: { Input: "ab", Delimiter: "abcd", Limit: "0" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=ab; p2=; p3=; p4=; p5=" } + } + } + } + { + documentation: "delimiter equals entire input" + params: { Input: "abc", Delimiter: "abc", Limit: "0" } + expect: { + endpoint: { + url: "https://example.com" + properties: { splitResult: "p1=; p2=; p3=; p4=; p5=" } + } + } + } + ] +) +@clientContextParams( + Input: { type: "string", documentation: "Input string to split" } + Delimiter: { type: "string", documentation: "Delimiter to split by" } + Limit: { type: "string", documentation: "Split limit" } +) +@suppress(["UnstableTrait.smithy"]) +service SplitTest {} diff --git a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/substring.smithy b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/substring.smithy index ad79f4aaf7f..f7a2108e2ff 100644 --- a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/substring.smithy +++ b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/substring.smithy @@ -8,267 +8,155 @@ use smithy.rules#endpointTests @suppress(["UnstableTrait"]) @endpointRuleSet({ - "version": "1.0", - "parameters": { - "TestCaseId": { - "type": "string", - "required": true, - "documentation": "Test case id used to select the test case to use" - }, - "Input": { - "type": "string", - "required": true, - "documentation": "the input used to test substring" - } - }, - "rules": [ - { - "documentation": "Substring from beginning of input", - "conditions": [ + version: "1.0" + parameters: { + TestCaseId: { type: "string", required: true, documentation: "Test case id used to select the test case to use" } + Input: { type: "string", required: true, documentation: "the input used to test substring" } + } + rules: [ + { + documentation: "Substring from beginning of input" + conditions: [ { - "fn": "stringEquals", - "argv": [ - "{TestCaseId}", - "1" - ] - }, + fn: "stringEquals" + argv: ["{TestCaseId}", "1"] + } { - "fn": "substring", - "argv": [ - "{Input}", - 0, - 4, - false - ], - "assign": "output" + fn: "substring" + argv: ["{Input}", 0, 4, false] + assign: "output" } - ], - "error": "The value is: `{output}`", - "type": "error" - }, + ] + error: "The value is: `{output}`" + type: "error" + } { - "documentation": "Substring from end of input", - "conditions": [ + documentation: "Substring from end of input" + conditions: [ { - "fn": "stringEquals", - "argv": [ - "{TestCaseId}", - "2" - ] - }, + fn: "stringEquals" + argv: ["{TestCaseId}", "2"] + } { - "fn": "substring", - "argv": [ - "{Input}", - 0, - 4, - true - ], - "assign": "output" + fn: "substring" + argv: ["{Input}", 0, 4, true] + assign: "output" } - ], - "error": "The value is: `{output}`", - "type": "error" - }, + ] + error: "The value is: `{output}`" + type: "error" + } { - "documentation": "Substring the middle of the string", - "conditions": [ + documentation: "Substring the middle of the string" + conditions: [ { - "fn": "stringEquals", - "argv": [ - "{TestCaseId}", - "3" - ] - }, + fn: "stringEquals" + argv: ["{TestCaseId}", "3"] + } { - "fn": "substring", - "argv": [ - "{Input}", - 1, - 3, - false - ], - "assign": "output" + fn: "substring" + argv: ["{Input}", 1, 3, false] + assign: "output" } - ], - "error": "The value is: `{output}`", - "type": "error" - }, + ] + error: "The value is: `{output}`" + type: "error" + } { - "documentation": "fallback when no tests match", - "conditions": [], - "error": "No tests matched", - "type": "error" + documentation: "fallback when no tests match" + conditions: [] + error: "No tests matched" + type: "error" } ] }) @endpointTests( - version: "1.0", + version: "1.0" testCases: [ { - "documentation": "substring when string is long enough", - "params": { - "TestCaseId": "1", - "Input": "abcdefg" - }, - "expect": { - "error": "The value is: `abcd`" - } - }, + documentation: "substring when string is long enough" + params: { TestCaseId: "1", Input: "abcdefg" } + expect: { error: "The value is: `abcd`" } + } { - "documentation": "substring when string is exactly the right length", - "params": { - "TestCaseId": "1", - "Input": "abcd" - }, - "expect": { - "error": "The value is: `abcd`" - } - }, + documentation: "substring when string is exactly the right length" + params: { TestCaseId: "1", Input: "abcd" } + expect: { error: "The value is: `abcd`" } + } { - "documentation": "substring when string is too short", - "params": { - "TestCaseId": "1", - "Input": "abc" - }, - "expect": { - "error": "No tests matched" - } - }, + documentation: "substring when string is too short" + params: { TestCaseId: "1", Input: "abc" } + expect: { error: "No tests matched" } + } { - "documentation": "substring when string is too short", - "params": { - "TestCaseId": "1", - "Input": "" - }, - "expect": { - "error": "No tests matched" - } - }, + documentation: "substring when string is too short" + params: { TestCaseId: "1", Input: "" } + expect: { error: "No tests matched" } + } { - "documentation": "substring on wide characters (ensure that unicode code points are properly counted)", - "params": { - "TestCaseId": "1", - "Input": "\ufdfd" - }, - "expect": { - "error": "No tests matched" - } - }, + documentation: "substring on wide characters (ensure that unicode code points are properly counted)" + params: { TestCaseId: "1", Input: "\ufdfd" } + expect: { error: "No tests matched" } + } { - "documentation": "the full set of ascii is supported, including non-printable characters", - "params": { - "TestCaseId": "1", - "Input": "\u007Fabcdef" - }, - "expect": { - "error": "The value is: `\u007Fabc`" - } - }, + documentation: "the full set of ascii is supported, including non-printable characters" + params: { TestCaseId: "1", Input: "\u007Fabcdef" } + expect: { error: "The value is: `\u007Fabc`" } + } { - "documentation": "substring when string is long enough", - "params": { - "TestCaseId": "2", - "Input": "abcdefg" - }, - "expect": { - "error": "The value is: `defg`" - } - }, + documentation: "substring when string is long enough" + params: { TestCaseId: "2", Input: "abcdefg" } + expect: { error: "The value is: `defg`" } + } { - "documentation": "substring when string is exactly the right length", - "params": { - "TestCaseId": "2", - "Input": "defg" - }, - "expect": { - "error": "The value is: `defg`" - } - }, + documentation: "substring when string is exactly the right length" + params: { TestCaseId: "2", Input: "defg" } + expect: { error: "The value is: `defg`" } + } { - "documentation": "substring when string is too short", - "params": { - "TestCaseId": "2", - "Input": "abc" - }, - "expect": { - "error": "No tests matched" - } - }, + documentation: "substring when string is too short" + params: { TestCaseId: "2", Input: "abc" } + expect: { error: "No tests matched" } + } { - "documentation": "substring when string is too short", - "params": { - "TestCaseId": "2", - "Input": "" - }, - "expect": { - "error": "No tests matched" - } - }, + documentation: "substring when string is too short" + params: { TestCaseId: "2", Input: "" } + expect: { error: "No tests matched" } + } { - "documentation": "substring on wide characters (ensure that unicode code points are properly counted)", - "params": { - "TestCaseId": "2", - "Input": "\ufdfd" - }, - "expect": { - "error": "No tests matched" - } - }, + documentation: "substring on wide characters (ensure that unicode code points are properly counted)" + params: { TestCaseId: "2", Input: "\ufdfd" } + expect: { error: "No tests matched" } + } { - "documentation": "substring when string is longer", - "params": { - "TestCaseId": "3", - "Input": "defg" - }, - "expect": { - "error": "The value is: `ef`" - } - }, + documentation: "substring when string is longer" + params: { TestCaseId: "3", Input: "defg" } + expect: { error: "The value is: `ef`" } + } { - "documentation": "substring when string is exact length", - "params": { - "TestCaseId": "3", - "Input": "def" - }, - "expect": { - "error": "The value is: `ef`" - } - }, + documentation: "substring when string is exact length" + params: { TestCaseId: "3", Input: "def" } + expect: { error: "The value is: `ef`" } + } { - "documentation": "substring when string is too short", - "params": { - "TestCaseId": "3", - "Input": "ab" - }, - "expect": { - "error": "No tests matched" - } - }, + documentation: "substring when string is too short" + params: { TestCaseId: "3", Input: "ab" } + expect: { error: "No tests matched" } + } { - "documentation": "substring when string is too short", - "params": { - "TestCaseId": "3", - "Input": "" - }, - "expect": { - "error": "No tests matched" - } - }, + documentation: "substring when string is too short" + params: { TestCaseId: "3", Input: "" } + expect: { error: "No tests matched" } + } { - "documentation": "substring on wide characters (ensure that unicode code points are properly counted)", - "params": { - "TestCaseId": "3", - "Input": "\ufdfd" - }, - "expect": { - "error": "No tests matched" - } + documentation: "substring on wide characters (ensure that unicode code points are properly counted)" + params: { TestCaseId: "3", Input: "\ufdfd" } + expect: { error: "No tests matched" } } ] ) @clientContextParams( - TestCaseId: {type: "string", documentation: "docs"} - Input: {type: "string", documentation: "docs"} + TestCaseId: { type: "string", documentation: "docs" } + Input: { type: "string", documentation: "docs" } ) service SubstringService {} diff --git a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/url-encode.smithy b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/url-encode.smithy index 149bd1a2bc6..a232730a03a 100644 --- a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/url-encode.smithy +++ b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/url-encode.smithy @@ -8,126 +8,85 @@ use smithy.rules#endpointTests @suppress(["UnstableTrait"]) @endpointRuleSet({ - "version": "1.0", - "parameters": { - "TestCaseId": { - "type": "string", - "required": true, - "documentation": "Test case id used to select the test case to use" - }, - "Input": { - "type": "string", - "required": true, - "documentation": "The input used to test uriEncode" - } - }, - "rules": [ + version: "1.0" + parameters: { + TestCaseId: { type: "string", required: true, documentation: "Test case id used to select the test case to use" } + Input: { type: "string", required: true, documentation: "The input used to test uriEncode" } + } + rules: [ { - "documentation": "uriEncode on input", - "conditions": [ + documentation: "uriEncode on input" + conditions: [ { - "fn": "stringEquals", - "argv": [ - "{TestCaseId}", - "1" - ] - }, + fn: "stringEquals" + argv: ["{TestCaseId}", "1"] + } { - "fn": "uriEncode", - "argv": [ - "{Input}" - ], - "assign": "output" + fn: "uriEncode" + argv: ["{Input}"] + assign: "output" } - ], - "error": "The value is: `{output}`", - "type": "error" - }, + ] + error: "The value is: `{output}`" + type: "error" + } { - "documentation": "fallback when no tests match", - "conditions": [], - "error": "No tests matched", - "type": "error" + documentation: "fallback when no tests match" + conditions: [] + error: "No tests matched" + type: "error" } ] }) @endpointTests( - version: "1.0", + version: "1.0" testCases: [ { - "documentation": "uriEncode when the string has nothing to encode returns the input", - "params": { - "TestCaseId": "1", - "Input": "abcdefg" - }, - "expect": { - "error": "The value is: `abcdefg`" - } - }, + documentation: "uriEncode when the string has nothing to encode returns the input" + params: { TestCaseId: "1", Input: "abcdefg" } + expect: { error: "The value is: `abcdefg`" } + } { - "documentation": "uriEncode with single character to encode encodes only that character", - "params": { - "TestCaseId": "1", - "Input": "abc:defg" - }, - "expect": { - "error": "The value is: `abc%3Adefg`" - } - }, + documentation: "uriEncode with single character to encode encodes only that character" + params: { TestCaseId: "1", Input: "abc:defg" } + expect: { error: "The value is: `abc%3Adefg`" } + } { - "documentation": "uriEncode with all ASCII characters to encode encodes all characters", - "params": { - "TestCaseId": "1", - "Input": "/:,?#[]{}|@! $&'()*+;=%<>\"^`\\" - }, - "expect": { - "error": "The value is: `%2F%3A%2C%3F%23%5B%5D%7B%7D%7C%40%21%20%24%26%27%28%29%2A%2B%3B%3D%25%3C%3E%22%5E%60%5C`" + documentation: "uriEncode with all ASCII characters to encode encodes all characters" + params: { TestCaseId: "1", Input: "/:,?#[]{}|@! $&'()*+;=%<>\"^`\\" } + expect: { + error: "The value is: `%2F%3A%2C%3F%23%5B%5D%7B%7D%7C%40%21%20%24%26%27%28%29%2A%2B%3B%3D%25%3C%3E%22%5E%60%5C`" } - }, + } { - "documentation": "uriEncode with ASCII characters that should not be encoded returns the input", - "params": { - "TestCaseId": "1", - "Input": "0123456789.underscore_dash-Tilda~" - }, - "expect": { - "error": "The value is: `0123456789.underscore_dash-Tilda~`" - } - }, + documentation: "uriEncode with ASCII characters that should not be encoded returns the input" + params: { TestCaseId: "1", Input: "0123456789.underscore_dash-Tilda~" } + expect: { error: "The value is: `0123456789.underscore_dash-Tilda~`" } + } { - "documentation": "uriEncode encodes unicode characters", - "params": { - "TestCaseId": "1", - "Input": "\ud83d\ude39" - }, - "expect": { - "error": "The value is: `%F0%9F%98%B9`" - } - }, + documentation: "uriEncode encodes unicode characters" + params: { TestCaseId: "1", Input: "\ud83d\ude39" } + expect: { error: "The value is: `%F0%9F%98%B9`" } + } { - "documentation": "uriEncode on all printable ASCII characters", - "params": { - "TestCaseId": "1", - "Input": " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" - }, - "expect": { - "error": "The value is: `%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~`" + documentation: "uriEncode on all printable ASCII characters" + params: { + TestCaseId: "1" + Input: " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" } - }, - { - "documentation": "uriEncode on an empty string", - "params": { - "TestCaseId": "1", - "Input": "" - }, - "expect": { - "error": "The value is: ``" + expect: { + error: "The value is: `%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~`" } } + { + documentation: "uriEncode on an empty string" + params: { TestCaseId: "1", Input: "" } + expect: { error: "The value is: ``" } + } ] ) @clientContextParams( - TestCaseId: {type: "string", documentation: "Test case id used to select the test case to use"}, - Input: {type: "string", documentation: "The input used to test uriEncoder"} + TestCaseId: { type: "string", documentation: "Test case id used to select the test case to use" } + Input: { type: "string", documentation: "The input used to test uriEncoder" } ) service UrlEncodeService {} diff --git a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/valid-hostlabel.smithy b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/valid-hostlabel.smithy index c6e8a7fe152..15e1dd532d5 100644 --- a/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/valid-hostlabel.smithy +++ b/smithy-rules-engine-tests/src/main/resources/META-INF/smithy/valid-hostlabel.smithy @@ -8,143 +8,103 @@ use smithy.rules#endpointTests @suppress(["UnstableTrait"]) @endpointRuleSet({ - "version": "1.0", - "parameters": { - "Region": { - "type": "string", - "required": true, - "documentation": "The region to dispatch this request, eg. `us-east-1`." - } - }, - "rules": [ + version: "1.0" + parameters: { + Region: { type: "string", required: true, documentation: "The region to dispatch this request, eg. `us-east-1`." } + } + rules: [ { - "documentation": "Template the region into the URI when region is set", - "conditions": [ + documentation: "Template the region into the URI when region is set" + conditions: [ { - "fn": "isValidHostLabel", - "argv": [ + fn: "isValidHostLabel" + argv: [ { - "ref": "Region" - }, + ref: "Region" + } false ] } - ], - "endpoint": { - "url": "https://{Region}.amazonaws.com" - }, - "type": "endpoint" - }, + ] + endpoint: { url: "https://{Region}.amazonaws.com" } + type: "endpoint" + } { - "documentation": "Template the region into the URI when region is set", - "conditions": [ + documentation: "Template the region into the URI when region is set" + conditions: [ { - "fn": "isValidHostLabel", - "argv": [ + fn: "isValidHostLabel" + argv: [ { - "ref": "Region" - }, + ref: "Region" + } true ] } - ], - "endpoint": { - "url": "https://{Region}-subdomains.amazonaws.com" - }, - "type": "endpoint" - }, + ] + endpoint: { url: "https://{Region}-subdomains.amazonaws.com" } + type: "endpoint" + } { - "documentation": "Region was not a valid host label", - "conditions": [], - "error": "Invalid hostlabel", - "type": "error" + documentation: "Region was not a valid host label" + conditions: [] + error: "Invalid hostlabel" + type: "error" } ] }) @endpointTests( - version: "1.0", + version: "1.0" testCases: [ { - "documentation": "standard region is a valid hostlabel", - "params": { - "Region": "us-east-1" - }, - "expect": { - "endpoint": { - "url": "https://us-east-1.amazonaws.com" - } + documentation: "standard region is a valid hostlabel" + params: { Region: "us-east-1" } + expect: { + endpoint: { url: "https://us-east-1.amazonaws.com" } } - }, + } { - "documentation": "starting with a number is a valid hostlabel", - "params": { - "Region": "3aws4" - }, - "expect": { - "endpoint": { - "url": "https://3aws4.amazonaws.com" - } + documentation: "starting with a number is a valid hostlabel" + params: { Region: "3aws4" } + expect: { + endpoint: { url: "https://3aws4.amazonaws.com" } } - }, + } { - "documentation": "when there are dots, only match if subdomains are allowed", - "params": { - "Region": "part1.part2" - }, - "expect": { - "endpoint": { - "url": "https://part1.part2-subdomains.amazonaws.com" - } + documentation: "when there are dots, only match if subdomains are allowed" + params: { Region: "part1.part2" } + expect: { + endpoint: { url: "https://part1.part2-subdomains.amazonaws.com" } } - }, + } { - "documentation": "a space is never a valid hostlabel", - "params": { - "Region": "part1 part2" - }, - "expect": { - "error": "Invalid hostlabel" - } - }, + documentation: "a space is never a valid hostlabel" + params: { Region: "part1 part2" } + expect: { error: "Invalid hostlabel" } + } { - "documentation": "an empty string is not a valid hostlabel", - "params": { - "Region": "" - }, - "expect": { - "error": "Invalid hostlabel" - } - }, + documentation: "an empty string is not a valid hostlabel" + params: { Region: "" } + expect: { error: "Invalid hostlabel" } + } { - "documentation": "ending with a dot is not a valid hostlabel", - "params": { - "Region": "part1." - }, - "expect": { - "error": "Invalid hostlabel" - } - }, + documentation: "ending with a dot is not a valid hostlabel" + params: { Region: "part1." } + expect: { error: "Invalid hostlabel" } + } { - "documentation": "multiple consecutive dots are not allowed", - "params": { - "Region": "part1..part2" - }, - "expect": { - "error": "Invalid hostlabel" - } - }, + documentation: "multiple consecutive dots are not allowed" + params: { Region: "part1..part2" } + expect: { error: "Invalid hostlabel" } + } { - "documentation": "labels cannot start with a dash", - "params": { - "Region": "part1.-part2" - }, - "expect": { - "error": "Invalid hostlabel" - } + documentation: "labels cannot start with a dash" + params: { Region: "part1.-part2" } + expect: { error: "Invalid hostlabel" } } ] ) @clientContextParams( - Region: {type: "string", documentation: "docs"} + Region: { type: "string", documentation: "docs" } ) service ValidHostLabelService {}