Skip to content

Commit

Permalink
Merge pull request #23 from andymccall/develop
Browse files Browse the repository at this point in the history
enhancement(issue-16): setup unit testing framework
  • Loading branch information
andymccall authored Sep 13, 2024
2 parents bfc6aa6 + e66de6d commit e43a00d
Show file tree
Hide file tree
Showing 10 changed files with 235 additions and 16 deletions.
48 changes: 45 additions & 3 deletions .github/workflows/makefile-develop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ name: Develop
on:
push:
branches: [ "develop" ]

pull_request:
branches:
- develop

jobs:

analysis:
Expand All @@ -28,7 +31,7 @@ jobs:

- name: Install Prerequisites
run: |
sudo apt-get install -y build-essential gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu gcc-arm-linux-gnueabi binutils-arm-linux-gnueabi
sudo apt-get install -y build-essential gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu gcc-arm-linux-gnueabi binutils-arm-linux-gnueabi lcov
wget https://github.com/CE-Programming/toolchain/releases/latest/download/CEdev-Linux.tar.gz
tar zxpvf CEdev-Linux.tar.gz
rm CEdev-Linux.tar.gz
Expand All @@ -40,4 +43,43 @@ jobs:
echo "AGDEV_BASE=$(pwd)/agdev" >> $GITHUB_ENV
- name: Make All
run: make all
run: make all

test:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
with:
submodules: true

- name: Install Prerequisites
run: |
sudo apt-get install -y lcov
- name: Run Tests
run: make test

- name: Generate Coverage Report
run: make coverage

- name: Upload Coverage Report
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/html

- name: Setup lcov
uses: hrishikesh-kadam/setup-lcov@v1

- name: Post Coverage Report to PR
uses: kefasjw/lcov-pull-request-report@v1
with:
lcov-file: coverage/coverage.info
github-token: ${{ secrets.GITHUB_TOKEN }}
working-directory: .
comment-title: 'Coverage Report'
all-files-minimum-coverage: 10
changed-files-minimum-coverage: 10
artifact-name: coverage-report
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ obj

*.dat

release
release
coverage
test_runner*
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "lib/unity"]
path = lib/unity
url = https://github.com/ThrowTheSwitch/Unity.git
53 changes: 41 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,11 @@ OBJ_X86_DIR = x86
OBJ_ARM64_DIR = arm64
OBJ_ARMHF_DIR = armhf
OBJ_Z80_DIR = z80
OBJ_TEST_DIR = test
BIN_DIR = bin
TEST_DIR = tests
RELEASE_DIR = release
TEST_EXECUTABLE = test_runner

# Source and Object Files
SOURCES = $(wildcard $(SRC_DIR)/*.c)
Expand All @@ -54,15 +56,21 @@ ARMHF_OBJECTS = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/$(OBJ_ARMHF_DIR)/%.o, $(SO
Z80_OBJECTS = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/$(OBJ_Z80_DIR)/%.o, $(SOURCES))

# Test Files and Object Files (if using Unity, adjust accordingly)
TEST_SOURCES = $(wildcard $(TEST_DIR)/*.c)
TEST_OBJECTS = $(patsubst $(TEST_DIR)/%.c, $(OBJ_DIR)/%.o, $(TEST_SOURCES))
TEST_SOURCES = $(filter-out $(SRC_DIR)/main.c, $(wildcard $(SRC_DIR)/*.c)) $(wildcard $(TEST_DIR)/*.c)
TEST_OBJECTS = $(patsubst $(TEST_DIR)/%.c, $(OBJ_DIR)/$(OBJ_TEST_DIR)/%.o, $(wildcard $(TEST_DIR)/*.c)) \
$(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/$(OBJ_TEST_DIR)/%.o, $(filter-out $(SRC_DIR)/main.c, $(wildcard $(SRC_DIR)/*.c)))

# Include Directories
INCLUDES = -Iinclude # Adjust if you have additional include directories
INCLUDES = -Iinclude -Ilib/unity/src # Adjust if you have additional include directories

# Unity Library (if using Unity for testing)
UNITY_DIR = path/to/unity # Update with the actual path
UNITY_LIB = $(UNITY_DIR)/unity.c
UNITY_DIR = lib/unity
UNITY_SRC = $(UNITY_DIR)/src/unity.c

# Define variables for coverage
COVERAGE_DIR = coverage
COVERAGE_INFO = $(COVERAGE_DIR)/coverage.info
COVERAGE_HTML = $(COVERAGE_DIR)/html

# Targets

Expand Down Expand Up @@ -103,8 +111,11 @@ $(Z80_PROJECT_NAME): $(BIN_DIR) $(OBJ_DIR)/$(OBJ_Z80_DIR) $(Z80_OBJECTS)

# Testing Target (adjust if using a different testing framework)

test: $(TEST_OBJECTS) $(OBJECTS) $(UNITY_LIB)
$(CC) $(CFLAGS) $(INCLUDES) $^ -o $(TEST_EXECUTABLE)
test: CFLAGS += -fprofile-arcs -ftest-coverage
test: LDFLAGS += -lgcov

test: $(TEST_OBJECTS) $(OBJECTS) $(UNITY_SRC)
$(CC) $(CFLAGS) $(INCLUDES) $(UNITY_OBJECT) $^ -o $(TEST_EXECUTABLE)
./$(TEST_EXECUTABLE)

# Release Target (optimize for performance)
Expand Down Expand Up @@ -147,7 +158,7 @@ package_z80: release_z80
# Cleanup Target

clean:
rm -rf $(OBJ_DIR) $(BIN_DIR) $(TEST_DIR) $(RELEASE_DIR) $(X86_PROJECT_NAME) $(ARM64_PROJECT_NAME) $(ARMHF_PROJECT_NAME) $(Z80_PROJECT_NAME) $(TEST_EXECUTABLE) analysis.txt gmon.out
rm -rf $(OBJ_DIR) $(BIN_DIR) $(RELEASE_DIR) $(COVERAGE_DIR) $(X86_PROJECT_NAME) $(ARM64_PROJECT_NAME) $(ARMHF_PROJECT_NAME) $(Z80_PROJECT_NAME) $(TEST_EXECUTABLE) analysis.txt gmon.out *.gcda *.gcno

# Create directories

Expand All @@ -166,10 +177,10 @@ $(OBJ_DIR)/$(OBJ_ARMHF_DIR):
$(OBJ_DIR)/$(OBJ_Z80_DIR):
mkdir -p $@

$(BIN_DIR):
$(OBJ_DIR)/$(OBJ_TEST_DIR):
mkdir -p $@

$(TEST_DIR):
$(BIN_DIR):
mkdir -p $@

$(RELEASE_DIR):
Expand All @@ -189,5 +200,23 @@ $(OBJ_DIR)/$(OBJ_ARMHF_DIR)/%.o: $(SRC_DIR)/%.c
$(OBJ_DIR)/$(OBJ_Z80_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) -MD $(CFLAGS) $(INCLUDES) -c $< -o $@

$(OBJ_DIR)/%.o: $(TEST_DIR)/%.c
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
$(OBJ_DIR)/$(OBJ_TEST_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

$(OBJ_DIR)/$(OBJ_TEST_DIR)/%.o: $(TEST_DIR)/%.c | $(OBJ_DIR)/$(OBJ_TEST_DIR)
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

# Compile Unity object file
$(UNITY_OBJECT): $(UNITY_SRC) | $(OBJ_TEST_DIR)
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

# Add a target to generate coverage reports
coverage: test
mkdir -p $(COVERAGE_DIR)
lcov --capture --directory . --output-file $(COVERAGE_INFO)
lcov --remove $(COVERAGE_INFO) '/usr/*' --output-file $(COVERAGE_INFO)
genhtml $(COVERAGE_INFO) --output-directory $(COVERAGE_HTML)

# Clean coverage data
clean-coverage:
rm -rf $(COVERAGE_DIR) *.gcda *.gcno
1 change: 1 addition & 0 deletions lib/unity
Submodule unity added at 73237c
31 changes: 31 additions & 0 deletions tests/test_constants.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "../lib/unity/src/unity.h" // The Unity test framework
#include "../src/constants.h" // Adjust the path as necessary
#include "test_constants.h"

void setUp(void) {
// Set up code, if needed
}

void tearDown(void) {
// Tear down code, if needed
}

void test_PROGRAM_NAME(void) {
TEST_ASSERT_EQUAL_STRING("ez80op", PROGRAM_NAME);
}

void test_GIT_REPOSITORY(void) {
TEST_ASSERT_EQUAL_STRING("https://github.com/andymccall/ez80op", GIT_REPOSITORY);
}

void test_GIT_INFO(void) {
TEST_ASSERT_EQUAL_STRING("unknown", GIT_INFO);
}

void test_BUILD_YEAR(void) {
TEST_ASSERT_EQUAL_STRING("2024", BUILD_YEAR);
}

void test_AUTHOR(void) {
TEST_ASSERT_EQUAL_STRING("Andy McCall", AUTHOR);
}
12 changes: 12 additions & 0 deletions tests/test_constants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef TEST_CONSTANTS_H
#define TEST_CONSTANTS_H

void setUp(void);
void tearDown(void);
void test_PROGRAM_NAME(void);
void test_GIT_REPOSITORY(void);
void test_GIT_INFO(void);
void test_BUILD_YEAR(void);
void test_AUTHOR(void);

#endif // TEST_CONSTANTS_H
14 changes: 14 additions & 0 deletions tests/test_main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "test_constants.h"
#include "test_opcode.h"

int main(void) {
UNITY_BEGIN();
RUN_TEST(test_createOpcode_should_ReturnValidOpcode);
RUN_TEST(test_createOpcode_should_ReturnNullOnMallocFailure);
RUN_TEST(test_PROGRAM_NAME);
RUN_TEST(test_GIT_REPOSITORY);
RUN_TEST(test_GIT_INFO);
RUN_TEST(test_BUILD_YEAR);
RUN_TEST(test_AUTHOR);
return UNITY_END();
}
73 changes: 73 additions & 0 deletions tests/test_opcode.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#include <stdlib.h>
#include <string.h>
#include "../lib/unity/src/unity.h" // The Unity test framework
#include "../src/opcode.h" // Adjust the path as necessary
#include "test_opcode.h"

void test_createOpcode_should_ReturnValidOpcode(void) {
int number = 1;
enum instructionType type = IO; // Replace with actual enum value
char *name = "Test Opcode";
char *shortDescription = "Short Desc";
char *longDescription = "Long Desc";
ConditionBits conditionBits;

conditionBits.S = true;
conditionBits.S_explanation = strdup("Sign flag");
conditionBits.Z = false;
conditionBits.Z_explanation = strdup("Zero flag");
conditionBits.H = true;
conditionBits.H_explanation = strdup("Half carry flag");
conditionBits.PV = false;
conditionBits.PV_explanation = strdup("Parity/Overflow flag");
conditionBits.N = true;
conditionBits.N_explanation = strdup("Add/Subtract flag");
conditionBits.C = false;
conditionBits.C_explanation = strdup("Carry flag");

opcode *code = createOpcode(number, type, name, shortDescription, longDescription, conditionBits);

TEST_ASSERT_NOT_NULL(code);
TEST_ASSERT_EQUAL_INT(number, code->number);
TEST_ASSERT_EQUAL_INT(type, code->type);
TEST_ASSERT_EQUAL_STRING(name, code->name);
TEST_ASSERT_EQUAL_STRING(shortDescription, code->shortDescription);
TEST_ASSERT_EQUAL_STRING(longDescription, code->longDescription);

// Clean up
free(code->name);
free(code->shortDescription);
free(code->longDescription);
free(code);
}

void test_createOpcode_should_ReturnNullOnMallocFailure(void) {
// // Simulate malloc failure by setting a limit on memory allocation
// // This part is platform-specific and may require additional setup

// // For demonstration purposes, we'll assume malloc fails
// // You can use a custom malloc function to simulate this in a real test

// // Example:
// // set_malloc_limit(0);

// opcode *code = createOpcode(1, IO, "Test", "Short", "Long", (ConditionBits) { // Create ConditionBits directly within the call
// .S = true,
// .S_explanation = "Sign flag is set if the result is negative",
// .Z = true,
// .Z_explanation = "Zero flag is set if the result is zero",
// .H = false,
// .H_explanation = NULL,
// .PV = false,
// .PV_explanation = NULL,
// .N = true,
// .N_explanation = "Negative flag is set if the result is negative",
// .C = false,
// .C_explanation = NULL
// } );

// TEST_ASSERT_NULL(code);

// // Reset malloc limit if necessary
// // reset_malloc_limit();
}
12 changes: 12 additions & 0 deletions tests/test_opcode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef TEST_OPCODE_H
#define TEST_OPCODE_H

#include <stdlib.h>
#include <string.h>
#include "../lib/unity/src/unity.h" // The Unity test framework
#include "../src/opcode.h" // Adjust the path as necessary

void test_createOpcode_should_ReturnValidOpcode(void);
void test_createOpcode_should_ReturnNullOnMallocFailure(void);

#endif // TEST_OPCODE_H

0 comments on commit e43a00d

Please sign in to comment.