diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml deleted file mode 100644 index 359af09a4..000000000 --- a/.github/workflows/nodejs.yml +++ /dev/null @@ -1,82 +0,0 @@ -# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions -name: Node.js CI -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] -jobs: - # building project - build: - name: Build - runs-on: ${{ matrix.os }} - strategy: - matrix: - node-version: [18.x] - os: [ ubuntu-latest ] - steps: - - uses: actions/checkout@v4 - - - name: Setup Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - - name: Cache NPM - uses: actions/cache@v3 - with: - path: ~/.npm - key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-node- - - - name: Cache Elm - uses: actions/cache@v3 - with: - path: ~/.elm - key: ${{ runner.os }}-elm-${{ hashFiles('**/elm.json') }} - restore-keys: | - ${{ runner.os }}-elm- - - - name: Download dependencies - run: npm ci - - - name: Build - run: npm run build --if-present - - - name: Running Test - run: npm test - - # CVE scanning - cvescan: - name: CVE Scanning - runs-on: ubuntu-latest - needs: [ build ] - strategy: - matrix: - node-version: [18.x] - steps: - - uses: actions/checkout@v4 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - - run: npm ci - - run: npx --yes auditjs ossi --whitelist allow-list.json - - # Semgrep static code analysis - semgrep: - name: Semgrep - runs-on: ubuntu-latest - needs: [ cvescan ] - container: - # A Docker image with Semgrep installed. Don't change this. - image: returntocorp/semgrep - # Skip any PR created by dependabot to avoid permission issues - if: (github.actor != 'dependabot[bot]') - steps: - - uses: actions/checkout@v4 - - run: semgrep scan --config auto --severity ERROR - env: - SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} diff --git a/.gitignore b/.gitignore index 398f984f3..f2aa1a176 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,4 @@ docs.json /.coverage/ tests-integration/reference-model/Dockerfile -.scala-build/ \ No newline at end of file +.scala-build/ diff --git a/elm.json b/elm.json index 8bc2ece75..e7351b0cb 100644 --- a/elm.json +++ b/elm.json @@ -18,6 +18,7 @@ "Morphir.SDK.Dict", "Morphir.SDK.ResultList", "Morphir.SDK.LocalTime", + "Morphir.SDK.UUID", "Morphir.IR.Name", "Morphir.IR.NodeId", "Morphir.IR.Decoration", @@ -55,6 +56,7 @@ ], "elm-version": "0.19.0 <= v < 0.20.0", "dependencies": { + "TSFoster/elm-uuid": "4.2.0 <= v < 5.0.0", "chain-partners/elm-bignum": "1.0.1 <= v < 2.0.0", "cmditch/elm-bigint": "1.0.1 <= v < 2.0.0", "cuducos/elm-format-number": "8.1.4 <= v < 9.0.0", diff --git a/src/Morphir/IR/Literal.elm b/src/Morphir/IR/Literal.elm index 4866f09e4..76fd18e36 100644 --- a/src/Morphir/IR/Literal.elm +++ b/src/Morphir/IR/Literal.elm @@ -29,6 +29,7 @@ module Morphir.IR.Literal exposing (Literal(..), boolLiteral, charLiteral, strin -} import Morphir.SDK.Decimal exposing (Decimal) +import Morphir.SDK.UUID exposing (UUID) diff --git a/src/Morphir/IR/Literal/Codec.elm b/src/Morphir/IR/Literal/Codec.elm index d6b15bf5c..14a3e7b7f 100644 --- a/src/Morphir/IR/Literal/Codec.elm +++ b/src/Morphir/IR/Literal/Codec.elm @@ -21,6 +21,7 @@ import Json.Decode as Decode import Json.Encode as Encode import Morphir.IR.Literal exposing (Literal(..)) import Morphir.SDK.Decimal as Decimal +import Morphir.SDK.UUID as UUID encodeLiteral : Literal -> Encode.Value diff --git a/src/Morphir/IR/Literal/CodecV1.elm b/src/Morphir/IR/Literal/CodecV1.elm index bdda59610..e6cdb717f 100644 --- a/src/Morphir/IR/Literal/CodecV1.elm +++ b/src/Morphir/IR/Literal/CodecV1.elm @@ -21,6 +21,7 @@ import Json.Decode as Decode import Json.Encode as Encode import Morphir.IR.Literal exposing (Literal(..)) import Morphir.SDK.Decimal as Decimal +import Morphir.SDK.UUID as UUID encodeLiteral : Literal -> Encode.Value diff --git a/src/Morphir/IR/SDK.elm b/src/Morphir/IR/SDK.elm index 2ec1d5aba..46dc6d7fa 100644 --- a/src/Morphir/IR/SDK.elm +++ b/src/Morphir/IR/SDK.elm @@ -44,6 +44,7 @@ import Morphir.IR.SDK.StatefulApp as StatefulApp import Morphir.IR.SDK.String as String import Morphir.IR.SDK.Tuple as Tuple import Morphir.Value.Native as Native +import Morphir.IR.SDK.UUID as UUID packageName : PackageName @@ -75,6 +76,7 @@ packageSpec = , ( [ [ "number" ] ], Number.moduleSpec ) , ( [ [ "key" ] ], Key.moduleSpec ) , ( [ [ "aggregate" ] ], Aggregate.moduleSpec ) + , ( [ [ "uuid" ] ], UUID.moduleSpec) ] } diff --git a/src/Morphir/IR/SDK/UUID.elm b/src/Morphir/IR/SDK/UUID.elm new file mode 100644 index 000000000..7ba02582a --- /dev/null +++ b/src/Morphir/IR/SDK/UUID.elm @@ -0,0 +1,111 @@ +module Morphir.IR.SDK.UUID exposing (..) + +import Dict +import Morphir.IR.Documented exposing (Documented) +import Morphir.IR.Module as Module exposing (ModuleName) +import Morphir.IR.Path as Path +import Morphir.IR.Name as Name +import Morphir.IR.Type exposing (Specification(..), Type(..)) +import Morphir.IR.Literal exposing (Literal(..)) +import Morphir.IR.Documented exposing (Documented) +import Morphir.IR.Value as Value exposing (Value) +import Morphir.IR.SDK.Common exposing (vSpec) +import Morphir.IR.SDK.String exposing (stringType) +import Morphir.IR.SDK.Common exposing (toFQName) +import Morphir.IR.SDK.Result exposing (resultType) +import Morphir.IR.SDK.Basics exposing (intType, orderType, boolType) +import Morphir.Value.Native as Native +import Morphir.Value.Native exposing (eval1, eval2) +import Morphir.SDK.UUID as UUID +import Morphir.Value.Native exposing (decodeLiteral, encodeLiteral, stringLiteral, intLiteral, encodeMaybe) +import Morphir.Value.Native exposing (eval0) +import Morphir.Value.Native exposing (encodeUUID, encodeUUID2) +import Morphir.IR.SDK.Maybe exposing (maybeType) +import Morphir.Value.Native exposing (decodeUUID) +import Morphir.Value.Native.Comparable exposing (compareValue) + +moduleName : ModuleName +moduleName = + Path.fromString "UUID" + +moduleSpec : Module.Specification () +moduleSpec = + { types = + Dict.fromList + [ (Name.fromString "UUID", OpaqueTypeSpecification [] |> Documented "Type that represents a UUID v5") + ] + , values = + Dict.fromList + [ vSpec "parse" [ ("s", stringType () ) ] (resultType () (errorType ()) (uuidType ())) + , vSpec "fromString" [ ("s", stringType() ) ] (maybeType () (uuidType ())) + , vSpec "forName" [ ("s", stringType () ), ("uuid", uuidType () ) ] (uuidType ()) + , vSpec "toString" [ ("uuid", uuidType () ) ] (stringType ()) + , vSpec "version" [ ("uuid", uuidType () ) ] (intType ()) + , vSpec "compare" [ ("uuid1", uuidType () ), ("uuid2", uuidType () ) ] (orderType ()) + , vSpec "nilString" [] (stringType ()) + , vSpec "isNilString" [ ("s", stringType () ) ] (boolType()) + , vSpec "dnsNamespace" [] (uuidType ()) + , vSpec "urlNamespace" [] (uuidType ()) + , vSpec "oidNamespace" [] (uuidType ()) + , vSpec "x500Namespace" [] (uuidType ()) + ] + , doc = Just "The UUID type and associated functions" + } + +uuidType : a -> Type a +uuidType attributes = + Reference attributes (toFQName moduleName "UUID") [] + +errorType: a -> Type a +errorType attributes = + Reference attributes (toFQName moduleName "Error") [] + +nativeFunctions : List ( String, Native.Function ) +nativeFunctions = + [ ( "forName" + , eval2 UUID.forName (decodeLiteral stringLiteral) decodeUUID (encodeUUID)) + , ( "parse" + , eval1 UUID.parse (decodeLiteral stringLiteral) (encodeUUID2)) + , ( "fromString" + , eval1 UUID.fromString (decodeLiteral stringLiteral) (encodeMaybe encodeUUID)) + , ( "toString" + , eval1 UUID.toString decodeUUID (encodeLiteral StringLiteral)) + , ( "version" + , eval1 UUID.version decodeUUID (encodeLiteral WholeNumberLiteral)) + , ( "nilString" + , eval0 UUID.nilString (encodeLiteral StringLiteral)) + , ( "isNilString" + , eval1 UUID.isNilString (decodeLiteral stringLiteral) (encodeLiteral BoolLiteral)) + , ( "compare" + , Native.binaryStrict + (\arg1 arg2 -> + compareValue arg1 arg2 + |> Result.map encodeOrder + ) + ) + , ( "dnsNamespace" + , eval0 UUID.dnsNamespace (encodeUUID)) + , ( "urlNamespace" + , eval0 UUID.urlNamespace (encodeUUID)) + , ( "oidNamespace" + , eval0 UUID.oidNamespace (encodeUUID)) + , ( "x500Namespace" + , eval0 UUID.x500Namespace (encodeUUID)) + ] + +encodeOrder : Order -> Value () () +encodeOrder = + \order -> + let + val = + case order of + GT -> + "GT" + + LT -> + "LT" + + EQ -> + "EQ" + in + Value.Constructor () (toFQName moduleName val) \ No newline at end of file diff --git a/src/Morphir/IR/Value.elm b/src/Morphir/IR/Value.elm index c457fbfb6..bd78d97bb 100644 --- a/src/Morphir/IR/Value.elm +++ b/src/Morphir/IR/Value.elm @@ -128,6 +128,7 @@ import Morphir.IR.Name as Name exposing (Name) import Morphir.IR.Path as Path import Morphir.IR.Type as Type exposing (Type) import Morphir.SDK.Decimal as Decimal +import Morphir.SDK.UUID exposing (UUID) import Morphir.SDK.ResultList as ListOfResults import Set exposing (Set) @@ -2039,6 +2040,7 @@ toString value = DecimalLiteral decimal -> Decimal.toString decimal + patternToString : Pattern va -> String patternToString pattern = case pattern of diff --git a/src/Morphir/SDK/UUID.elm b/src/Morphir/SDK/UUID.elm new file mode 100644 index 000000000..22c765c8b --- /dev/null +++ b/src/Morphir/SDK/UUID.elm @@ -0,0 +1,143 @@ +module Morphir.SDK.UUID exposing ( + UUID + , Error + , parse + , fromString + , forName + , toString + , version + , compare + , nilString + , isNilString + , dnsNamespace + , urlNamespace + , oidNamespace + , x500Namespace) + +{-| + # The datatype + + @docs UUID + + + # Convert from a known UUID String + + @docs parse + @docs fromString + + + # Create + + @docs forName + + + # Convert to + + @docs toString + + + # Comparing + + @docs compare + + + # Nil check + + @docs isNilString + + + # Nil UUID + + @docs nilString + + + # Namespaces + + @docs dnsNamespace + @docs urlNamespace + @docs oidNamespace + @docs x500Namespace + + + # Other misc functions + + @docs version + +-} + +import UUID as U + +{-| The UUID datatype -} +type alias UUID = + U.UUID + +-- Make this a type with one option that is UUID, we can hold off on this for now +{-| The error type for UUIDs -} +type alias Error = + U.Error + + +{-| You can attempt to create a UUID from a string. This function can interpret a fairly broad range of formatted (and mis-formatted) UUIDs, including ones with too much whitespace, too many (or not enough) hyphens, or uppercase characters.-} +parse : String -> Result Error UUID +parse s = + U.fromString s + +{-| Includes all the functionality as `parse`, however only returns a `Maybe` on failures instead of an `Error`.-} +fromString : String -> Maybe UUID +fromString s = + U.fromString s |> Result.toMaybe + + +{-| Create a version 5 UUID from a String and a namespace, which should be a UUID. The same name and namespace will always produce the same UUID, which can be used to your advantage. Furthermore, the UUID created from this can be used as a namespace for another UUID, creating a hierarchy of sorts.-} +forName : String -> UUID -> UUID +forName s uuid = + U.forName s uuid + + +{-| The cannonical representation of the UUID -} +toString : UUID -> String +toString uuid = + U.toString uuid + + +{-| Get the version number of a UUID. Only versions 3, 4, and 5 are supported in this package, so you should expect the returned Int to be 3, 4, or 5.-} +version : UUID -> Int +version uuid = + U.version uuid + +{-| Returns the relative ordering of two UUIDs. THe main use case of this function is helping in binary-searching algorithms. Mimics elm/core's compare.-} +compare : UUID -> UUID -> Order +compare uuid1 uuid2 = + U.compare uuid1 uuid2 + + +{-| Returns a nil UUID.-} +nilString : String +nilString = + U.nilString + +{-| True if the given string represents the nil UUID (00000000-0000-0000-0000-000000000000).-} +isNilString : String -> Bool +isNilString s = + U.isNilString s + +{-| A UUID for the DNS namespace, "6ba7b810-9dad-11d1-80b4-00c04fd430c8".-} +dnsNamespace : UUID +dnsNamespace = + U.dnsNamespace + + +{-| A UUID for the URL namespace, "6ba7b811-9dad-11d1-80b4-00c04fd430c8".-} +urlNamespace : UUID +urlNamespace = + U.urlNamespace + +{-| A UUID for the ISO object ID (OID) namespace, "6ba7b812-9dad-11d1-80b4-00c04fd430c8".-} +oidNamespace : UUID +oidNamespace = + U.oidNamespace + +{-| A UUID for the X.500 Distinguished Name (DN) namespace, "6ba7b814-9dad-11d1-80b4-00c04fd430c8".-} +x500Namespace : UUID +x500Namespace = + U.x500Namespace diff --git a/src/Morphir/Scala/AST.elm b/src/Morphir/Scala/AST.elm index 03fe7eea1..8ca38b857 100644 --- a/src/Morphir/Scala/AST.elm +++ b/src/Morphir/Scala/AST.elm @@ -40,6 +40,7 @@ generator uses. It's a relatively large portion of the language but it's not aim -} import Decimal exposing (Decimal) +import UUID exposing (UUID) {-| -} @@ -288,6 +289,7 @@ type Lit | IntegerLit Int | FloatLit Float | DecimalLit Decimal + | UUIDLit UUID | NullLit diff --git a/src/Morphir/Scala/Feature/Core.elm b/src/Morphir/Scala/Feature/Core.elm index 64bd3fecc..d0004b4e5 100644 --- a/src/Morphir/Scala/Feature/Core.elm +++ b/src/Morphir/Scala/Feature/Core.elm @@ -474,6 +474,7 @@ mapValue inScopeVars value = DecimalLiteral _ -> Debug.todo "branch 'DecimalLiteral _' not implemented" + Constructor constructorType fQName -> Scala.TypeAscripted (curryConstructorArgs inScopeVars constructorType fQName []) @@ -784,6 +785,7 @@ mapPattern pattern = DecimalLiteral v -> Scala.DecimalLit v + in Scala.LiteralMatch (map literal) diff --git a/src/Morphir/Scala/PrettyPrinter.elm b/src/Morphir/Scala/PrettyPrinter.elm index 5647ece24..9115efa4d 100644 --- a/src/Morphir/Scala/PrettyPrinter.elm +++ b/src/Morphir/Scala/PrettyPrinter.elm @@ -24,6 +24,7 @@ module Morphir.Scala.PrettyPrinter exposing (Options, mapCompilationUnit, mapMem -} import Decimal +import UUID import Morphir.File.SourceCode exposing (Doc, concat, dot, dotSep, empty, indent, indentLines, newLine, parens, space) import Morphir.IR.Name as Name import Morphir.Scala.AST exposing (..) @@ -677,6 +678,9 @@ mapLit lit = DecimalLit decimal -> Decimal.toString decimal + UUIDLit uuid -> + UUID.toString uuid + NullLit -> "null" diff --git a/src/Morphir/Type/MetaType.elm b/src/Morphir/Type/MetaType.elm index b867dac81..4fd2bc222 100644 --- a/src/Morphir/Type/MetaType.elm +++ b/src/Morphir/Type/MetaType.elm @@ -1,4 +1,4 @@ -module Morphir.Type.MetaType exposing (MetaType(..), Variable, boolType, charType, contains, floatType, intType, listType, metaAlias, metaClosedRecord, metaFun, metaOpenRecord, metaRecord, metaRef, metaTuple, metaUnit, metaVar, removeAliases, stringType, substituteVariable, substituteVariables, toString, variableByIndex, variableGreaterThan, variables, wrapInAliases) +module Morphir.Type.MetaType exposing (MetaType(..), Variable, boolType, charType, uuidType, contains, floatType, intType, listType, metaAlias, metaClosedRecord, metaFun, metaOpenRecord, metaRecord, metaRef, metaTuple, metaUnit, metaVar, removeAliases, stringType, substituteVariable, substituteVariables, toString, variableByIndex, variableGreaterThan, variables, wrapInAliases) import Dict exposing (Dict) import Morphir.IR.FQName as FQName exposing (FQName, fqn) @@ -363,6 +363,10 @@ floatType : MetaType floatType = metaRef (fqn "Morphir.SDK" "Basics" "Float") [] +uuidType : MetaType +uuidType = + metaRef (fqn "Morphir.SDK" "UUID" "UUID") [] + listType : MetaType -> MetaType listType itemType = diff --git a/src/Morphir/Value/Native.elm b/src/Morphir/Value/Native.elm index 2a992a067..0353c7ff6 100644 --- a/src/Morphir/Value/Native.elm +++ b/src/Morphir/Value/Native.elm @@ -3,7 +3,7 @@ module Morphir.Value.Native exposing , Eval , unaryLazy, unaryStrict, binaryLazy, binaryStrict, boolLiteral, charLiteral, eval0, eval1, eval2, eval3 , floatLiteral, intLiteral, oneOf, stringLiteral, decimalLiteral - , decodeFun1, decodeList, decodeLiteral, decodeMaybe, decodeLocalDate, decodeRaw, decodeTuple2, encodeList, encodeLiteral, encodeMaybe, encodeLocalDate, encodeMaybeResult, encodeRaw, encodeResultList, encodeTuple2, decodeDict, decodeFun2, encodeDict + , decodeFun1, decodeList, decodeLiteral, decodeMaybe, decodeLocalDate, decodeRaw, decodeTuple2, decodeUUID, encodeList, encodeLiteral, encodeMaybe, encodeLocalDate, encodeMaybeResult, encodeRaw, encodeResultList, encodeTuple2, decodeDict, decodeFun2, encodeDict, encodeUUID, encodeUUID2 , trinaryLazy, trinaryStrict ) @@ -49,8 +49,12 @@ import Morphir.IR.Value as Value exposing (RawValue, Value) import Morphir.SDK.Decimal exposing (Decimal) import Morphir.SDK.Dict as Dict exposing (Dict) import Morphir.SDK.LocalDate as LocalDate exposing (LocalDate) +import Morphir.SDK.UUID exposing (UUID) import Morphir.SDK.ResultList as ListOfResults import Morphir.Value.Error exposing (Error(..)) +import Morphir.SDK.UUID as UUID +import UUID as U +import Json.Encode exposing (encode) {-| Type that represents a native function. It's a function that takes two arguments: @@ -450,6 +454,56 @@ decodeMaybe decodeItem eval value = Err error +{-| -} +encodeUUID : UUID -> Result Error RawValue +encodeUUID uuid = + UUID.toString uuid + |> StringLiteral + |> Value.Literal () + |> Value.Apply () (Value.Reference () ( [ [ "morphir" ], [ "s", "d", "k" ] ], [ [ "uuid" ] ], [ "from", "string" ] )) + |> Ok + + +{-| -} +encodeUUID2 : (Result Error UUID) -> Result Error RawValue +encodeUUID2 result = + case result of + Ok uuid -> + UUID.toString uuid + |> StringLiteral + |> Value.Literal () + |> Value.Apply () (Value.Reference () ( [ [ "morphir" ], [ "s", "d", "k" ] ], [ [ "uuid" ] ], [ "from", "string" ] )) + |> Ok + Err error -> + Err error + +{-| -} +decodeUUID : Decoder UUID +decodeUUID e value = + e value + |> Result.andThen + (\v -> + case v of + Value.Apply () (Value.Reference () ( [ [ "morphir" ], [ "s", "d", "k" ] ], [ [ "uuid" ] ], [ "from", "string" ] )) (Value.Literal () (StringLiteral str)) -> + case UUID.fromString str of + Just uuid -> + Ok uuid + + Nothing -> + Err <| ErrorWhileEvaluatingDerivedType ("Invalid UUID format: " ++ str) + + Value.Literal () (StringLiteral str) -> + case UUID.fromString str of + Just uuid -> + Ok uuid + + Nothing -> + Err <| ErrorWhileEvaluatingDerivedType ("Invalid UUID format: " ++ str) + + _ -> + Err (ExpectedDerivedType ( [ [ "morphir" ], [ "s", "d", "k" ] ], [ [ "uuid" ] ], [ "uuid" ] ) v) + ) + {-| -} encodeLocalDate : LocalDate -> Result Error RawValue encodeLocalDate localDate = diff --git a/src/Morphir/Value/Native/Comparable.elm b/src/Morphir/Value/Native/Comparable.elm index f7f35a7f3..8588b5c69 100644 --- a/src/Morphir/Value/Native/Comparable.elm +++ b/src/Morphir/Value/Native/Comparable.elm @@ -3,6 +3,7 @@ module Morphir.Value.Native.Comparable exposing (..) import Morphir.IR.Literal exposing (Literal(..)) import Morphir.IR.Value as Value exposing (RawValue) import Morphir.Value.Error exposing (Error(..)) +import Morphir.SDK.UUID as UUID exposing (UUID) lessThan : RawValue -> RawValue -> Result Error Bool diff --git a/tests/Morphir/AbstractTreeVisualizer.elm b/tests/Morphir/AbstractTreeVisualizer.elm index abfbd1295..66a53a414 100644 --- a/tests/Morphir/AbstractTreeVisualizer.elm +++ b/tests/Morphir/AbstractTreeVisualizer.elm @@ -11,6 +11,7 @@ import Morphir.Visual.Components.AritmeticExpressions exposing (ArithmeticOperat import Svg exposing (..) import Svg.Attributes exposing (..) import Morphir.SDK.Decimal exposing (Decimal) +import UUID import Decimal diff --git a/tests/Morphir/SDK/UUIDTests.elm b/tests/Morphir/SDK/UUIDTests.elm new file mode 100644 index 000000000..addf67df6 --- /dev/null +++ b/tests/Morphir/SDK/UUIDTests.elm @@ -0,0 +1,84 @@ +module Morphir.SDK.UUIDTests exposing (..) + +import UUID exposing (UUID) +import Morphir.SDK.UUID as U +import Test exposing (..) +import Expect +import UUID exposing (Error(..)) + +namespaceTests : Test +namespaceTests = + describe "namespace tests" + [test "dns namespace test" <| + \_ -> + Expect.equal (U.dnsNamespace |> U.toString) (UUID.dnsNamespace |> UUID.toString) + , test "url namespace test" <| + \_ -> + Expect.equal (U.urlNamespace |> U.toString) (UUID.urlNamespace |> UUID.toString) + , test "oid namespace test" <| + \_ -> + Expect.equal (U.oidNamespace |> U.toString) (UUID.oidNamespace |> UUID.toString) + , test "x500 namespace test" <| + \_ -> + Expect.equal (U.x500Namespace |> U.toString) (UUID.x500Namespace |> UUID.toString) + ] + + +toStringTests : Test +toStringTests = + describe "empty uuid tests" + [ test "empty string to string" <| + \_ -> + Expect.equal (U.nilString) (UUID.nilString) + , test "test is nil string" <| + \_ -> + Expect.equal (U.nilString |> U.isNilString) (UUID.nilString |> UUID.isNilString) + ] + +fromStringTests : Test +fromStringTests = + describe "fromString tests" + [ test "from string basic uuid" <| + \_ -> + Expect.equal (U.fromString "6ba7b810-9dad-11d1-80b4-00c04fd430c8") (UUID.fromString "6ba7b810-9dad-11d1-80b4-00c04fd430c8" |> Result.toMaybe) + , test "from string invalid uuid" <| + \_ -> + Expect.equal(U.fromString "c72c207b-0847-386d-bdbc-2e5def81cg81") (Maybe.Nothing) + , test "fromString incorrect length" <| + \_ -> + Expect.equal(U.fromString "6ba7b811-9dad-11d1-80b4-00c04fd430d80") (Maybe.Nothing) + ] + +parseTests : Test +parseTests = + describe "parse tests" + [ test "parse basic uuid" <| + \_ -> + Expect.equal (U.parse "6ba7b810-9dad-11d1-80b4-00c04fd430c8") ( Ok UUID.dnsNamespace ) + , test "parse invalid uuid" <| + \_ -> + Expect.equal (U.parse "c72c207b-0847-386d-bdbc-2e5def81cg81") (Err WrongFormat) + , test "parse incorrect length" <| + \_ -> + Expect.equal (U.parse "6ba7b811-9dad-11d1-80b4-00c04fd430d80") (Err WrongLength) + , test "parse uuid version mapping" <| + \_ -> + Expect.equal (U.parse "c72c207b-0847-386d-bdbc-2e5def81cf81" |> Result.map U.version) (Ok 3) + ] + +forNameTests : Test +forNameTests = + describe "forName tests" + [ test "forName dnsNamespace test" <| + \_ -> + Expect.equal(U.forName "foo" U.dnsNamespace) (UUID.forName "foo" UUID.dnsNamespace) + , test "forName urlNamespace test" <| + \_ -> + Expect.equal (U.forName "foo" U.urlNamespace) (UUID.forName "foo" UUID.urlNamespace) + , test "forName oidNamespace test" <| + \_ -> + Expect.equal (U.forName "foo" U.oidNamespace) (UUID.forName "foo" UUID.oidNamespace) + , test "forName x500Namespace test" <| + \_ -> + Expect.equal (U.forName "foo" U.x500Namespace) (UUID.forName "foo" UUID.x500Namespace) + ]