gcc(1)
orclang(1)
bash(1)
indent(1)
(optional)make(1)
(optional)
This document is intended for libssc
developers working on the
internals of the library. Please see api.md for the
porcelain/public interfaces for integrating and using this library
in your project or application.
Please check the LICENSE to ensure this library and its license meet your needs.
Contributions to libssc
can be made with a new
pull request opened
on this library's
canonical repository.
If you have discovered an bug or want to open up a discussion, please open an issue on this library's canonical repository.
Please be sure to review the following before committing or opening a
pull request to the libssc
project:
libssc
uses the FFmpeg Coding Rules developer
guidelines in this project with exceptions outlined in this section. For
clarity, some rules are repeated here to give a clear context of
expectations for developers contributing to this library.
TODO
The following outlines indentation requirements for files in the project:
- Indent size is 2
- The TAB character is forbidden with the exceptions of
Makefile
files
This section describes various naming conventions used in libssc
.
All types, structs, functions, variables, and macros exported for public
usage should be namespaced with ssc_
, SSC
, or SSC_
depending on
the defined interface.
All exported types should be
PascalCamelCase and
prefixed with the SSC
namespace.
Example:
typedef unsigned char * SSCByte
All exported structs should be
PascalCamelCase and
prefixed with the SSC
namespace.
Example:
struct SSCBuffer {
SSCBytes bytes;
SSCUSize size;
};
All exported functions and preprocessor functions should be
snake_case and prefixed with
the ssc_
namespace.
Example:
#define ssc_buffer(value) (SSCBuffer) (value)
SSC_EXPORT const SSCResult
ssc_buffer_compare (const SSCBuffer self, const SSCBuffer right);
All globally (static
) exported, externally (extern
) linked, or
preprocessor macro variables should be
snake_case and prefixed with the
ssc_
namespace.
Example:
static SSCBoolean ssc_some_boolean = SSC_FALSE;
extern SSCString *ssc_some_extern_string = 0;
#define ssc_argc ssc_init_argc
#define ssc_argv ssc_init_argv
All preprocessor macros should be
SCREAMING_SNAKE_CASE and prefixed
with the SSC_
namespace.
Example:
#define SSC_VSNPRINTF vsnprintf
#define SSC_PP_STRING(value) SSC_PP_STRINGX(value)
#define SSC_PP_STRINGX(value) #value
TODO
TODO
TODO
TODO
TODO
TODO
Tests are single context executables that emit
TAP output. Tests make use of a self hosted
<ssc/test.h>
header file that provides
various macros and functions for making assertions that output TAP
compliant logs.
The runner for each test can be invoke with a make
target from the
root of the repository.
make tests/$TARGET
where $TARGET
is the test to run which corresponds to a single .c
file in the tests/
directory.
Example:
Run string
and uri
tests:
make tests/string tests/uri
Run many tests with brace expansion:
make tests/{string,ipc,uri,error}
All tests can be run by simply invoking:
make tests
This section describes the C API exposed by the <ssc/test.h>
A simple TAP test runner context.
name
The name of the test contextexpected
The expected number of passed tests.0
means there is no expected count.
Example:
#include <ssc/test.h>
test("a simple test", 2) {
assert(1 + 1 == 2);
assert_equal(2, 2);
assert_not_equal(2, 3);
}
Output:
TAP version 14
# a simple test
1..3
ok 1 - 1 + 1 == 2
ok 2 - 2 equals 2
ok 3 - 2 not equals 3
A simple macro to skip tests instead of running them marked by the leading
x
character intest(...)
Example:
#include <ssc/test.h>
xtest("a simple skipped test", 3) {
assert(1 + 1 == 2);
assert_equal(2, 2);
assert_not_equal(2, 3);
}
Output:
TAP version 14
# a simple skipped test
1..0
A simple assertion that emits
ok ...
ornot ok ...
Example:
assert(1 + 1 == 3);
assert(1 != 2);
A simple assertion that emits
ok ...
ornot ok ...
along with a caught error that is printed as a TAP error
Example:
#include <ssc/test.h>
test("error", 0) {
assert_ok(ssc_throw(SSC_ERROR, "ooops"));
}
Output:
TAP version 14
# error
ok 1 (SSCResult) (SSC_OK)
not ok 1 - ssc_error_throw( SSC_ERROR, "ooops", (SSCString)("error.c"), (SSCUSize) (35), (SSCString)(__PRETTY_FUNCTION__) ) [runner (error.c:35)]
---
message: (runner): ooops
severity: fail
at:
file: error.c
line: 35
---
1..2
# tests 2
# fail 1
# pass 1
A simple negated assertion that emits
ok ...
ornot ok ...
along with a caught error that is printed as a TAP error
Example:
#include <ssc/test.h>
test("error", 0) {
assert_notok(ssc_throw(SSC_ERROR, "oops"));
}
Output:
TAP version 14
# error
ok 1 - ssc_error_throw( SSC_ERROR, "oops", (SSCString)("error.c"), (SSCUSize) (35), (SSCString)(__PRETTY_FUNCTION__) )
not ok 2 - (SSCResult) (SSC_OK) [runner (error.c:36)]
---
message: (runner): oops
severity: fail
at:
file: error.c
line: 35
---
1..2
# tests 2
# fail 1
# pass 1
A simple assertion that emits
ok ...
ornot ok ...
based on the givenleft
andright
values inequality being true.
Example:
test("error", 0) {
assert_equal(1, 1);
assert_equal(2, 2);
}
A simple assertion that emits
ok ...
ornot ok ...
based on the givenleft
andright
values equality being true.
Example:
test("error", 0) {
assert_not_equal(1, 2);
assert_not_equal(2, 3);
}
Simple
ok()
emission for a passed test.
Example:
test("ok", 0) {
ok("a test passed");
}
Simple
notok()
emission for a failed test.
Example:
test("notok", 0) {
notok("a test failed");
}
Simple skipped
ok()
with '#SKIP' emission for a pending test.
Example:
test("okskip", 0) {
okskip("a skipped test assertion");
}
Simple skipped
notok()
with '#SKIP' emission for a pending test.
Example:
test("okskip", 0) {
notokskip("a skipped failing test assertion");
}
Simple skipped
ok()
with '#TODO' emission for a pending test.
Example:
test("oktodo", 0) {
oktodo("a pending test assertion marked as TODO");
}
Simple skipped
notok()
with '#TODO' emission for a pending test.
Example:
test("oktodo", 0) {
notoktodo("a pending failed test assertion marked as TODO");
}