File: json_eq.c

package info (click to toggle)
liblognorm 2.0.9-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,696 kB
  • sloc: ansic: 11,634; sh: 2,639; makefile: 255; python: 34
file content (93 lines) | stat: -rw-r--r-- 2,787 bytes parent folder | download | duplicates (5)
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
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <json.h>
#include "internal.h"


typedef struct json_object obj;

static int eq(obj* expected, obj* actual);

static int obj_eq(obj* expected, obj* actual) {
	int eql = 1;
	struct json_object_iterator it = json_object_iter_begin(expected);
	struct json_object_iterator itEnd = json_object_iter_end(expected);
	while (!json_object_iter_equal(&it, &itEnd)) {
		obj *actual_val;
		json_object_object_get_ex(actual, json_object_iter_peek_name(&it), &actual_val);
		eql &= eq(json_object_iter_peek_value(&it), actual_val);
		json_object_iter_next(&it);
	}
	return eql;
}

static int arr_eq(obj* expected, obj* actual) {
	int eql = 1;
	int expected_len = json_object_array_length(expected);
	int actual_len = json_object_array_length(actual);
	if (expected_len != actual_len) return 0;
		for (int i = 0; i < expected_len; i++) {
			obj* exp = json_object_array_get_idx(expected, i);
			obj* act = json_object_array_get_idx(actual, i);
			eql &= eq(exp, act);
		}
	return eql;
}

static int str_eq(obj* expected, obj* actual) {
	const char* exp_str = json_object_to_json_string(expected);
	const char* act_str = json_object_to_json_string(actual);
	return strcmp(exp_str, act_str) == 0;
}

static int eq(obj* expected, obj* actual) {
	if (expected == NULL && actual == NULL) {
		return 1;
	} else if (expected == NULL) {
		return 0;
	} else if (actual == NULL) {
		return 0;
	}
	enum json_type expected_type = json_object_get_type(expected);
	enum json_type actual_type = json_object_get_type(actual);
	if (expected_type != actual_type) return 0;
	switch(expected_type) {
	case json_type_null:
		return 1;
	case json_type_boolean:
		return json_object_get_boolean(expected) == json_object_get_boolean(actual);
	case json_type_double:
		return (fabs(json_object_get_double(expected) - json_object_get_double(actual)) < 0.001);
	case json_type_int:
		return json_object_get_int64(expected) == json_object_get_int64(actual);
	case json_type_object:
		return obj_eq(expected, actual);
	case json_type_array:
		return arr_eq(expected, actual);
	case json_type_string:
		return str_eq(expected, actual);
	default:
		fprintf(stderr, "unexpected type in %s:%d\n", __FILE__, __LINE__);
		abort();
	}
	return 0;
}

int main(int argc, char** argv) {
	if (argc != 3) {
		fprintf(stderr, "expected and actual json not given, number of args was: %d\n", argc);
		exit(100);
	}
	obj* expected = json_tokener_parse(argv[1]);
	obj* actual = json_tokener_parse(argv[2]);
	int result = eq(expected, actual) ? 0 : 1;
	json_object_put(expected);
	json_object_put(actual);
	if (result != 0) {
		printf("JSONs weren't equal. \n\tExpected: \n\t\t%s\n\tActual: \n\t\t%s\n", argv[1], argv[2]);
	}
	return result;
}