blob: f1c3e9f3c572b1f39f30cffc0d4ed7ec531736b5 [file] [log] [blame]
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "apr_json.h"
#include "abts.h"
#include "testutil.h"
static void test_json_identity(abts_case * tc, void *data)
{
apr_json_value_t *json = NULL;
apr_json_kv_t *image, *width, *ids, *title,
*animated, *thumbnail, *height;
apr_bucket_alloc_t *ba;
apr_bucket_brigade *bb;
const char *src;
char buf[1024];
apr_size_t len = sizeof(buf);
apr_off_t offset = 0;
ba = apr_bucket_alloc_create(p);
bb = apr_brigade_create(p, ba);
src = "{"
" \"Image\" : {"
" \"Width\" : 800 ,"
" \"IDs\" : [116, 943, 234, 38793],"
" \"Title\" : \"View from 15th Floor\","
" \"Animated\" : false,"
" \"Thumbnail\" : {"
" \"Height\" : 125,"
" \"Width\" : 100,"
" \"Url\" : \"http://www.example.com/image/481989943\""
" },"
" \"Height\" : 600 "
" }"
"}";
apr_json_decode(&json, src, APR_JSON_VALUE_STRING, &offset, APR_JSON_FLAGS_WHITESPACE,
10, p);
apr_json_encode(bb, NULL, NULL, json, APR_JSON_FLAGS_WHITESPACE, p);
apr_brigade_flatten(bb, buf, &len);
apr_json_decode(&json, buf, len, &offset, APR_JSON_FLAGS_WHITESPACE, 10, p);
ABTS_STR_NEQUAL(tc, src, buf, len);
ABTS_INT_EQUAL(tc, len, offset);
ABTS_INT_EQUAL(tc, APR_JSON_OBJECT, json->type);
image = apr_hash_get(json->value.object->hash, "Image", 5);
ABTS_PTR_NOTNULL(tc, image);
width = apr_hash_get(image->v->value.object->hash, "Width", 5);
ABTS_PTR_NOTNULL(tc, width);
ABTS_INT_EQUAL(tc, APR_JSON_LONG, width->v->type);
ABTS_INT_EQUAL(tc, 800, width->v->value.lnumber);
ids = apr_hash_get(image->v->value.object->hash, "IDs", 3);
ABTS_PTR_NOTNULL(tc, ids);
ABTS_INT_EQUAL(tc, APR_JSON_ARRAY, ids->v->type);
title = apr_hash_get(image->v->value.object->hash, "Title", 5);
ABTS_PTR_NOTNULL(tc, title);
ABTS_INT_EQUAL(tc, APR_JSON_STRING, title->v->type);
animated = apr_hash_get(image->v->value.object->hash, "Animated", 8);
ABTS_PTR_NOTNULL(tc, animated);
ABTS_INT_EQUAL(tc, APR_JSON_BOOLEAN, animated->v->type);
ABTS_TRUE(tc, !animated->v->value.boolean);
thumbnail = apr_hash_get(image->v->value.object->hash, "Thumbnail", 9);
ABTS_PTR_NOTNULL(tc, thumbnail);
ABTS_INT_EQUAL(tc, APR_JSON_OBJECT, thumbnail->v->type);
height = apr_hash_get(image->v->value.object->hash, "Height", 6);
ABTS_PTR_NOTNULL(tc, height);
ABTS_INT_EQUAL(tc, APR_JSON_LONG, height->v->type);
ABTS_INT_EQUAL(tc, 600, height->v->value.lnumber);
}
static void test_json_level(abts_case * tc, void *data)
{
apr_json_value_t *json = NULL;
apr_status_t status;
const char *src;
apr_off_t offset = 0;
src = "{"
"\"One\":{"
"\"Two\":{"
"\"Three\":{";
status = apr_json_decode(&json, src, APR_JSON_VALUE_STRING, &offset,
APR_JSON_FLAGS_WHITESPACE, 2, p);
ABTS_INT_EQUAL(tc, APR_EINVAL, status);
}
static void test_json_eof(abts_case * tc, void *data)
{
apr_json_value_t *json = NULL;
apr_status_t status;
const char *src;
apr_off_t offset = 0;
src = "{"
"\"One\":{"
"\"Two\":{"
"\"Three\":{";
status = apr_json_decode(&json, src, APR_JSON_VALUE_STRING, &offset,
APR_JSON_FLAGS_WHITESPACE, 10, p);
ABTS_INT_EQUAL(tc, APR_EOF, status);
}
static void test_json_string(abts_case * tc, void *data)
{
apr_json_value_t *json = NULL;
apr_status_t status;
const char *src;
apr_off_t offset = 0;
/* "턞\"\t/\b\f\n\r\t"; */
const unsigned char expected[] = {237, 132, 158, 34, 9, 47, 8, 12, 10, 13, 9, 0};
src = "\"\\uD834\\uDD1E\\\"\\t\\/\\b\\f\\n\\r\\t\"";
status = apr_json_decode(&json, src, APR_JSON_VALUE_STRING, &offset,
APR_JSON_FLAGS_WHITESPACE, 10, p);
ABTS_INT_EQUAL(tc, APR_SUCCESS, status);
ABTS_INT_EQUAL(tc, APR_JSON_STRING, json->type);
ABTS_ASSERT(tc, "check for string unescape match",
(memcmp(expected, json->value.string.p, json->value.string.len) == 0));
}
static void test_json_overlay(abts_case * tc, void *data)
{
const char *o = "{\"o1\":\"foo\",\"common\":\"bar\",\"o2\":\"baz\"}";
const char *b = "{\"b1\":\"foo\",\"common\":\"bar\",\"b2\":\"baz\"}";
apr_json_value_t *res;
apr_json_value_t *base;
apr_json_value_t *overlay;
apr_off_t offset;
apr_status_t status;
status = apr_json_decode(&base, b, APR_JSON_VALUE_STRING, &offset,
APR_JSON_FLAGS_WHITESPACE, 10, p);
ABTS_INT_EQUAL(tc, APR_SUCCESS, status);
status = apr_json_decode(&overlay, o, APR_JSON_VALUE_STRING, &offset,
APR_JSON_FLAGS_WHITESPACE, 10, p);
ABTS_INT_EQUAL(tc, APR_SUCCESS, status);
res = apr_json_overlay(p, overlay, base, APR_JSON_FLAGS_NONE);
ABTS_INT_EQUAL(tc, 5, apr_hash_count(res->value.object->hash));
res = apr_json_overlay(p, overlay, base, APR_JSON_FLAGS_STRICT);
ABTS_ASSERT(tc, "overlay strict should return NULL",
(res == NULL));
}
static void test_json_object_iterate(abts_case * tc, void *data)
{
const char *o = "{\"o1\":\"foo\",\"o2\":\"bar\"}";
apr_json_value_t *val;
apr_json_kv_t *kv;
apr_off_t offset;
apr_status_t status;
status = apr_json_decode(&val, o, APR_JSON_VALUE_STRING, &offset,
APR_JSON_FLAGS_WHITESPACE, 10, p);
ABTS_INT_EQUAL(tc, APR_SUCCESS, status);
kv = apr_json_object_first(val);
ABTS_PTR_NOTNULL(tc, kv);
kv = apr_json_object_next(val, kv);
ABTS_PTR_NOTNULL(tc, kv);
kv = apr_json_object_next(val, kv);
ABTS_ASSERT(tc, "object next should return NULL",
(kv == NULL));
}
static void test_json_array_iterate(abts_case * tc, void *data)
{
const char *o = "[\"a1\",\"a2\"]";
apr_json_value_t *arr;
apr_json_value_t *val;
apr_off_t offset;
apr_status_t status;
status = apr_json_decode(&arr, o, APR_JSON_VALUE_STRING, &offset,
APR_JSON_FLAGS_WHITESPACE, 10, p);
ABTS_INT_EQUAL(tc, APR_SUCCESS, status);
val = apr_json_array_first(arr);
ABTS_PTR_NOTNULL(tc, val);
val = apr_json_array_next(arr, val);
ABTS_PTR_NOTNULL(tc, val);
val = apr_json_array_next(arr, val);
ABTS_ASSERT(tc, "array next should return NULL",
(val == NULL));
}
abts_suite *testjson(abts_suite * suite)
{
suite = ADD_SUITE(suite);
abts_run_test(suite, test_json_identity, NULL);
abts_run_test(suite, test_json_level, NULL);
abts_run_test(suite, test_json_eof, NULL);
abts_run_test(suite, test_json_string, NULL);
abts_run_test(suite, test_json_overlay, NULL);
abts_run_test(suite, test_json_object_iterate, NULL);
abts_run_test(suite, test_json_array_iterate, NULL);
return suite;
}