Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,42 @@ libcjson_utils.so.*
cmake-build-debug
*.lst
*.lss

# Bazel
MODULE.bazel.lock
# Ignore backup files.
*~
# Ignore Vim swap files.
.*.swp
# macOS-specific excludes
.DS_Store
# Ignore files generated by IDEs.
/.aswb/
/.bazelbsp/
/.cache/
/.classpath
/.clwb/
/.factorypath
/.idea/
/.ijwb/
/.project
/.settings
/.vscode/
.eclipse/
.settings/
.classpath
.project
eclipse-*bin/
/bazel.iml
# Ignore all bazel-* symlinks. There is no full list since this can change
# based on the name of the directory bazel is cloned into.
/bazel-*
# Ignore outputs generated during Bazel bootstrapping.
/output/
# Ignore jekyll build output.
/production
/.sass-cache
# Bazelisk version file
.bazelversion
# User-specific .bazelrc
user.bazelrc
76 changes: 76 additions & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")

CJSON_COPTS = select({
"@bazel_tools//src/conditions:darwin": [
"-std=c89", # Standards compliance
"-Wc++-compat", # C++ compatibility
"-fvisibility=hidden", # Symbol visibility
],
"@bazel_tools//src/conditions:linux": [
"-std=c89", # Standards compliance
"-Wc++-compat", # C++ compatibility
"-fstack-protector-strong", # Security (GCC/Clang on Linux supports this)
"-fvisibility=hidden", # Symbol visibility
],
"@bazel_tools//src/conditions:windows": [
"/Za", # Equivalent to -std=c89 (enforce ANSI C)
"/W3", # Moderate warning level (instead of -Wc++-compat)
"/GS", # Stack protection (equivalent to -fstack-protect-strong)
],
})

cc_library(
name = "cjson",
srcs = ["cJSON.c"],
hdrs = ["cJSON.h"],
copts = CJSON_COPTS + [
"-DCJSON_EXPORT_SYMBOLS",
"-DCJSON_API_VISIBILITY",
],
linkopts = select({
"@bazel_tools//src/conditions:windows": [],
"//conditions:default": ["-lm"], # Link math library on non-Windows
}),
visibility = ["//visibility:public"],
)

cc_library(
name = "cjson_utils",
srcs = ["cJSON_Utils.c"],
hdrs = ["cJSON_Utils.h"],
copts = CJSON_COPTS + [
"-DCJSON_EXPORT_SYMBOLS",
"-DCJSON_API_VISIBILITY",
],
visibility = ["//visibility:public"],
deps = [":cjson"],
)

cc_library(
name = "cjson_tests", # Some tests directly include the .c file
hdrs = ["cJSON.c"],
visibility = ["//tests:__pkg__"],
)

cc_test(
name = "cjson_test",
size = "small",
srcs = ["test.c"],
copts = CJSON_COPTS + select({
"@platforms//os:windows": [],
"//conditions:default": [
"-fno-sanitize=float-divide-by-zero",
],
}),
deps = [":cjson"],
)

