summary refs log tree commit diff stats
path: root/tests/cpp/tcasts.nim
blob: d968d87dbd097d70e8a5ed7bac64e68bac57ce40 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
discard """
  cmd: "nim cpp $file"
  output: '''{"vas": "kas", "123": "123"}'''
  targets: "cpp"
"""

block: #5979
  var a = 'a'
  var p: pointer = cast[pointer](a)
  var c = cast[char](p)
  doAssert(c == 'a')


#----------------------------------------------------
# bug #9739
import tables

var t = initTable[string, string]()
discard t.hasKeyOrPut("123", "123")
discard t.mgetOrPut("vas", "kas")
echo t
eric.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
#[
Note: Macro tests are in tests/stdlib/tjsonmacro.nim
]#

import std/[json,parsejson,strutils,streams]

let testJson = parseJson"""{ "a": [1, 2, 3, 4], "b": "asd", "c": "\ud83c\udf83", "d": "\u00E6"}"""
# nil passthrough
doAssert(testJson{"doesnt_exist"}{"anything"}.isNil)
testJson{["e", "f"]} = %true
doAssert(testJson["e"]["f"].bval)

# make sure UTF-16 decoding works.
doAssert(testJson["c"].str == "🎃")
doAssert(testJson["d"].str == "æ")

# make sure no memory leek when parsing invalid string
let startMemory = getOccupiedMem()
for i in 0 .. 10000:
  try:
    discard parseJson"""{ invalid"""
  except:
    discard
# memory diff should less than 4M
doAssert(abs(getOccupiedMem() - startMemory) < 4 * 1024 * 1024)


# test `$`
let stringified = $testJson
let parsedAgain = parseJson(stringified)
doAssert(parsedAgain["b"].str == "asd")

parsedAgain["abc"] = %5
doAssert parsedAgain["abc"].num == 5

# Bounds checking
when compileOption("boundChecks"):
  try:
    let a = testJson["a"][9]
    doAssert(false, "IndexDefect not thrown")
  except IndexDefect:
    discard
  try:
    let a = testJson["a"][-1]
    doAssert(false, "IndexDefect not thrown")
  except IndexDefect:
    discard
  try:
    doAssert(testJson["a"][0].num == 1, "Index doesn't correspond to its value")
  except:
    doAssert(false, "IndexDefect thrown for valid index")

doAssert(testJson{"b"}.getStr() == "asd", "Couldn't fetch a singly nested key with {}")
doAssert(isNil(testJson{"nonexistent"}), "Non-existent keys should return nil")
doAssert(isNil(testJson{"a", "b"}), "Indexing through a list should return nil")
doAssert(isNil(testJson{"a", "b"}), "Indexing through a list should return nil")
doAssert(testJson{"a"} == parseJson"[1, 2, 3, 4]", "Didn't return a non-JObject when there was one to be found")
doAssert(isNil(parseJson("[1, 2, 3]"){"foo"}), "Indexing directly into a list should return nil")

# Generator:
var j = %* [{"name": "John", "age": 30}, {"name": "Susan", "age": 31}]
doAssert j == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]

var j2 = %*
  [
    {
      "name": "John",
      "age": 30
    },
    {
      "name": "Susan",
      "age": 31
    }
  ]
doAssert j2 == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]

var name = "John"
let herAge = 30
const hisAge = 31

var j3 = %*
  [ {"name": "John"
    , "age": herAge
    }
  , {"name": "Susan"
    , "age": hisAge
    }
  ]
doAssert j3 == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]

var j4 = %*{"test": nil}
doAssert j4 == %{"test": newJNull()}

let seqOfNodes = @[%1, %2]
let jSeqOfNodes = %seqOfNodes
doAssert(jSeqOfNodes[1].num == 2)

type MyObj = object
  a, b: int
  s: string
  f32: float32
  f64: float64
  next: ref MyObj
var m: MyObj
m.s = "hi"
m.a = 5
let jMyObj = %m
doAssert(jMyObj["a"].num == 5)
doAssert(jMyObj["s"].str == "hi")

# Test loading of file.
when not defined(js):
  var parsed = parseFile("tests/testdata/jsontest.json")

  try:
    discard parsed["key2"][12123]
    doAssert(false)
  except IndexDefect: doAssert(true)

  var parsed2 = parseFile("tests/testdata/jsontest2.json")
  doAssert(parsed2{"repository", "description"}.str ==
      "IRC Library for Haskell", "Couldn't fetch via multiply nested key using {}")

doAssert escapeJsonUnquoted("\10Foo🎃barÄ") == "\\nFoo🎃barÄ"
doAssert escapeJsonUnquoted("\0\7\20") == "\\u0000\\u0007\\u0014" # for #7887
doAssert escapeJson("\10Foo🎃barÄ") == "\"\\nFoo🎃barÄ\""
doAssert escapeJson("\0\7\20") == "\"\\u0000\\u0007\\u0014\"" # for #7887

# Test with extra data
when not defined(js):
  try:
    discard parseJson("123 456")
    doAssert(false)
  except JsonParsingError:
    doAssert getCurrentExceptionMsg().contains(errorMessages[errEofExpected])

  try:
    discard parseFile("tests/testdata/jsonwithextradata.json")
    doAssert(false)
  except JsonParsingError:
    doAssert getCurrentExceptionMsg().contains(errorMessages[errEofExpected])

# bug #6438
doAssert($ %*[] == "[]")
doAssert($ %*{} == "{}")

doAssert(not compiles(%{"error": "No messages"}))

# bug #9111
block:
  type
    Bar = string
    Foo = object
      a: int
      b: Bar

  let
    js = """{"a": 123, "b": "abc"}""".parseJson
    foo = js.to Foo

  doAssert(foo.b == "abc")

# Generate constructors for range[T] types
block:
  type
    Q1 = range[0'u8 .. 50'u8]
    Q2 = range[0'u16 .. 50'u16]
    Q3 = range[0'u32 .. 50'u32]
    Q4 = range[0'i8 .. 50'i8]
    Q5 = range[0'i16 .. 50'i16]
    Q6 = range[0'i32 .. 50'i32]
    Q7 = range[0'f32 .. 50'f32]
    Q8 = range[0'f64 .. 50'f64]
    Q9 = range[0 .. 50]

    X = object
      m1: Q1
      m2: Q2
      m3: Q3
      m4: Q4
      m5: Q5
      m6: Q6
      m7: Q7
      m8: Q8
      m9: Q9

  let obj = X(
    m1: Q1(42),
    m2: Q2(42),
    m3: Q3(42),
    m4: Q4(42),
    m5: Q5(42),
    m6: Q6(42),
    m7: Q7(42),
    m8: Q8(42),
    m9: Q9(42)
  )

  doAssert(obj == to(%obj, type(obj)))

  when not defined(js):
    const fragments = """[1,2,3] {"hi":3} 12 [] """
    var res = ""
    for x in parseJsonFragments(newStringStream(fragments)):
      res.add($x)
      res.add " "
    doAssert res == fragments


# test isRefSkipDistinct
type
  MyRef = ref object
  MyObject = object
  MyDistinct = distinct MyRef
  MyOtherDistinct = distinct MyRef

var x0: ref int
var x1: MyRef
var x2: MyObject
var x3: MyDistinct
var x4: MyOtherDistinct

doAssert isRefSkipDistinct(x0)
doAssert isRefSkipDistinct(x1)
doAssert not isRefSkipDistinct(x2)
doAssert isRefSkipDistinct(x3)
doAssert isRefSkipDistinct(x4)


doAssert isRefSkipDistinct(ref int)
doAssert isRefSkipDistinct(MyRef)
doAssert not isRefSkipDistinct(MyObject)
doAssert isRefSkipDistinct(MyDistinct)
doAssert isRefSkipDistinct(MyOtherDistinct)

let x = parseJson("9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999")
doAssert x.kind == JString