merge main, update fail test descriptions

This commit is contained in:
Luke Boswell 2023-03-29 10:01:38 +11:00
parent e5dd4295c9
commit addc4debef
No known key found for this signature in database
GPG key ID: F6DB3C9DB47377B0
11 changed files with 1822 additions and 1855 deletions

View file

@ -405,13 +405,11 @@ decodeBool = Decode.custom \bytes, @Json {} ->
_ -> { result: Err TooShort, rest: bytes }
expect
actual : DecodeResult Bool
actual = "true\n" |> Str.toUtf8 |> Decode.fromBytesPartial fromUtf8
expected = Ok Bool.true
actual.result == expected
expect
actual : DecodeResult Bool
actual = "false ]\n" |> Str.toUtf8 |> Decode.fromBytesPartial fromUtf8
expected = Ok Bool.false
actual.result == expected
@ -459,12 +457,6 @@ parseExactChar = \bytes, char ->
Err _ -> { result: Err TooShort, rest: bytes }
# openBrace : List U8 -> DecodeResult {}
# openBrace = \bytes -> parseExactChar bytes '{'
# closingBrace : List U8 -> DecodeResult {}
# closingBrace = \bytes -> parseExactChar bytes '}'
openBracket : List U8 -> DecodeResult {}
openBracket = \bytes -> parseExactChar bytes '['
@ -474,9 +466,6 @@ closingBracket = \bytes -> parseExactChar bytes ']'
anything : List U8 -> DecodeResult {}
anything = \bytes -> { result: Err TooShort, rest: bytes }
# colon : List U8 -> DecodeResult {}
# colon = \bytes -> parseExactChar bytes ':'
comma : List U8 -> DecodeResult {}
comma = \bytes -> parseExactChar bytes ','
@ -588,10 +577,8 @@ expect
expected = { result: Ok 2u64, rest: [']'] }
actual == expected
# TODO why is this trying to decode as a Record?
# If you use Decode.fromBytesPartial it fails
expect
actual = "30,\n" |> Str.toUtf8 |> Decode.decodeWith decodeI64 fromUtf8
actual = "30,\n" |> Str.toUtf8 |> Decode.fromBytesPartial fromUtf8
expected = { result: Ok 30i64, rest: [',', '\n'] }
actual == expected
@ -1077,161 +1064,141 @@ expect
# JSON OBJECTS -----------------------------------------------------------------
# decodeRecord = \initialState, stepField, finalizer -> Decode.custom \bytes, @Json {} ->
# # NB: the stepper function must be passed explicitly until #2894 is resolved.
# decodeFields = \stepper, state, kvBytes ->
# { val: key, rest } <- (Decode.decodeWith kvBytes decodeString (@Json {})) |> tryDecode
# { rest: afterColonBytes } <- colon rest |> tryDecode
# { val: newState, rest: beforeCommaOrBreak } <- tryDecode
# (
# when stepper state key is
# Skip ->
# { rest: beforeCommaOrBreak } <- afterColonBytes |> anything |> tryDecode
# { result: Ok state, rest: beforeCommaOrBreak }
# Keep decoder ->
# Decode.decodeWith afterColonBytes decoder (@Json {})
# )
# { result: commaResult, rest: nextBytes } = comma beforeCommaOrBreak
# when commaResult is
# Ok {} -> decodeFields stepField newState nextBytes
# Err _ -> { result: Ok newState, rest: nextBytes }
# { rest: afterBraceBytes } <- bytes |> openBrace |> tryDecode
# { val: endStateResult, rest: beforeClosingBraceBytes } <- decodeFields stepField initialState afterBraceBytes |> tryDecode
# { rest: afterRecordBytes } <- beforeClosingBraceBytes |> closingBrace |> tryDecode
# when finalizer endStateResult is
# Ok val -> { result: Ok val, rest: afterRecordBytes }
# Err e -> { result: Err e, rest: afterRecordBytes }
decodeRecord = \initialState, stepField, finalizer -> Decode.custom \bytes, @Json {} ->
# Recursively build up record from object field:value pairs
decodeFields = \recordState, bytesBeforeField ->
# Recursively build up record from object field:value pairs
decodeFields = \recordState, bytesBeforeField ->
# Decode the json string field name
{result: fieldNameResult, rest: bytesAfterField} =
Decode.decodeWith bytesBeforeField decodeString fromUtf8
# Decode the json string field name
{ result: fieldNameResult, rest: bytesAfterField } =
Decode.decodeWith bytesBeforeField decodeString fromUtf8
# Count the bytes until the field value
countBytesBeforeValue = when List.walkUntil bytesAfterField (BeforeColon 0) objectHelp is
ObjectValueStart n -> n
_ -> 0
# Count the bytes until the field value
countBytesBeforeValue =
when List.walkUntil bytesAfterField (BeforeColon 0) objectHelp is
AfterColon n -> n
_ -> 0
valueBytes = List.drop bytesAfterField countBytesBeforeValue
valueBytes = List.drop bytesAfterField countBytesBeforeValue
when fieldNameResult is
Err TooShort ->
# Invalid object, unable to decode field name or find colon ':'
# after field and before the value
{result: Err TooShort, rest: bytes}
Ok fieldName ->
# Decode the json value
{val: updatedRecord, rest: bytesAfterValue } <-
(
# Retrieve value decoder for the current field
when stepField recordState fieldName is
Skip ->
# TODO This doesn't seem right, shouldn't we eat
# the remaining value bytes if we are skipping this
# field?
#
# Should rest be bytesAfterNextValue or similar?
{result: Ok recordState, rest: valueBytes}
when fieldNameResult is
Err TooShort ->
# Invalid object, unable to decode field name or find colon ':'
# after field and before the value
{ result: Err TooShort, rest: bytes }
Keep valueDecoder ->
# Decode the value using the decoder from the recordState
Decode.decodeWith valueBytes valueDecoder fromUtf8
)
|> tryDecode
Ok fieldName ->
# Decode the json value
{ val: updatedRecord, rest: bytesAfterValue } <-
(
# Retrieve value decoder for the current field
when stepField recordState fieldName is
Skip ->
# TODO This doesn't seem right, shouldn't we eat
# the remaining value bytes if we are skipping this
# field?
#
# Should rest be bytesAfterNextValue or similar?
{ result: Ok recordState, rest: valueBytes }
# Check if another field or '}' for end of object
when List.walkUntil bytesAfterValue (AfterObjectValue 0) objectHelp is
ObjectFieldNameStart n ->
rest = List.drop bytesAfterValue n
Keep valueDecoder ->
# Decode the value using the decoder from the recordState
Decode.decodeWith valueBytes valueDecoder fromUtf8
)
|> tryDecode
# Decode the next field and value
decodeFields updatedRecord rest
# Check if another field or '}' for end of object
when List.walkUntil bytesAfterValue (AfterObjectValue 0) objectHelp is
ObjectFieldNameStart n ->
rest = List.drop bytesAfterValue n
AfterClosingBrace n ->
rest = List.drop bytesAfterValue n
# Decode the next field and value
decodeFields updatedRecord rest
# Build final record from decoded fields and values
when finalizer updatedRecord is
Ok val -> { result: Ok val, rest }
Err e -> { result: Err e, rest }
AfterClosingBrace n ->
rest = List.drop bytesAfterValue n
_ ->
# Invalid object
{result : Err TooShort, rest: bytesAfterValue}
countBytesBeforeFirstField =
when List.walkUntil bytes (BeforeOpeningBrace 0) objectHelp is
ObjectFieldNameStart n -> n
_ -> 0
# Build final record from decoded fields and values
when finalizer updatedRecord is
Ok val -> { result: Ok val, rest }
Err e -> { result: Err e, rest }
if countBytesBeforeFirstField == 0 then
# Invalid object, expected opening brace '{' followed by a field
{result: Err TooShort, rest: bytes}
else
bytesBeforeFirstField = (List.drop bytes countBytesBeforeFirstField)
_ ->
# Invalid object
{ result: Err TooShort, rest: bytesAfterValue }
# Begin decoding field:value pairs
decodeFields initialState bytesBeforeFirstField
countBytesBeforeFirstField =
when List.walkUntil bytes (BeforeOpeningBrace 0) objectHelp is
ObjectFieldNameStart n -> n
_ -> 0
if countBytesBeforeFirstField == 0 then
# Invalid object, expected opening brace '{' followed by a field
{ result: Err TooShort, rest: bytes }
else
bytesBeforeFirstField = List.drop bytes countBytesBeforeFirstField
# Begin decoding field:value pairs
decodeFields initialState bytesBeforeFirstField
objectHelp : ObjectState, U8 -> [Break ObjectState, Continue ObjectState]
objectHelp = \state, byte ->
when (state, byte) is
(BeforeOpeningBrace n, b) if isWhitespace b -> Continue (BeforeOpeningBrace (n+1))
(BeforeOpeningBrace n, b) if b == '{' -> Continue (AfterOpeningBrace (n+1))
(AfterOpeningBrace n, b) if isWhitespace b -> Continue (AfterOpeningBrace (n+1))
when (state, byte) is
(BeforeOpeningBrace n, b) if isWhitespace b -> Continue (BeforeOpeningBrace (n + 1))
(BeforeOpeningBrace n, b) if b == '{' -> Continue (AfterOpeningBrace (n + 1))
(AfterOpeningBrace n, b) if isWhitespace b -> Continue (AfterOpeningBrace (n + 1))
(AfterOpeningBrace n, b) if b == '"' -> Break (ObjectFieldNameStart n) # field names must be a json string
(BeforeColon n, b) if isWhitespace b -> Continue (BeforeColon (n+1))
(BeforeColon n, b) if b == ':' -> Continue (AfterColon (n+1))
(AfterColon n, b) if isWhitespace b -> Continue (AfterColon (n+1))
(AfterColon n, _) -> Break (ObjectValueStart n) # object value could start with **almost** anything
(AfterObjectValue n, b) if isWhitespace b -> Continue (AfterObjectValue (n+1))
(AfterObjectValue n, b) if b == ',' -> Continue (AfterComma (n+1))
(AfterObjectValue n, b) if b == '}' -> Continue (AfterClosingBrace (n+1))
(AfterComma n, b) if isWhitespace b -> Continue (AfterComma (n+1))
(BeforeColon n, b) if isWhitespace b -> Continue (BeforeColon (n + 1))
(BeforeColon n, b) if b == ':' -> Continue (AfterColon (n + 1))
(AfterColon n, b) if isWhitespace b -> Continue (AfterColon (n + 1))
(AfterColon n, _) -> Break (AfterColon n) # object value could start with lots of things
(AfterObjectValue n, b) if isWhitespace b -> Continue (AfterObjectValue (n + 1))
(AfterObjectValue n, b) if b == ',' -> Continue (AfterComma (n + 1))
(AfterObjectValue n, b) if b == '}' -> Continue (AfterClosingBrace (n + 1))
(AfterComma n, b) if isWhitespace b -> Continue (AfterComma (n + 1))
(AfterComma n, b) if b == '"' -> Break (ObjectFieldNameStart n)
(AfterClosingBrace n, b) if isWhitespace b -> Continue (AfterClosingBrace (n+1))
(AfterClosingBrace n, b) if isWhitespace b -> Continue (AfterClosingBrace (n + 1))
_ -> Break InvalidObject
ObjectState : [
BeforeOpeningBrace Nat,
AfterOpeningBrace Nat,
ObjectFieldNameStart Nat,
BeforeColon Nat,
AfterColon Nat,
ObjectValueStart Nat,
BeforeColon Nat,
AfterColon Nat,
AfterObjectValue Nat,
AfterComma Nat,
AfterClosingBrace Nat,
AfterClosingBrace Nat,
InvalidObject,
]
# Test decode of simple Json Object into Roc Record
expect
input = Str.toUtf8 "{\"fruit\":2\n} "
actual = Decode.fromBytesPartial input fromUtf8
expected = Ok { fruit: 2 }
actual.result == expected
# Test decode of simple Json Object into Roc Record
# TODO assertion failed: value == 0 || value == 1
# Test decode of simple Json Object into Roc Record ignoring whitespace
# TODO this test makes `decodeI64` test fail
# expect
# input = Str.toUtf8 "{\"fruit\":\"two\"}"
# input = Str.toUtf8 " {\n\"fruit\"\t:2\n } "
# actual = Decode.fromBytesPartial input fromUtf8
# expected = Ok { fruit: "two" }
# expected = Ok { fruit: 2 }
# actual.result == expected
# Test decode of simple Json Object
# TODO this test makes `decodeString` tests fail
# expect
# input = Str.toUtf8 "{\"fruit\": \"apple\" }"
# actual = Decode.fromBytesPartial input fromUtf8
# expected = Ok { fruit: "apple" }
# actual.result == expected
# Test decode of simple Json Object
# TODO this test makes `decodeBool` tests fail
# expect
# input = Str.toUtf8 "{\"fruit\": true }"
# actual : DecodeResult { fruit : Bool }
# actual = Decode.fromBytesPartial input fromUtf8
# expected = Ok { fruit: Bool.true }
# actual.result == expected