refactor the tests of options (#16527)
This commit is contained in:
parent
e67059a03a
commit
b5101b23b5
1 changed files with 154 additions and 115 deletions
|
|
@ -1,19 +1,8 @@
|
||||||
discard """
|
discard """
|
||||||
output: '''{"foo":{"test":"123"}}'''
|
targets: "c js"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import json, options
|
import std/[json, options]
|
||||||
|
|
||||||
type
|
|
||||||
Foo = ref object
|
|
||||||
test: string
|
|
||||||
Test = object
|
|
||||||
foo: Option[Foo]
|
|
||||||
|
|
||||||
let js = """{"foo": {"test": "123"}}"""
|
|
||||||
let parsed = parseJson(js)
|
|
||||||
let a = parsed.to(Test)
|
|
||||||
echo $(%*a)
|
|
||||||
|
|
||||||
|
|
||||||
# RefPerson is used to test that overloaded `==` operator is not called by
|
# RefPerson is used to test that overloaded `==` operator is not called by
|
||||||
|
|
@ -26,133 +15,183 @@ proc `==`(a, b: RefPerson): bool =
|
||||||
assert(not a.isNil and not b.isNil)
|
assert(not a.isNil and not b.isNil)
|
||||||
a.name == b.name
|
a.name == b.name
|
||||||
|
|
||||||
block options:
|
|
||||||
# work around a bug in unittest
|
|
||||||
let intNone = none(int)
|
|
||||||
let stringNone = none(string)
|
|
||||||
|
|
||||||
block example:
|
template disableJsVm(body) =
|
||||||
proc find(haystack: string, needle: char): Option[int] =
|
# something doesn't work in JS VM
|
||||||
for i, c in haystack:
|
when defined(js):
|
||||||
if c == needle:
|
when nimvm: discard
|
||||||
return some i
|
else: body
|
||||||
|
else:
|
||||||
|
body
|
||||||
|
|
||||||
doAssert("abc".find('c').get() == 2)
|
proc main() =
|
||||||
|
type
|
||||||
|
Foo = ref object
|
||||||
|
test: string
|
||||||
|
Test = object
|
||||||
|
foo: Option[Foo]
|
||||||
|
|
||||||
let result = "team".find('i')
|
let js = """{"foo": {"test": "123"}}"""
|
||||||
|
let parsed = parseJson(js)
|
||||||
|
let a = parsed.to(Test)
|
||||||
|
doAssert $(%*a) == """{"foo":{"test":"123"}}"""
|
||||||
|
|
||||||
doAssert result == intNone
|
block options:
|
||||||
doAssert result.isNone
|
# work around a bug in unittest
|
||||||
|
let intNone = none(int)
|
||||||
|
let stringNone = none(string)
|
||||||
|
|
||||||
block some:
|
block example:
|
||||||
doAssert some(6).get() == 6
|
proc find(haystack: string, needle: char): Option[int] =
|
||||||
doAssert some("a").unsafeGet() == "a"
|
for i, c in haystack:
|
||||||
doAssert some(6).isSome
|
if c == needle:
|
||||||
doAssert some("a").isSome
|
return some i
|
||||||
|
|
||||||
block none:
|
doAssert("abc".find('c').get() == 2)
|
||||||
doAssertRaises UnpackDefect:
|
|
||||||
discard none(int).get()
|
|
||||||
doAssert(none(int).isNone)
|
|
||||||
doAssert(not none(string).isSome)
|
|
||||||
|
|
||||||
block equality:
|
let result = "team".find('i')
|
||||||
doAssert some("a") == some("a")
|
|
||||||
doAssert some(7) != some(6)
|
|
||||||
doAssert some("a") != stringNone
|
|
||||||
doAssert intNone == intNone
|
|
||||||
|
|
||||||
when compiles(some("a") == some(5)):
|
doAssert result == intNone
|
||||||
doAssert false
|
doAssert result.isNone
|
||||||
when compiles(none(string) == none(int)):
|
|
||||||
doAssert false
|
|
||||||
|
|
||||||
block get_with_a_default_value:
|
block some:
|
||||||
doAssert(some("Correct").get("Wrong") == "Correct")
|
doAssert some(6).get() == 6
|
||||||
doAssert(stringNone.get("Correct") == "Correct")
|
doAssert some("a").unsafeGet() == "a"
|
||||||
|
doAssert some(6).isSome
|
||||||
|
doAssert some("a").isSome
|
||||||
|
|
||||||
block stringify:
|
block none:
|
||||||
doAssert($(some("Correct")) == "Some(\"Correct\")")
|
doAssertRaises UnpackDefect:
|
||||||
doAssert($(stringNone) == "None[string]")
|
discard none(int).get()
|
||||||
|
doAssert(none(int).isNone)
|
||||||
|
doAssert(not none(string).isSome)
|
||||||
|
|
||||||
block map_with_a_void_result:
|
block equality:
|
||||||
var procRan = 0
|
doAssert some("a") == some("a")
|
||||||
some(123).map(proc (v: int) = procRan = v)
|
doAssert some(7) != some(6)
|
||||||
doAssert procRan == 123
|
doAssert some("a") != stringNone
|
||||||
intNone.map(proc (v: int) = doAssert false)
|
doAssert intNone == intNone
|
||||||
|
|
||||||
block map:
|
when compiles(some("a") == some(5)):
|
||||||
doAssert(some(123).map(proc (v: int): int = v * 2) == some(246))
|
doAssert false
|
||||||
doAssert(intNone.map(proc (v: int): int = v * 2).isNone)
|
when compiles(none(string) == none(int)):
|
||||||
|
doAssert false
|
||||||
|
|
||||||
block filter:
|
block get_with_a_default_value:
|
||||||
doAssert(some(123).filter(proc (v: int): bool = v == 123) == some(123))
|
doAssert(some("Correct").get("Wrong") == "Correct")
|
||||||
doAssert(some(456).filter(proc (v: int): bool = v == 123).isNone)
|
doAssert(stringNone.get("Correct") == "Correct")
|
||||||
doAssert(intNone.filter(proc (v: int): bool = doAssert false).isNone)
|
|
||||||
|
|
||||||
block flatMap:
|
block stringify:
|
||||||
proc addOneIfNotZero(v: int): Option[int] =
|
doAssert($(some("Correct")) == "Some(\"Correct\")")
|
||||||
if v != 0:
|
doAssert($(stringNone) == "None[string]")
|
||||||
result = some(v + 1)
|
|
||||||
else:
|
|
||||||
result = none(int)
|
|
||||||
|
|
||||||
doAssert(some(1).flatMap(addOneIfNotZero) == some(2))
|
disableJsVm:
|
||||||
doAssert(some(0).flatMap(addOneIfNotZero) == none(int))
|
block map_with_a_void_result:
|
||||||
doAssert(some(1).flatMap(addOneIfNotZero).flatMap(addOneIfNotZero) == some(3))
|
var procRan = 0
|
||||||
|
# TODO closure anonymous functions doesn't work in VM with JS
|
||||||
|
# Error: cannot evaluate at compile time: procRan
|
||||||
|
some(123).map(proc (v: int) = procRan = v)
|
||||||
|
doAssert procRan == 123
|
||||||
|
intNone.map(proc (v: int) = doAssert false)
|
||||||
|
|
||||||
proc maybeToString(v: int): Option[string] =
|
block map:
|
||||||
if v != 0:
|
doAssert(some(123).map(proc (v: int): int = v * 2) == some(246))
|
||||||
result = some($v)
|
doAssert(intNone.map(proc (v: int): int = v * 2).isNone)
|
||||||
else:
|
|
||||||
result = none(string)
|
|
||||||
|
|
||||||
doAssert(some(1).flatMap(maybeToString) == some("1"))
|
block filter:
|
||||||
|
doAssert(some(123).filter(proc (v: int): bool = v == 123) == some(123))
|
||||||
|
doAssert(some(456).filter(proc (v: int): bool = v == 123).isNone)
|
||||||
|
doAssert(intNone.filter(proc (v: int): bool = doAssert false).isNone)
|
||||||
|
|
||||||
proc maybeExclaim(v: string): Option[string] =
|
block flatMap:
|
||||||
if v != "":
|
proc addOneIfNotZero(v: int): Option[int] =
|
||||||
result = some v & "!"
|
if v != 0:
|
||||||
else:
|
result = some(v + 1)
|
||||||
result = none(string)
|
else:
|
||||||
|
result = none(int)
|
||||||
|
|
||||||
doAssert(some(1).flatMap(maybeToString).flatMap(maybeExclaim) == some("1!"))
|
doAssert(some(1).flatMap(addOneIfNotZero) == some(2))
|
||||||
doAssert(some(0).flatMap(maybeToString).flatMap(maybeExclaim) == none(string))
|
doAssert(some(0).flatMap(addOneIfNotZero) == none(int))
|
||||||
|
doAssert(some(1).flatMap(addOneIfNotZero).flatMap(addOneIfNotZero) == some(3))
|
||||||
|
|
||||||
block SomePointer:
|
proc maybeToString(v: int): Option[string] =
|
||||||
var intref: ref int
|
if v != 0:
|
||||||
doAssert(option(intref).isNone)
|
result = some($v)
|
||||||
intref.new
|
else:
|
||||||
doAssert(option(intref).isSome)
|
result = none(string)
|
||||||
|
|
||||||
let tmp = option(intref)
|
doAssert(some(1).flatMap(maybeToString) == some("1"))
|
||||||
doAssert(sizeof(tmp) == sizeof(ptr int))
|
|
||||||
|
|
||||||
var prc = proc (x: int): int = x + 1
|
proc maybeExclaim(v: string): Option[string] =
|
||||||
doAssert(option(prc).isSome)
|
if v != "":
|
||||||
prc = nil
|
result = some v & "!"
|
||||||
doAssert(option(prc).isNone)
|
else:
|
||||||
|
result = none(string)
|
||||||
|
|
||||||
block:
|
doAssert(some(1).flatMap(maybeToString).flatMap(maybeExclaim) == some("1!"))
|
||||||
doAssert(none[int]().isNone)
|
doAssert(some(0).flatMap(maybeToString).flatMap(maybeExclaim) == none(string))
|
||||||
doAssert(none(int) == none[int]())
|
|
||||||
|
|
||||||
# "$ on typed with .name"
|
block SomePointer:
|
||||||
block:
|
var intref: ref int
|
||||||
type Named = object
|
doAssert(option(intref).isNone)
|
||||||
name: string
|
intref.new
|
||||||
|
doAssert(option(intref).isSome)
|
||||||
|
|
||||||
let nobody = none(Named)
|
let tmp = option(intref)
|
||||||
doAssert($nobody == "None[Named]")
|
doAssert(sizeof(tmp) == sizeof(ptr int))
|
||||||
|
|
||||||
# "$ on type with name()"
|
var prc = proc (x: int): int = x + 1
|
||||||
block:
|
doAssert(option(prc).isSome)
|
||||||
type Person = object
|
prc = nil
|
||||||
myname: string
|
doAssert(option(prc).isNone)
|
||||||
|
|
||||||
let noperson = none(Person)
|
block:
|
||||||
doAssert($noperson == "None[Person]")
|
doAssert(none[int]().isNone)
|
||||||
|
doAssert(none(int) == none[int]())
|
||||||
|
|
||||||
# "Ref type with overloaded `==`"
|
# "$ on typed with .name"
|
||||||
block:
|
block:
|
||||||
let p = some(RefPerson.new())
|
type Named = object
|
||||||
doAssert p.isSome
|
name: string
|
||||||
|
|
||||||
|
let nobody = none(Named)
|
||||||
|
doAssert($nobody == "None[Named]")
|
||||||
|
|
||||||
|
# "$ on type with name()"
|
||||||
|
block:
|
||||||
|
type Person = object
|
||||||
|
myname: string
|
||||||
|
|
||||||
|
let noperson = none(Person)
|
||||||
|
doAssert($noperson == "None[Person]")
|
||||||
|
|
||||||
|
# "Ref type with overloaded `==`"
|
||||||
|
block:
|
||||||
|
let p = some(RefPerson.new())
|
||||||
|
doAssert p.isSome
|
||||||
|
|
||||||
|
block: # test cstring
|
||||||
|
block:
|
||||||
|
let x = some("".cstring)
|
||||||
|
doAssert x.isSome
|
||||||
|
doAssert x.get == ""
|
||||||
|
|
||||||
|
block:
|
||||||
|
let x = some("12345".cstring)
|
||||||
|
doAssert x.isSome
|
||||||
|
doAssert x.get == "12345"
|
||||||
|
|
||||||
|
block:
|
||||||
|
let x = "12345".cstring
|
||||||
|
let y = some(x)
|
||||||
|
doAssert y.isSome
|
||||||
|
doAssert y.get == "12345"
|
||||||
|
|
||||||
|
block:
|
||||||
|
let x = none(cstring)
|
||||||
|
doAssert x.isNone
|
||||||
|
doAssert $x == "None[cstring]"
|
||||||
|
|
||||||
|
|
||||||
|
static: main()
|
||||||
|
main()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue