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
1 change: 1 addition & 0 deletions parser/c_parser/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*.o
zdoc-c-parser
c_parser_test
19 changes: 15 additions & 4 deletions parser/c_parser/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ else
fixpath = $1
endif

OBJS = c_parser.o main.o
OBJS = c_parser.o main.o
TEST_BIN = c_parser_test$(EXE)
TEST_OBJS = tests/c_parser_test.o

SHARED_H = ../shared/parser_shared.h ../../extractor/doc_extractor/module_tree/modtree_tables.h

Expand All @@ -38,10 +40,19 @@ $(BIN): $(OBJS)
c_parser.o: c_parser.c c_parser.h $(SHARED_H)
main.o: main.c c_parser.h $(SHARED_H)

test: $(BIN)
$(RUN) tests/sample.c tests/sample.cpp
tests/c_parser_test.o: tests/c_parser_test.c c_parser.h $(SHARED_H)

$(TEST_BIN): c_parser.o $(TEST_OBJS)
$(CC) $(CFLAGS) -o $@ c_parser.o $(TEST_OBJS)

test: $(TEST_BIN)
ifdef WINDOWS_CMD
$(TEST_BIN)
else
./$(TEST_BIN)
endif

clean:
-$(RM) $(call fixpath,$(BIN) $(OBJS))
-$(RM) $(call fixpath,$(BIN) $(OBJS) $(TEST_BIN) $(TEST_OBJS))

.PHONY: all test clean
89 changes: 89 additions & 0 deletions parser/c_parser/tests/c_parser_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Unit tests for c_parser, exercised against tests/sample.c. Asserts on
* exact expected symbols instead of just dumping output for a human to
* eyeball - a mismatch here is a real regression, not something to read
* and judge by hand.
*/
#include "../c_parser.h"
#include "../../shared/parser_shared.h"

#include <stdio.h>
#include <string.h>

static int failures = 0;

#define CHECK(cond, msg) \
do { \
if (!(cond)) { \
fprintf(stderr, "FAIL: %s (%s:%d)\n", msg, __FILE__, __LINE__); \
failures++; \
} \
} while (0)

#define CHECK_STR(a, b, msg) \
CHECK((a) != NULL && (b) != NULL && strcmp((a), (b)) == 0, msg)

static void check_no_symbol_named(const Module *m, const char *name, const char *msg) {
for (int i = 0; i < m->symbolCount; i++)
CHECK(strcmp(m->symbols[i].name, name) != 0, msg);
}

int main(void) {
Module *m = cp_parse_file("tests/sample.c");
CHECK(m != NULL, "cp_parse_file returned NULL");
if (!m) {
fprintf(stderr, "aborting: no module to check further\n");
return 1;
}

CHECK(m->symbolCount == 9, "expected exactly 9 documented symbols");

/* Explicit negative coverage: the fixture calls these out by name as
* things that must NOT be attached/extracted. */
check_no_symbol_named(m, "SAMPLE_H_GUARD", "undocumented object-like macro must be skipped");
check_no_symbol_named(m, "internal_counter", "variable preceded only by a plain comment must be skipped");

if (m->symbolCount > 0) {
Symbol *s = &m->symbols[0];
CHECK_STR(s->name, "MAX_RETRIES", "symbol[0] name");
CHECK_STR(s->type, "macro", "symbol[0] type");
CHECK(s->line == 9, "symbol[0] line");
CHECK_STR(s->description, "Maximum number of retries before giving up.", "symbol[0] brief");
}

if (m->symbolCount > 2) {
Symbol *s = &m->symbols[2];
CHECK_STR(s->name, "widget_init", "symbol[2] name");
CHECK_STR(s->type, "prototype", "symbol[2] type");
CHECK(s->line == 26, "symbol[2] line");
CHECK_STR(s->description, "Initialise the widget subsystem.", "symbol[2] brief");
CHECK_STR(s->output, "0 on success, 8 on storage failure", "symbol[2] returns");
CHECK_STR(s->notes, "Allocates the anchor control block and chains it. Not thread safe.",
"symbol[2] notes");
CHECK(s->inputCount == 2, "symbol[2] param count");
if (s->inputCount == 2) {
CHECK_STR(s->input[0].name, "anchor", "symbol[2] param[0] name");
CHECK_STR(s->input[0].description, "pointer to the anchor block", "symbol[2] param[0] desc");
CHECK_STR(s->input[1].name, "flags", "symbol[2] param[1] name");
CHECK_STR(s->input[1].description, "initialisation flags", "symbol[2] param[1] desc");
}
}

if (m->symbolCount > 8) {
Symbol *s = &m->symbols[8];
CHECK_STR(s->name, "widget_reset", "symbol[8] name");
CHECK_STR(s->type, "function", "symbol[8] type");
CHECK(s->line == 62, "symbol[8] line");
CHECK_STR(s->description, "Line-comment style doc. Second line of the brief.",
"symbol[8] brief (multi-line // doc joined)");
}

cp_free_module(m);

if (failures) {
fprintf(stderr, "c_parser_test: %d assertion(s) FAILED\n", failures);
return 1;
}
printf("c_parser_test: all assertions passed\n");
return 0;
}
1 change: 1 addition & 0 deletions parser/java_parser/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
*.o
zdoc-java-parser
java_parser_test
*.dSYM/
tests/big.java
tests/small.java
21 changes: 18 additions & 3 deletions parser/java_parser/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ CFLAGS = -O2 -Wall -Wextra -std=c11
TARGET = zdoc-java-parser
OBJS = main.o java_parser.o doc_comment.o

TEST_BIN = java_parser_test
TEST_OBJS = tests/java_parser_test.o

SHARED_H = ../shared/parser_shared.h ../../extractor/doc_extractor/module_tree/modtree_tables.h

all: $(TARGET)
Expand All @@ -14,13 +17,25 @@ main.o: main.c java_parser.h $(SHARED_H)
java_parser.o: java_parser.c java_parser.h util.h doc_comment.h $(SHARED_H)
doc_comment.o: doc_comment.c doc_comment.h util.h java_parser.h $(SHARED_H)

tests/java_parser_test.o: tests/java_parser_test.c java_parser.h $(SHARED_H)

$(TEST_BIN): java_parser.o doc_comment.o $(TEST_OBJS)
$(CC) $(CFLAGS) -o $@ java_parser.o doc_comment.o $(TEST_OBJS)

test: $(TEST_BIN)
ifeq ($(OS),Windows_NT)
$(TEST_BIN)
else
./$(TEST_BIN)
endif

ifeq ($(OS),Windows_NT)
clean: SHELL := cmd.exe
clean:
-del /f /q $(subst /,\,$(TARGET) $(TARGET).exe $(OBJS)) 2>NUL
-del /f /q $(subst /,\,$(TARGET) $(TARGET).exe $(OBJS) $(TEST_BIN) $(TEST_BIN).exe $(TEST_OBJS)) 2>NUL
else
clean:
rm -f $(TARGET) $(OBJS)
rm -f $(TARGET) $(OBJS) $(TEST_BIN) $(TEST_OBJS)
endif

.PHONY: all clean
.PHONY: all test clean
83 changes: 83 additions & 0 deletions parser/java_parser/tests/java_parser_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Unit tests for java_parser, exercised against tests/TestKek.java. Asserts
* on exact expected symbols instead of relying on a human to eyeball
* printed output.
*/
#include "../java_parser.h"

#include <stdio.h>
#include <string.h>

static int failures = 0;

#define CHECK(cond, msg) \
do { \
if (!(cond)) { \
fprintf(stderr, "FAIL: %s (%s:%d)\n", msg, __FILE__, __LINE__); \
failures++; \
} \
} while (0)

#define CHECK_STR(a, b, msg) \
CHECK((a) != NULL && (b) != NULL && strcmp((a), (b)) == 0, msg)

static void check_no_symbol_named(const Module *m, const char *name, const char *msg) {
for (int i = 0; i < m->symbolCount; i++)
CHECK(strcmp(m->symbols[i].name, name) != 0, msg);
}

int main(void) {
Module *m = java_parse("tests/TestKek.java");
CHECK(m != NULL, "java_parse returned NULL");
if (!m) {
fprintf(stderr, "aborting: no module to check further\n");
return 1;
}

CHECK(m->symbolCount == 2, "expected exactly 2 documented methods/constructors");

/* Explicit negative coverage: the fixture calls this out by name as a
* method that must NOT be extracted (no doc comment above it). */
check_no_symbol_named(m, "doStuff", "method with no doc comment must be skipped");

if (m->symbolCount > 0) {
Symbol *s = &m->symbols[0];
CHECK_STR(s->name, "Kek", "symbol[0] name");
CHECK_STR(s->type, "constructor", "symbol[0] type");
CHECK(s->line == 11, "symbol[0] line");
CHECK_STR(s->description,
"Creates a Kek object and loads the continuous data for the object",
"symbol[0] brief");
CHECK(s->inputCount == 2, "symbol[0] param count");
if (s->inputCount == 2) {
CHECK_STR(s->input[0].name, "sadkek", "symbol[0] param[0] name");
CHECK_STR(s->input[1].name, "kekw", "symbol[0] param[1] name");
}
}

if (m->symbolCount > 1) {
Symbol *s = &m->symbols[1];
CHECK_STR(s->name, "loadKekData", "symbol[1] name");
CHECK_STR(s->type, "method", "symbol[1] type");
CHECK(s->line == 33, "symbol[1] line");
CHECK_STR(s->output, "true if the data was loaded successfully, false otherwise",
"symbol[1] returns");
CHECK(s->inputCount == 1, "symbol[1] param count");
if (s->inputCount == 1)
CHECK_STR(s->input[0].name, "path", "symbol[1] param[0] name");
/* Two @throws lines must both be preserved, joined together. */
CHECK(s->notes != NULL && strstr(s->notes, "IllegalArgumentException") != NULL,
"symbol[1] notes contains first @throws");
CHECK(s->notes != NULL && strstr(s->notes, "java.io.IOException") != NULL,
"symbol[1] notes contains second @throws");
}

module_free(m);

if (failures) {
fprintf(stderr, "java_parser_test: %d assertion(s) FAILED\n", failures);
return 1;
}
printf("java_parser_test: all assertions passed\n");
return 0;
}
4 changes: 3 additions & 1 deletion parser/plx_parser/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
*.exe
*.o
*.o
plx_parser
plx_parser_test
21 changes: 18 additions & 3 deletions parser/plx_parser/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ CFLAGS = -std=c11 -Wall -Wextra
TARGET = plx_parser
OBJS = plx_parser.o helpers.o plx_parser_demo.o

TEST_BIN = plx_parser_test
TEST_OBJS = tests/plx_parser_test.o

all: $(TARGET)

$(TARGET): $(OBJS)
Expand All @@ -14,13 +17,25 @@ plx_parser.o: plx_parser.c plx_parser.h helpers.h $(SHARED_H)
helpers.o: helpers.c helpers.h
plx_parser_demo.o: plx_parser_demo.c plx_parser.h helpers.h $(SHARED_H)

tests/plx_parser_test.o: tests/plx_parser_test.c plx_parser.h helpers.h $(SHARED_H)

$(TEST_BIN): plx_parser.o helpers.o $(TEST_OBJS)
$(CC) $(CFLAGS) -o $@ plx_parser.o helpers.o $(TEST_OBJS)

test: $(TEST_BIN)
ifeq ($(OS),Windows_NT)
$(TEST_BIN)
else
./$(TEST_BIN)
endif

ifeq ($(OS),Windows_NT)
clean: SHELL := cmd.exe
clean:
-del /f /q $(subst /,\,$(TARGET) $(OBJS)) 2>NUL
-del /f /q $(subst /,\,$(TARGET) $(OBJS) $(TEST_BIN) $(TEST_BIN).exe $(TEST_OBJS)) 2>NUL
else
clean:
rm -f $(TARGET) $(OBJS)
rm -f $(TARGET) $(OBJS) $(TEST_BIN) $(TEST_OBJS)
endif

.PHONY: all clean
.PHONY: all test clean
25 changes: 25 additions & 0 deletions parser/plx_parser/tests/basic_doc.plx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/********************************************************************/
/* basic_doc.plx */
/* Small, deterministic fixture: one documented procedure and one */
/* undocumented one, for unit-test assertions. */
/********************************************************************/

/****************************************************************** */
/* TITLE: ADD_NUMBERS */
/* FUNCTION: Adds two integers and returns the sum */
/* INPUT: A - first operand */
/* INPUT: B - second operand */
/* OUTPUT: Sum of A and B */
/****************************************************************** */
ADD_NUMBERS: PROC(A, B) RETURNS(FIXED(31));
DCL A FIXED(31);
DCL B FIXED(31);
RETURN(A + B);
END ADD_NUMBERS;
@EJECT;

/* plain comment, not a doc-comment block - must not attach */
UNDOCUMENTED_PROC: PROC;
DCL X FIXED(31);
X = 0;
END UNDOCUMENTED_PROC;
Loading