test_suite(
name = "all_tests",
tests = [
":cjson_test",
"//tests:json_patch_tests",
"//tests:parse_examples",
"//tests:unity_tests",
],
)
14 changes: 14 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""
Module: cjson
Purpose: Provides the cjson library compileable as a Bazel target. Includes general and unity tests through Bazel
Note: cjson_utils target is also available
"""

module(
name = "cjson",
version = "1.7.19-0.20240923110858-12c4bf1986c2",
compatibility_level = 1,
)

bazel_dep(name = "rules_cc", version = "0.1.1")
bazel_dep(name = "platforms", version = "0.0.11")
70 changes: 70 additions & 0 deletions tests/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
load(":tools.bzl", "test_set")

DEPS = [
"//:cjson",
"//:cjson_tests",
"//:cjson_utils",
"//tests/unity",
"//tests/unity:unity-examples",
] + select({
"@platforms//os:windows": [":unity-win"],
"//conditions:default": [],
})

DATA = [
":patch-test_inputs",
":test_inputs",
]

HDRS = glob(["*.h"])

cc_library(
name = "unity-win",
srcs = ["unity_setup.c"],
)

filegroup(
name = "test_inputs",
srcs = glob(["inputs/*"]),
visibility = ["//tests:__pkg__"],
)

filegroup(
name = "patch-test_inputs",
srcs = glob(["json-patch-tests/*.json"]),
visibility = ["//tests:__pkg__"],
)

test_suite(
name = "unity_tests",
tests = test_set(
srcs = HDRS,
data = DATA,
test_files = glob(
["*.c"],
exclude = [
"unity_setup.c",
"parse_examples.c",
"json_patch_tests.c",
],
),
deps = DEPS,
),
)

cc_test(
name = "parse_examples",
srcs = HDRS + ["parse_examples.c"],
copts = ['-DTEST_DIR_PATH=\\"tests/inputs/\\"'],
data = DATA,
deps = DEPS,
)

cc_test(
name = "json_patch_tests",
srcs = HDRS + ["json_patch_tests.c"],
copts = ['-DTEST_DIR_PATH=\\"tests/json-patch-tests/\\"'],
data = DATA,
deps = DEPS,
)
10 changes: 7 additions & 3 deletions tests/json_patch_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
#include "common.h"
#include "../cJSON_Utils.h"

#ifndef TEST_DIR_PATH
#define TEST_DIR_PATH "json-patch-tests/"
#endif

static cJSON *parse_test_file(const char * const filename)
{
char *file = NULL;
Expand Down Expand Up @@ -182,7 +186,7 @@ static cJSON_bool test_generate_test(cJSON *test)

static void cjson_utils_should_pass_json_patch_test_tests(void)
{
cJSON *tests = parse_test_file("json-patch-tests/tests.json");
cJSON *tests = parse_test_file(TEST_DIR_PATH "tests.json");
cJSON *test = NULL;

cJSON_bool failed = false;
Expand All @@ -199,7 +203,7 @@ static void cjson_utils_should_pass_json_patch_test_tests(void)

static void cjson_utils_should_pass_json_patch_test_spec_tests(void)
{
cJSON *tests = parse_test_file("json-patch-tests/spec_tests.json");
cJSON *tests = parse_test_file(TEST_DIR_PATH "spec_tests.json");
cJSON *test = NULL;

cJSON_bool failed = false;
Expand All @@ -216,7 +220,7 @@ static void cjson_utils_should_pass_json_patch_test_spec_tests(void)

static void cjson_utils_should_pass_json_patch_test_cjson_utils_tests(void)
{
cJSON *tests = parse_test_file("json-patch-tests/cjson-utils-tests.json");
cJSON *tests = parse_test_file(TEST_DIR_PATH "cjson-utils-tests.json");
cJSON *test = NULL;

cJSON_bool failed = false;
Expand Down
9 changes: 8 additions & 1 deletion tests/parse_examples.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ static void do_test(const char *test_name)
test_name_length = strlen(test_name);

/* allocate file paths */
#ifndef TEST_DIR_PATH
#define TEST_DIR_PATH "inputs/"
#endif
test_path = (char*)malloc(sizeof(TEST_DIR_PATH) + test_name_length);
TEST_ASSERT_NOT_NULL_MESSAGE(test_path, "Failed to allocate test_path buffer.");
expected_path = (char*)malloc(sizeof(TEST_DIR_PATH) + test_name_length + sizeof(".expected"));
Expand Down Expand Up @@ -136,7 +138,12 @@ static void file_test6_should_not_be_parsed(void)
char *test6 = NULL;
cJSON *tree = NULL;

test6 = read_file("inputs/test6");
char *test_path = NULL;
const char * test_name = "test6";
test_path = (char*)malloc(sizeof(TEST_DIR_PATH) + strlen(test_name));
TEST_ASSERT_NOT_NULL_MESSAGE(test_path, "Failed to allocate test_path buffer.");
sprintf(test_path, TEST_DIR_PATH"%s", test_name);
test6 = read_file(test_path);
TEST_ASSERT_NOT_NULL_MESSAGE(test6, "Failed to read test6 data.");

tree = cJSON_Parse(test6);
Expand Down
44 changes: 44 additions & 0 deletions tests/tools.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Tool for generating C++ test targets efficiently using Bazel rules.
"""

load("@rules_cc//cc:defs.bzl", "cc_test")

def test_set(
test_files = None,
size = "small",
srcs = [],
file_extensions = ".c",
**kwargs):
"""Creates C++ test targets from a list of test files.

Args:
test_files: List of test file paths to process. Defaults to None.
size: Test size parameter for cc_test rule. Defaults to "small".
srcs: Additional source files to include in all tests. Defaults to empty list.
file_extensions: Expected extension of test files. Defaults to ".cpp".
**kwargs: Additional arguments to pass to cc_test rule.

Returns:
List of test target names (e.g., [":test1", ":test2"]).

Note:
Only files ending with the specified file_extensions are processed.
Each test target is created with the filename (without extension) as its name.
"""
test_targets = []

# Process positive tests
for file in test_files:
if not file.endswith(file_extensions):
continue
name = file[:-len(file_extensions)]
target = ":" + name
cc_test(
name = name,
size = size,
srcs = srcs + [file],
**kwargs
)
test_targets.append(target)

return test_targets
27 changes: 27 additions & 0 deletions tests/unity/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
load("@rules_cc//cc:defs.bzl", "cc_library")

cc_library(
name = "unity",
srcs = glob(["src/*.c"]),
hdrs = glob(["src/*.h"]),
copts = select({
"@platforms//os:windows": [
"/wd4100", # Disable warning C4100: unreferenced formal parameter (similar to -Wno-error)
"/wd4065", # Disable warning C4065: switch statement contains default but no case (similar to -Wno-switch-enum)
],
"//conditions:default": [
"-fvisibility=default",
"-fno-sanitize=float-divide-by-zero",
"-Wno-switch-enum",
],
}),
includes = ["src"],
visibility = ["//tests:__pkg__"],
deps = [":unity-examples"],
)

cc_library(
name = "unity-examples",
hdrs = ["examples/unity_config.h"],
visibility = ["//tests:__pkg__"],
)
Loading