1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
/*
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
*
* Jansson is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <jansson.h>
#include <string.h>
#include "util.h"
static void file_not_found()
{
json_t *json;
json_error_t error;
char *pos;
json = json_load_file("/path/to/nonexistent/file.json", 0, &error);
if(json)
fail("json_load_file returned non-NULL for a nonexistent file");
if(error.line != -1)
fail("json_load_file returned an invalid line number");
/* The error message is locale specific, only check the beginning
of the error message. */
pos = strchr(error.text, ':');
if(!pos)
fail("json_load_file returne an invalid error message");
*pos = '\0';
if(strcmp(error.text, "unable to open /path/to/nonexistent/file.json") != 0)
fail("json_load_file returned an invalid error message");
}
static void reject_duplicates()
{
json_error_t error;
if(json_loads("{\"foo\": 1, \"foo\": 2}", JSON_REJECT_DUPLICATES, &error))
fail("json_loads did not detect a duplicate key");
check_error("duplicate object key near '\"foo\"'", "<string>", 1, 16, 16);
}
static void disable_eof_check()
{
json_error_t error;
json_t *json;
const char *text = "{\"foo\": 1} garbage";
if(json_loads(text, 0, &error))
fail("json_loads did not detect garbage after JSON text");
check_error("end of file expected near 'garbage'", "<string>", 1, 18, 18);
json = json_loads(text, JSON_DISABLE_EOF_CHECK, &error);
if(!json)
fail("json_loads failed with JSON_DISABLE_EOF_CHECK");
json_decref(json);
}
static void decode_any()
{
json_t *json;
json_error_t error;
json = json_loads("\"foo\"", JSON_DECODE_ANY, &error);
if (!json || !json_is_string(json))
fail("json_load decoded any failed - string");
json_decref(json);
json = json_loads("42", JSON_DECODE_ANY, &error);
if (!json || !json_is_integer(json))
fail("json_load decoded any failed - integer");
json_decref(json);
json = json_loads("true", JSON_DECODE_ANY, &error);
if (!json || !json_is_true(json))
fail("json_load decoded any failed - boolean");
json_decref(json);
json = json_loads("null", JSON_DECODE_ANY, &error);
if (!json || !json_is_null(json))
fail("json_load decoded any failed - null");
json_decref(json);
}
static void decode_int_as_real()
{
json_t *json;
json_error_t error;
#if JSON_INTEGER_IS_LONG_LONG
const char *imprecise;
json_int_t expected;
#endif
json = json_loads("42", JSON_DECODE_INT_AS_REAL | JSON_DECODE_ANY, &error);
if (!json || !json_is_real(json) || json_real_value(json) != 42.0)
fail("json_load decode int as real failed - int");
json_decref(json);
#if JSON_INTEGER_IS_LONG_LONG
/* This number cannot be represented exactly by a double */
imprecise = "9007199254740993";
expected = 9007199254740992ll;
json = json_loads(imprecise, JSON_DECODE_INT_AS_REAL | JSON_DECODE_ANY,
&error);
if (!json || !json_is_real(json) || expected != (json_int_t)json_real_value(json))
fail("json_load decode int as real failed - expected imprecision");
json_decref(json);
#endif
}
static void allow_nul()
{
const char *text = "\"nul byte \\u0000 in string\"";
const char *expected = "nul byte \0 in string";
size_t len = 20;
json_t *json;
json = json_loads(text, JSON_ALLOW_NUL | JSON_DECODE_ANY, NULL);
if(!json || !json_is_string(json))
fail("unable to decode embedded NUL byte");
if(json_string_length(json) != len)
fail("decoder returned wrong string length");
if(memcmp(json_string_value(json), expected, len + 1))
fail("decoder returned wrong string content");
json_decref(json);
}
static void load_wrong_args()
{
json_t *json;
json_error_t error;
json = json_loads(NULL, 0, &error);
if (json)
fail("json_loads should return NULL if the first argument is NULL");
json = json_loadb(NULL, 0, 0, &error);
if (json)
fail("json_loadb should return NULL if the first argument is NULL");
json = json_loadf(NULL, 0, &error);
if (json)
fail("json_loadf should return NULL if the first argument is NULL");
json = json_load_file(NULL, 0, &error);
if (json)
fail("json_loadf should return NULL if the first argument is NULL");
}
static void position()
{
json_t *json;
size_t flags = JSON_DISABLE_EOF_CHECK;
json_error_t error;
json = json_loads("{\"foo\": \"bar\"}", 0, &error);
if(error.position != 14)
fail("json_loads returned a wrong position");
json_decref(json);
json = json_loads("{\"foo\": \"bar\"} baz quux", flags, &error);
if(error.position != 14)
fail("json_loads returned a wrong position");
json_decref(json);
}
static void run_tests()
{
file_not_found();
reject_duplicates();
disable_eof_check();
decode_any();
decode_int_as_real();
allow_nul();
load_wrong_args();
position();
}
|