From 8ef81a9b388fbcad50734a575d2616a31c25e2a6 Mon Sep 17 00:00:00 2001 From: Rickard Andersson Date: Tue, 11 Oct 2022 23:08:21 +0300 Subject: [PATCH 1/8] testing(ts): add test for `basicStruct` --- gotyno-hs.cabal | 1 + test/ParsingSpec.hs | 24 +++++++++++++++++++++--- test/reference-output/basicStruct.ts | 14 ++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 test/reference-output/basicStruct.ts diff --git a/gotyno-hs.cabal b/gotyno-hs.cabal index 619ec1f..14e9d60 100644 --- a/gotyno-hs.cabal +++ b/gotyno-hs.cabal @@ -31,6 +31,7 @@ extra-source-files: examples/python.gotyno test/reference-output/arrayOfArraysOfNullableStrings.ts test/reference-output/basic.ts + test/reference-output/basicStruct.ts test/reference-output/external.ts test/reference-output/generics.ts test/reference-output/github.ts diff --git a/test/ParsingSpec.hs b/test/ParsingSpec.hs index dbfb593..95ea5af 100644 --- a/test/ParsingSpec.hs +++ b/test/ParsingSpec.hs @@ -12,8 +12,16 @@ import qualified RIO.List.Partial as PartialList import Test.Hspec import Types +-- { basicStruct :: !Text, +-- basicUnion :: !Text, +-- genericStruct :: !Text, +-- genericUnion :: !Text, +-- basicEnumeration :: !Text, +-- basicImport :: !Text, +-- basicOptional :: !Text, data TypeScriptReferenceOutput = TypeScriptReferenceOutput - { basic :: !Text, + { basicStruct :: !Text, + basic :: !Text, import' :: !Text, hasGeneric :: !Text, generics :: !Text, @@ -66,12 +74,21 @@ data DLangReferenceOutput = DLangReferenceOutput typeScriptReferenceOutput :: IO TypeScriptReferenceOutput typeScriptReferenceOutput = do + basicStruct <- basicStructReferenceOutput "ts" basic <- basicReferenceOutput "ts" import' <- importReferenceOutput "ts" hasGeneric <- hasGenericReferenceOutput "ts" generics <- genericsReferenceOutput "ts" gitHub <- gitHubReferenceOutput "ts" - pure TypeScriptReferenceOutput {basic, import', hasGeneric, generics, gitHub} + pure + TypeScriptReferenceOutput + { basicStruct, + basic, + import', + hasGeneric, + generics, + gitHub + } haskellReferenceOutput :: IO HaskellReferenceOutput haskellReferenceOutput = do @@ -191,7 +208,7 @@ spec :: DLangReferenceOutput -> Spec spec - (TypeScriptReferenceOutput tsBasic tsImport tsHasGeneric tsGenerics tsGitHub) + (TypeScriptReferenceOutput tsBasicStruct tsBasic tsImport tsHasGeneric tsGenerics tsGitHub) (HaskellReferenceOutput hsBasic hsImport hsHasGeneric hsGenerics hsGitHub) (FSharpReferenceOutput fsBasic fsImport fsHasGeneric fsGenerics fsGitHub) (PythonReferenceOutput pyPython pyBasic pyGenerics) @@ -513,6 +530,7 @@ spec it "Mirrors reference output for `basicStruct.gotyno`" $ do basicStructModule <- (getRight >>> PartialList.head) <$> parseModules ["examples/basicStruct.gotyno"] + TypeScript.outputModule basicStructModule `shouldBe` tsBasicStruct DLang.outputModule basicStructModule `shouldBe` dBasicStruct it "Mirrors reference output for `basicUnion.gotyno`" $ do diff --git a/test/reference-output/basicStruct.ts b/test/reference-output/basicStruct.ts new file mode 100644 index 0000000..51954fd --- /dev/null +++ b/test/reference-output/basicStruct.ts @@ -0,0 +1,14 @@ +import * as svt from "simple-validation-tools"; + +export type BasicStruct = { + field1: number; + field2: string; +}; + +export function isBasicStruct(value: unknown): value is BasicStruct { + return svt.isInterface(value, {field1: svt.isNumber, field2: svt.isString}); +} + +export function validateBasicStruct(value: unknown): svt.ValidationResult { + return svt.validate(value, {field1: svt.validateNumber, field2: svt.validateString}); +} From 3392b5a60ed1cc0e01941974aec6dc6ffc9a2f64 Mon Sep 17 00:00:00 2001 From: Rickard Andersson Date: Tue, 11 Oct 2022 23:20:23 +0300 Subject: [PATCH 2/8] testing(ts): add test for `basicUnion` --- gotyno-hs.cabal | 1 + test/ParsingSpec.hs | 14 ++++- test/reference-output/basicUnion.ts | 79 +++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 test/reference-output/basicUnion.ts diff --git a/gotyno-hs.cabal b/gotyno-hs.cabal index 14e9d60..9601dc7 100644 --- a/gotyno-hs.cabal +++ b/gotyno-hs.cabal @@ -32,6 +32,7 @@ extra-source-files: test/reference-output/arrayOfArraysOfNullableStrings.ts test/reference-output/basic.ts test/reference-output/basicStruct.ts + test/reference-output/basicUnion.ts test/reference-output/external.ts test/reference-output/generics.ts test/reference-output/github.ts diff --git a/test/ParsingSpec.hs b/test/ParsingSpec.hs index 95ea5af..5abae9d 100644 --- a/test/ParsingSpec.hs +++ b/test/ParsingSpec.hs @@ -21,6 +21,7 @@ import Types -- basicOptional :: !Text, data TypeScriptReferenceOutput = TypeScriptReferenceOutput { basicStruct :: !Text, + basicUnion :: !Text, basic :: !Text, import' :: !Text, hasGeneric :: !Text, @@ -75,6 +76,7 @@ data DLangReferenceOutput = DLangReferenceOutput typeScriptReferenceOutput :: IO TypeScriptReferenceOutput typeScriptReferenceOutput = do basicStruct <- basicStructReferenceOutput "ts" + basicUnion <- basicUnionReferenceOutput "ts" basic <- basicReferenceOutput "ts" import' <- importReferenceOutput "ts" hasGeneric <- hasGenericReferenceOutput "ts" @@ -83,6 +85,7 @@ typeScriptReferenceOutput = do pure TypeScriptReferenceOutput { basicStruct, + basicUnion, basic, import', hasGeneric, @@ -208,7 +211,15 @@ spec :: DLangReferenceOutput -> Spec spec - (TypeScriptReferenceOutput tsBasicStruct tsBasic tsImport tsHasGeneric tsGenerics tsGitHub) + ( TypeScriptReferenceOutput + tsBasicStruct + tsBasicUnion + tsBasic + tsImport + tsHasGeneric + tsGenerics + tsGitHub + ) (HaskellReferenceOutput hsBasic hsImport hsHasGeneric hsGenerics hsGitHub) (FSharpReferenceOutput fsBasic fsImport fsHasGeneric fsGenerics fsGitHub) (PythonReferenceOutput pyPython pyBasic pyGenerics) @@ -536,6 +547,7 @@ spec it "Mirrors reference output for `basicUnion.gotyno`" $ do basicUnionModule <- (getRight >>> PartialList.head) <$> parseModules ["examples/basicUnion.gotyno"] + TypeScript.outputModule basicUnionModule `shouldBe` tsBasicUnion DLang.outputModule basicUnionModule `shouldBe` dBasicUnion it "Mirrors reference output for `genericStruct.gotyno`" $ do diff --git a/test/reference-output/basicUnion.ts b/test/reference-output/basicUnion.ts new file mode 100644 index 0000000..73c4038 --- /dev/null +++ b/test/reference-output/basicUnion.ts @@ -0,0 +1,79 @@ +import * as svt from "simple-validation-tools"; + +export type PayloadStruct = { + field1: number; +}; + +export function isPayloadStruct(value: unknown): value is PayloadStruct { + return svt.isInterface(value, {field1: svt.isNumber}); +} + +export function validatePayloadStruct(value: unknown): svt.ValidationResult { + return svt.validate(value, {field1: svt.validateNumber}); +} + +export type BasicUnion = HasStringPayload | HasPayload | HasNoPayload; + +export enum BasicUnionTag { + HasStringPayload = "HasStringPayload", + HasPayload = "HasPayload", + HasNoPayload = "HasNoPayload", +} + +export type HasStringPayload = { + type: BasicUnionTag.HasStringPayload; + data: string; +}; + +export type HasPayload = { + type: BasicUnionTag.HasPayload; + data: PayloadStruct; +}; + +export type HasNoPayload = { + type: BasicUnionTag.HasNoPayload; +}; + +export function HasStringPayload(data: string): HasStringPayload { + return {type: BasicUnionTag.HasStringPayload, data}; +} + +export function HasPayload(data: PayloadStruct): HasPayload { + return {type: BasicUnionTag.HasPayload, data}; +} + +export function HasNoPayload(): HasNoPayload { + return {type: BasicUnionTag.HasNoPayload}; +} + +export function isBasicUnion(value: unknown): value is BasicUnion { + return [isHasStringPayload, isHasPayload, isHasNoPayload].some((typePredicate) => typePredicate(value)); +} + +export function isHasStringPayload(value: unknown): value is HasStringPayload { + return svt.isInterface(value, {type: BasicUnionTag.HasStringPayload, data: svt.isString}); +} + +export function isHasPayload(value: unknown): value is HasPayload { + return svt.isInterface(value, {type: BasicUnionTag.HasPayload, data: isPayloadStruct}); +} + +export function isHasNoPayload(value: unknown): value is HasNoPayload { + return svt.isInterface(value, {type: BasicUnionTag.HasNoPayload}); +} + +export function validateBasicUnion(value: unknown): svt.ValidationResult { + return svt.validateWithTypeTag(value, {[BasicUnionTag.HasStringPayload]: validateHasStringPayload, [BasicUnionTag.HasPayload]: validateHasPayload, [BasicUnionTag.HasNoPayload]: validateHasNoPayload}, "type"); +} + +export function validateHasStringPayload(value: unknown): svt.ValidationResult { + return svt.validate(value, {type: BasicUnionTag.HasStringPayload, data: svt.validateString}); +} + +export function validateHasPayload(value: unknown): svt.ValidationResult { + return svt.validate(value, {type: BasicUnionTag.HasPayload, data: validatePayloadStruct}); +} + +export function validateHasNoPayload(value: unknown): svt.ValidationResult { + return svt.validate(value, {type: BasicUnionTag.HasNoPayload}); +} From 34fd935ddc25411cf1d639583b207d1d88d5f59c Mon Sep 17 00:00:00 2001 From: Rickard Andersson Date: Wed, 12 Oct 2022 20:49:30 +0300 Subject: [PATCH 3/8] testing(ts): add test for `genericStruct` --- gotyno-hs.cabal | 1 + test/ParsingSpec.hs | 5 +++++ test/reference-output/genericStruct.ts | 17 +++++++++++++++++ 3 files changed, 23 insertions(+) create mode 100644 test/reference-output/genericStruct.ts diff --git a/gotyno-hs.cabal b/gotyno-hs.cabal index 9601dc7..640bc62 100644 --- a/gotyno-hs.cabal +++ b/gotyno-hs.cabal @@ -35,6 +35,7 @@ extra-source-files: test/reference-output/basicUnion.ts test/reference-output/external.ts test/reference-output/generics.ts + test/reference-output/genericStruct.ts test/reference-output/github.ts test/reference-output/hasGeneric.ts test/reference-output/importExample.ts diff --git a/test/ParsingSpec.hs b/test/ParsingSpec.hs index 5abae9d..d1522a5 100644 --- a/test/ParsingSpec.hs +++ b/test/ParsingSpec.hs @@ -22,6 +22,7 @@ import Types data TypeScriptReferenceOutput = TypeScriptReferenceOutput { basicStruct :: !Text, basicUnion :: !Text, + genericStruct :: !Text, basic :: !Text, import' :: !Text, hasGeneric :: !Text, @@ -77,6 +78,7 @@ typeScriptReferenceOutput :: IO TypeScriptReferenceOutput typeScriptReferenceOutput = do basicStruct <- basicStructReferenceOutput "ts" basicUnion <- basicUnionReferenceOutput "ts" + genericStruct <- genericStructReferenceOutput "ts" basic <- basicReferenceOutput "ts" import' <- importReferenceOutput "ts" hasGeneric <- hasGenericReferenceOutput "ts" @@ -86,6 +88,7 @@ typeScriptReferenceOutput = do TypeScriptReferenceOutput { basicStruct, basicUnion, + genericStruct, basic, import', hasGeneric, @@ -214,6 +217,7 @@ spec ( TypeScriptReferenceOutput tsBasicStruct tsBasicUnion + tsGenericStruct tsBasic tsImport tsHasGeneric @@ -553,6 +557,7 @@ spec it "Mirrors reference output for `genericStruct.gotyno`" $ do genericStructModule <- (getRight >>> PartialList.head) <$> parseModules ["examples/genericStruct.gotyno"] + TypeScript.outputModule genericStructModule `shouldBe` tsGenericStruct DLang.outputModule genericStructModule `shouldBe` dGenericStruct it "Mirrors reference output for `genericUnion.gotyno`" $ do diff --git a/test/reference-output/genericStruct.ts b/test/reference-output/genericStruct.ts new file mode 100644 index 0000000..26d492c --- /dev/null +++ b/test/reference-output/genericStruct.ts @@ -0,0 +1,17 @@ +import * as svt from "simple-validation-tools"; + +export type GenericStruct = { + field: T; +}; + +export function isGenericStruct(isT: svt.TypePredicate): svt.TypePredicate> { + return function isGenericStructT(value: unknown): value is GenericStruct { + return svt.isInterface>(value, {field: isT}); + }; +} + +export function validateGenericStruct(validateT: svt.Validator): svt.Validator> { + return function validateGenericStructT(value: unknown): svt.ValidationResult> { + return svt.validate>(value, {field: validateT}); + }; +} From 352f87a750435413f09f636861e32bd04efa7cc8 Mon Sep 17 00:00:00 2001 From: Rickard Andersson Date: Wed, 12 Oct 2022 20:57:28 +0300 Subject: [PATCH 4/8] testing(ts): add test for `genericUnion` --- gotyno-hs.cabal | 1 + test/ParsingSpec.hs | 5 +++ test/reference-output/genericUnion.ts | 57 +++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 test/reference-output/genericUnion.ts diff --git a/gotyno-hs.cabal b/gotyno-hs.cabal index 640bc62..1c98b31 100644 --- a/gotyno-hs.cabal +++ b/gotyno-hs.cabal @@ -36,6 +36,7 @@ extra-source-files: test/reference-output/external.ts test/reference-output/generics.ts test/reference-output/genericStruct.ts + test/reference-output/genericUnion.ts test/reference-output/github.ts test/reference-output/hasGeneric.ts test/reference-output/importExample.ts diff --git a/test/ParsingSpec.hs b/test/ParsingSpec.hs index d1522a5..189ba6f 100644 --- a/test/ParsingSpec.hs +++ b/test/ParsingSpec.hs @@ -23,6 +23,7 @@ data TypeScriptReferenceOutput = TypeScriptReferenceOutput { basicStruct :: !Text, basicUnion :: !Text, genericStruct :: !Text, + genericUnion :: !Text, basic :: !Text, import' :: !Text, hasGeneric :: !Text, @@ -79,6 +80,7 @@ typeScriptReferenceOutput = do basicStruct <- basicStructReferenceOutput "ts" basicUnion <- basicUnionReferenceOutput "ts" genericStruct <- genericStructReferenceOutput "ts" + genericUnion <- genericUnionReferenceOutput "ts" basic <- basicReferenceOutput "ts" import' <- importReferenceOutput "ts" hasGeneric <- hasGenericReferenceOutput "ts" @@ -89,6 +91,7 @@ typeScriptReferenceOutput = do { basicStruct, basicUnion, genericStruct, + genericUnion, basic, import', hasGeneric, @@ -218,6 +221,7 @@ spec tsBasicStruct tsBasicUnion tsGenericStruct + tsGenericUnion tsBasic tsImport tsHasGeneric @@ -563,6 +567,7 @@ spec it "Mirrors reference output for `genericUnion.gotyno`" $ do genericUnionModule <- (getRight >>> PartialList.head) <$> parseModules ["examples/genericUnion.gotyno"] + TypeScript.outputModule genericUnionModule `shouldBe` tsGenericUnion DLang.outputModule genericUnionModule `shouldBe` dGenericUnion it "Mirrors reference output for `basicEnumeration.gotyno`" $ do diff --git a/test/reference-output/genericUnion.ts b/test/reference-output/genericUnion.ts new file mode 100644 index 0000000..9f9adfd --- /dev/null +++ b/test/reference-output/genericUnion.ts @@ -0,0 +1,57 @@ +import * as svt from "simple-validation-tools"; + +export type GenericUnion = HasTPayload | HasNoPayload; + +export enum GenericUnionTag { + HasTPayload = "HasTPayload", + HasNoPayload = "HasNoPayload", +} + +export type HasTPayload = { + type: GenericUnionTag.HasTPayload; + data: T; +}; + +export type HasNoPayload = { + type: GenericUnionTag.HasNoPayload; +}; + +export function HasTPayload(data: T): HasTPayload { + return {type: GenericUnionTag.HasTPayload, data}; +} + +export function HasNoPayload(): HasNoPayload { + return {type: GenericUnionTag.HasNoPayload}; +} + +export function isGenericUnion(isT: svt.TypePredicate): svt.TypePredicate> { + return function isGenericUnionT(value: unknown): value is GenericUnion { + return [isHasTPayload(isT), isHasNoPayload].some((typePredicate) => typePredicate(value)); + }; +} + +export function isHasTPayload(isT: svt.TypePredicate): svt.TypePredicate> { + return function isHasTPayloadT(value: unknown): value is HasTPayload { + return svt.isInterface>(value, {type: GenericUnionTag.HasTPayload, data: isT}); + }; +} + +export function isHasNoPayload(value: unknown): value is HasNoPayload { + return svt.isInterface(value, {type: GenericUnionTag.HasNoPayload}); +} + +export function validateGenericUnion(validateT: svt.Validator): svt.Validator> { + return function validateGenericUnionT(value: unknown): svt.ValidationResult> { + return svt.validateWithTypeTag>(value, {[GenericUnionTag.HasTPayload]: validateHasTPayload(validateT), [GenericUnionTag.HasNoPayload]: validateHasNoPayload}, "type"); + }; +} + +export function validateHasTPayload(validateT: svt.Validator): svt.Validator> { + return function validateHasTPayloadT(value: unknown): svt.ValidationResult> { + return svt.validate>(value, {type: GenericUnionTag.HasTPayload, data: validateT}); + }; +} + +export function validateHasNoPayload(value: unknown): svt.ValidationResult { + return svt.validate(value, {type: GenericUnionTag.HasNoPayload}); +} From 79c403a217d0a2bffa9462baac7565f6c9ae8ace Mon Sep 17 00:00:00 2001 From: Rickard Andersson Date: Thu, 13 Oct 2022 23:50:24 +0300 Subject: [PATCH 5/8] testing(ts): add `basicEnumeration` --- gotyno-hs.cabal | 1 + test/ParsingSpec.hs | 5 ++++ test/reference-output/basicEnumeration.ts | 31 +++++++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 test/reference-output/basicEnumeration.ts diff --git a/gotyno-hs.cabal b/gotyno-hs.cabal index 1c98b31..9186ffb 100644 --- a/gotyno-hs.cabal +++ b/gotyno-hs.cabal @@ -31,6 +31,7 @@ extra-source-files: examples/python.gotyno test/reference-output/arrayOfArraysOfNullableStrings.ts test/reference-output/basic.ts + test/reference-output/basicEnumeration.ts test/reference-output/basicStruct.ts test/reference-output/basicUnion.ts test/reference-output/external.ts diff --git a/test/ParsingSpec.hs b/test/ParsingSpec.hs index 189ba6f..a7be0f3 100644 --- a/test/ParsingSpec.hs +++ b/test/ParsingSpec.hs @@ -24,6 +24,7 @@ data TypeScriptReferenceOutput = TypeScriptReferenceOutput basicUnion :: !Text, genericStruct :: !Text, genericUnion :: !Text, + basicEnumeration :: !Text, basic :: !Text, import' :: !Text, hasGeneric :: !Text, @@ -81,6 +82,7 @@ typeScriptReferenceOutput = do basicUnion <- basicUnionReferenceOutput "ts" genericStruct <- genericStructReferenceOutput "ts" genericUnion <- genericUnionReferenceOutput "ts" + basicEnumeration <- basicEnumerationReferenceOutput "ts" basic <- basicReferenceOutput "ts" import' <- importReferenceOutput "ts" hasGeneric <- hasGenericReferenceOutput "ts" @@ -92,6 +94,7 @@ typeScriptReferenceOutput = do basicUnion, genericStruct, genericUnion, + basicEnumeration, basic, import', hasGeneric, @@ -222,6 +225,7 @@ spec tsBasicUnion tsGenericStruct tsGenericUnion + tsBasicEnumeration tsBasic tsImport tsHasGeneric @@ -573,6 +577,7 @@ spec it "Mirrors reference output for `basicEnumeration.gotyno`" $ do enumerationModule <- (getRight >>> PartialList.head) <$> parseModules ["examples/basicEnumeration.gotyno"] + TypeScript.outputModule enumerationModule `shouldBe` tsBasicEnumeration DLang.outputModule enumerationModule `shouldBe` dBasicEnumeration it "Mirrors reference output for `basicImport.gotyno`" $ do diff --git a/test/reference-output/basicEnumeration.ts b/test/reference-output/basicEnumeration.ts new file mode 100644 index 0000000..baa7a19 --- /dev/null +++ b/test/reference-output/basicEnumeration.ts @@ -0,0 +1,31 @@ +import * as svt from "simple-validation-tools"; + +export enum StringValues { + first = "first", + second = "second", + third = "Third", + fourth = "Fourth", +} + +export function isStringValues(value: unknown): value is StringValues { + return [StringValues.first, StringValues.second, StringValues.third, StringValues.fourth].some((v) => v === value); +} + +export function validateStringValues(value: unknown): svt.ValidationResult { + return svt.validateOneOfLiterals(value, [StringValues.first, StringValues.second, StringValues.third, StringValues.fourth]); +} + +export enum IntValues { + first = 1, + second = 2, + third = 3, + fourth = 4, +} + +export function isIntValues(value: unknown): value is IntValues { + return [IntValues.first, IntValues.second, IntValues.third, IntValues.fourth].some((v) => v === value); +} + +export function validateIntValues(value: unknown): svt.ValidationResult { + return svt.validateOneOfLiterals(value, [IntValues.first, IntValues.second, IntValues.third, IntValues.fourth]); +} From 52c1de932f19452259286badf516099f0706a48a Mon Sep 17 00:00:00 2001 From: Rickard Andersson Date: Fri, 14 Oct 2022 00:10:09 +0300 Subject: [PATCH 6/8] testing(ts): add `basicImport` --- gotyno-hs.cabal | 1 + test/ParsingSpec.hs | 5 +++ test/reference-output/basicImport.ts | 46 ++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 test/reference-output/basicImport.ts diff --git a/gotyno-hs.cabal b/gotyno-hs.cabal index 9186ffb..709555d 100644 --- a/gotyno-hs.cabal +++ b/gotyno-hs.cabal @@ -32,6 +32,7 @@ extra-source-files: test/reference-output/arrayOfArraysOfNullableStrings.ts test/reference-output/basic.ts test/reference-output/basicEnumeration.ts + test/reference-output/basicImport.ts test/reference-output/basicStruct.ts test/reference-output/basicUnion.ts test/reference-output/external.ts diff --git a/test/ParsingSpec.hs b/test/ParsingSpec.hs index a7be0f3..939d1de 100644 --- a/test/ParsingSpec.hs +++ b/test/ParsingSpec.hs @@ -25,6 +25,7 @@ data TypeScriptReferenceOutput = TypeScriptReferenceOutput genericStruct :: !Text, genericUnion :: !Text, basicEnumeration :: !Text, + basicImport :: !Text, basic :: !Text, import' :: !Text, hasGeneric :: !Text, @@ -83,6 +84,7 @@ typeScriptReferenceOutput = do genericStruct <- genericStructReferenceOutput "ts" genericUnion <- genericUnionReferenceOutput "ts" basicEnumeration <- basicEnumerationReferenceOutput "ts" + basicImport <- basicImportReferenceOutput "ts" basic <- basicReferenceOutput "ts" import' <- importReferenceOutput "ts" hasGeneric <- hasGenericReferenceOutput "ts" @@ -95,6 +97,7 @@ typeScriptReferenceOutput = do genericStruct, genericUnion, basicEnumeration, + basicImport, basic, import', hasGeneric, @@ -226,6 +229,7 @@ spec tsGenericStruct tsGenericUnion tsBasicEnumeration + tsBasicImport tsBasic tsImport tsHasGeneric @@ -584,6 +588,7 @@ spec basicImportModule <- (getRight >>> PartialList.last) <$> parseModules ["examples/basicStruct.gotyno", "examples/basicImport.gotyno"] + TypeScript.outputModule basicImportModule `shouldBe` tsBasicImport DLang.outputModule basicImportModule `shouldBe` dBasicImport it "Mirrors reference output for `basicOptional.gotyno`" $ do diff --git a/test/reference-output/basicImport.ts b/test/reference-output/basicImport.ts new file mode 100644 index 0000000..985d00f --- /dev/null +++ b/test/reference-output/basicImport.ts @@ -0,0 +1,46 @@ +import * as svt from "simple-validation-tools"; + +import * as basicStruct from "./basicStruct"; + +export type StructUsingImport = { + field: basicStruct.BasicStruct; +}; + +export function isStructUsingImport(value: unknown): value is StructUsingImport { + return svt.isInterface(value, {field: basicStruct.isBasicStruct}); +} + +export function validateStructUsingImport(value: unknown): svt.ValidationResult { + return svt.validate(value, {field: basicStruct.validateBasicStruct}); +} + +export type UnionUsingImport = ConstructorWithPayload; + +export enum UnionUsingImportTag { + ConstructorWithPayload = "ConstructorWithPayload", +} + +export type ConstructorWithPayload = { + type: UnionUsingImportTag.ConstructorWithPayload; + data: basicStruct.BasicStruct; +}; + +export function ConstructorWithPayload(data: basicStruct.BasicStruct): ConstructorWithPayload { + return {type: UnionUsingImportTag.ConstructorWithPayload, data}; +} + +export function isUnionUsingImport(value: unknown): value is UnionUsingImport { + return [isConstructorWithPayload].some((typePredicate) => typePredicate(value)); +} + +export function isConstructorWithPayload(value: unknown): value is ConstructorWithPayload { + return svt.isInterface(value, {type: UnionUsingImportTag.ConstructorWithPayload, data: basicStruct.isBasicStruct}); +} + +export function validateUnionUsingImport(value: unknown): svt.ValidationResult { + return svt.validateWithTypeTag(value, {[UnionUsingImportTag.ConstructorWithPayload]: validateConstructorWithPayload}, "type"); +} + +export function validateConstructorWithPayload(value: unknown): svt.ValidationResult { + return svt.validate(value, {type: UnionUsingImportTag.ConstructorWithPayload, data: basicStruct.validateBasicStruct}); +} From 3fad42c5546f30cd807423c455108bab8c274401 Mon Sep 17 00:00:00 2001 From: Rickard Andersson Date: Fri, 14 Oct 2022 00:38:18 +0300 Subject: [PATCH 7/8] fix(ts): fix output for optional constructor arguments --- gotyno-hs.cabal | 1 + src/CodeGeneration/TypeScript.hs | 9 ++- test/ParsingSpec.hs | 12 ++-- test/reference-output/basicOptional.ts | 82 ++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 9 deletions(-) create mode 100644 test/reference-output/basicOptional.ts diff --git a/gotyno-hs.cabal b/gotyno-hs.cabal index 709555d..8cd18a0 100644 --- a/gotyno-hs.cabal +++ b/gotyno-hs.cabal @@ -33,6 +33,7 @@ extra-source-files: test/reference-output/basic.ts test/reference-output/basicEnumeration.ts test/reference-output/basicImport.ts + test/reference-output/basicOptional.ts test/reference-output/basicStruct.ts test/reference-output/basicUnion.ts test/reference-output/external.ts diff --git a/src/CodeGeneration/TypeScript.hs b/src/CodeGeneration/TypeScript.hs index 007361a..332a805 100644 --- a/src/CodeGeneration/TypeScript.hs +++ b/src/CodeGeneration/TypeScript.hs @@ -1038,7 +1038,10 @@ outputCaseType unionName (FieldName tag) (Constructor (ConstructorName name) maybePayload) = - let payloadLine = maybe "" (\p -> " data: " <> outputFieldType p <> ";\n") maybePayload + let payloadLine = maybe "" outputDataField maybePayload + outputDataField (ComplexType (OptionalType t)) = + mconcat [" data?: ", outputFieldType t, ";\n"] + outputDataField t = mconcat [" data: ", outputFieldType t, ";\n"] maybeTypeVariables = maybe "" (typeVariablesFrom >>> maybeJoinTypeVariables) maybePayload in mconcat [ mconcat ["export type ", upperCaseFirst name, maybeTypeVariables, " = {\n"], @@ -1058,7 +1061,9 @@ outputCaseConstructor unionName (FieldName tag) (Constructor (ConstructorName name) maybePayload) = - let argumentFieldAndType = maybe "" (\p -> "data: " <> outputFieldType p) maybePayload + let argumentFieldAndType = maybe "" outputDataParameter maybePayload + outputDataParameter (ComplexType (OptionalType t)) = mconcat ["data?: ", outputFieldType t] + outputDataParameter t = mconcat ["data: ", outputFieldType t] maybeTypeVariables = maybe "" joinTypeVariables (maybePayload >>= typeVariablesFrom) in mconcat [ mconcat diff --git a/test/ParsingSpec.hs b/test/ParsingSpec.hs index 939d1de..c64e837 100644 --- a/test/ParsingSpec.hs +++ b/test/ParsingSpec.hs @@ -12,13 +12,6 @@ import qualified RIO.List.Partial as PartialList import Test.Hspec import Types --- { basicStruct :: !Text, --- basicUnion :: !Text, --- genericStruct :: !Text, --- genericUnion :: !Text, --- basicEnumeration :: !Text, --- basicImport :: !Text, --- basicOptional :: !Text, data TypeScriptReferenceOutput = TypeScriptReferenceOutput { basicStruct :: !Text, basicUnion :: !Text, @@ -26,6 +19,7 @@ data TypeScriptReferenceOutput = TypeScriptReferenceOutput genericUnion :: !Text, basicEnumeration :: !Text, basicImport :: !Text, + basicOptional :: !Text, basic :: !Text, import' :: !Text, hasGeneric :: !Text, @@ -85,6 +79,7 @@ typeScriptReferenceOutput = do genericUnion <- genericUnionReferenceOutput "ts" basicEnumeration <- basicEnumerationReferenceOutput "ts" basicImport <- basicImportReferenceOutput "ts" + basicOptional <- basicOptionalReferenceOutput "ts" basic <- basicReferenceOutput "ts" import' <- importReferenceOutput "ts" hasGeneric <- hasGenericReferenceOutput "ts" @@ -98,6 +93,7 @@ typeScriptReferenceOutput = do genericUnion, basicEnumeration, basicImport, + basicOptional, basic, import', hasGeneric, @@ -230,6 +226,7 @@ spec tsGenericUnion tsBasicEnumeration tsBasicImport + tsBasicOptional tsBasic tsImport tsHasGeneric @@ -594,6 +591,7 @@ spec it "Mirrors reference output for `basicOptional.gotyno`" $ do basicOptionalModule <- (getRight >>> PartialList.head) <$> parseModules ["examples/basicOptional.gotyno"] + TypeScript.outputModule basicOptionalModule `shouldBe` tsBasicOptional DLang.outputModule basicOptionalModule `shouldBe` dBasicOptional it "Mirrors reference output for `basic.gotyno`" $ do diff --git a/test/reference-output/basicOptional.ts b/test/reference-output/basicOptional.ts new file mode 100644 index 0000000..698ad13 --- /dev/null +++ b/test/reference-output/basicOptional.ts @@ -0,0 +1,82 @@ +import * as svt from "simple-validation-tools"; + +export type HasOptionalString = { + stringField?: string; + optionalArrayField?: number[]; + arrayOfOptionalField: (number | null | undefined)[]; +}; + +export function isHasOptionalString(value: unknown): value is HasOptionalString { + return svt.isInterface(value, {stringField: svt.optional(svt.isString), optionalArrayField: svt.optional(svt.arrayOf(svt.isNumber)), arrayOfOptionalField: svt.arrayOf(svt.optional(svt.isNumber))}); +} + +export function validateHasOptionalString(value: unknown): svt.ValidationResult { + return svt.validate(value, {stringField: svt.validateOptional(svt.validateString), optionalArrayField: svt.validateOptional(svt.validateArray(svt.validateNumber)), arrayOfOptionalField: svt.validateArray(svt.validateOptional(svt.validateNumber))}); +} + +export type HasOptionalConstructor = DoesNot | Does | HasOptionalStruct; + +export enum HasOptionalConstructorTag { + DoesNot = "DoesNot", + Does = "Does", + HasOptionalStruct = "HasOptionalStruct", +} + +export type DoesNot = { + type: HasOptionalConstructorTag.DoesNot; + data: number; +}; + +export type Does = { + type: HasOptionalConstructorTag.Does; + data?: number; +}; + +export type HasOptionalStruct = { + type: HasOptionalConstructorTag.HasOptionalStruct; + data?: HasOptionalString; +}; + +export function DoesNot(data: number): DoesNot { + return {type: HasOptionalConstructorTag.DoesNot, data}; +} + +export function Does(data?: number): Does { + return {type: HasOptionalConstructorTag.Does, data}; +} + +export function HasOptionalStruct(data?: HasOptionalString): HasOptionalStruct { + return {type: HasOptionalConstructorTag.HasOptionalStruct, data}; +} + +export function isHasOptionalConstructor(value: unknown): value is HasOptionalConstructor { + return [isDoesNot, isDoes, isHasOptionalStruct].some((typePredicate) => typePredicate(value)); +} + +export function isDoesNot(value: unknown): value is DoesNot { + return svt.isInterface(value, {type: HasOptionalConstructorTag.DoesNot, data: svt.isNumber}); +} + +export function isDoes(value: unknown): value is Does { + return svt.isInterface(value, {type: HasOptionalConstructorTag.Does, data: svt.optional(svt.isNumber)}); +} + +export function isHasOptionalStruct(value: unknown): value is HasOptionalStruct { + return svt.isInterface(value, {type: HasOptionalConstructorTag.HasOptionalStruct, data: svt.optional(isHasOptionalString)}); +} + +export function validateHasOptionalConstructor(value: unknown): svt.ValidationResult { + return svt.validateWithTypeTag(value, {[HasOptionalConstructorTag.DoesNot]: validateDoesNot, [HasOptionalConstructorTag.Does]: validateDoes, [HasOptionalConstructorTag.HasOptionalStruct]: validateHasOptionalStruct}, "type"); +} + +export function validateDoesNot(value: unknown): svt.ValidationResult { + return svt.validate(value, {type: HasOptionalConstructorTag.DoesNot, data: svt.validateNumber}); +} + +export function validateDoes(value: unknown): svt.ValidationResult { + return svt.validate(value, {type: HasOptionalConstructorTag.Does, data: svt.validateOptional(svt.validateNumber)}); +} + +export function validateHasOptionalStruct(value: unknown): svt.ValidationResult { + return svt.validate(value, {type: HasOptionalConstructorTag.HasOptionalStruct, data: svt.validateOptional(validateHasOptionalString)}); +} From de9f40b7e6e730a0f05033523f244b3c19c17ec6 Mon Sep 17 00:00:00 2001 From: Rickard Andersson Date: Fri, 14 Oct 2022 00:45:12 +0300 Subject: [PATCH 8/8] docs: add to changelog --- CHANGELOG.md | 16 ++++++++++++++++ gotyno-hs.cabal | 2 +- package.yaml | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 691f31f..90077aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## 2.2.0 + +### Added + +- More tests for TypeScript output; the "basic" suite + +### Fixes +- Fixed bug where TypeScript's optional parameters to constructors would not + use `?`, i.e. `function Constructor(data?: string)`. + +## 2.1.0 + +### Fixes + +- Made it so Kotlin started using types from enum definitions instead of `Any`. + ## 2.0.0 ### Breaking changes diff --git a/gotyno-hs.cabal b/gotyno-hs.cabal index 8cd18a0..6068d74 100644 --- a/gotyno-hs.cabal +++ b/gotyno-hs.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: gotyno-hs -version: 2.1.0 +version: 2.2.0 synopsis: A type definition compiler supporting multiple output languages. description: Compiles type definitions into F#, TypeScript and Python, with validators, decoders and encoders. category: Compiler diff --git a/package.yaml b/package.yaml index 41c0ddc..ed52e64 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: gotyno-hs -version: 2.1.0 +version: 2.2.0 synopsis: A type definition compiler supporting multiple output languages. description: Compiles type definitions into F#, TypeScript and Python, with validators, decoders and encoders. license: BSD2