Skip to content

Commit

Permalink
home-grown unit-testing system
Browse files Browse the repository at this point in the history
with a failing test for bggame_valid_move_exists

really ought to be replaced with something NIH
  • Loading branch information
beerriot committed Mar 2, 2011
1 parent 21fb17d commit ffaa2df
Show file tree
Hide file tree
Showing 12 changed files with 283 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -4,4 +4,5 @@
*.hex
*.ass
blockgame
bgtest

6 changes: 5 additions & 1 deletion Makefile
Expand Up @@ -21,13 +21,17 @@ blockgame: $(OBJECTS) blockgame.c
blockgame.ass: blockgame
avr-objdump -S -d blockgame > blockgame.ass

.PHONY: clean
.PHONY: clean test
clean:
-rm *.o *.d blockgame blockgame.hex blockgame.ass
$(MAKE) -C test clean

-include $(OBJECTS:%.o=%.d)

deps: $(OBJECTS:%.o=%.d)

%.d: %.c
$(CC) $(CFLAGS) -MM $< > $@

test:
$(MAKE) -C test test
26 changes: 26 additions & 0 deletions test/Makefile
@@ -0,0 +1,26 @@
VPATH=../src:../include:mock:mock/avr
CC=gcc
MOCK=mock
CFLAGS=-g -Os -Wall -I../include -I$(MOCK)
NKOBJECTS=lcd.o
AVROBJECTS=sleep.o interrupt.o
OBJECTS=bggame.o bgmenu.o bghighscore.o \
nktimer.o nklcd.o nkrand.o nkeeprom.o nkbuttons.o nksleep.o

.PHONY: clean test

test: bgtest
./bgtest

bgtest: $(OBJECTS) $(NKOBJECTS) $(AVROBJECTS) bgtest.c
$(CC) $(CFLAGS) $^ -o bgtest

clean:
-rm *.o *.d bgtest

-include $(OBJECTS:%.o=%.d)

deps: $(OBJECTS:%.o=%.d) $(NKOBJECTS:%.o=%.d) $(AVROBJECTS:%.0=%.d)

%.d: %.c
$(CC) $(CFLAGS) -MM $< > $@
84 changes: 84 additions & 0 deletions test/bgtest.c
@@ -0,0 +1,84 @@
/* bgtest: unit tests for parts of blockgame */

#include <stdio.h>

#include <inttypes.h>

#include "bggame.h"

#define PASS 0
#define FAIL 1

#define ASSERT_GAME(Test, Game) \
if (!(Test)) { \
printf("Assertion failed, line %d:\n", __LINE__); \
print_game(Game); \
return FAIL; \
}

#define TEST(Test) \
printf(#Test " ... "); \
if (Test()==PASS) { \
printf("PASS\n"); \
} else { \
printf("FAIL\n"); \
pass = FAIL; \
}

void print_game(game_t);
int valid_move_test_SIMPLE();
int valid_move_test_BITTEST();

int main() {
int pass = PASS;
printf("Beginning tests...\n");
TEST(valid_move_test_SIMPLE);
TEST(valid_move_test_BITTEST);
printf("Tests finished: %s\n", pass == PASS ? "PASS" : "FAIL");
return pass;
}

// TESTS

int valid_move_test_SIMPLE() {
game_t game = {.width=3,
.height=3,
.variety=9,
.board={ {'a', 'b', 'c'},
{'a', 'd', 'e'},
{'f', 'a', 'z'} }
};

//SIMPLE has a valid move (move 'a' in lower middle to the left)
ASSERT_GAME(bggame_valid_move_exists(game), game);
return PASS;
}

int valid_move_test_BITTEST() {
game_t game = {.width=3,
.height=3,
.variety=9,
.board={ {'a', 'b', 'c'},
{'a', 'd', 'e'},
{'f', 'q', 'z'} }
};

// BITTEST has no valid move ('a' is now 'q')
// this test captures a bug that bggame_match has:
// comparing only four bits of the character, not five
ASSERT_GAME(!bggame_valid_move_exists(game), game);
return PASS;
}

// UTILS

void print_game(game_t game) {
int r, c;
printf("%d x %d (%d)\n", game.width, game.height, game.variety);
for (r = 0; r < game.height; r++) {
printf(" ");
for (c = 0; c < game.width; c++)
putchar(game.board[r][c]);
putchar('\n');
}
}
12 changes: 12 additions & 0 deletions test/mock/avr/interrupt.c
@@ -0,0 +1,12 @@
/* interrupt.c: Mock definitions for testing */

#include <inttypes.h>
#include <stdio.h>

void cli() {
printf("%s:%d\n", __FILE__, __LINE__);
}
void sei() {
printf("%s:%d\n", __FILE__, __LINE__);
}

10 changes: 10 additions & 0 deletions test/mock/avr/interrupt.h
@@ -0,0 +1,10 @@
/* interrupt.h: Mock definitions for testing */
#ifndef __INTERRUPT_H_
#define __INTERRUPT_H_

#define ISR(x) void x()

void cli();
void sei();

#endif
65 changes: 65 additions & 0 deletions test/mock/avr/pgmspace.h
@@ -0,0 +1,65 @@
/* pgmspace.h: Mock definitions for testing */
#ifndef __PGMSPACE_H_
#define __PGMSPACE_H_

#define PSTR(x) x

uint8_t TCCR0A;
uint8_t TCCR0B;

uint8_t OCR0A;

uint8_t TIMSK0;

uint8_t ADMUX;
uint8_t ADCSRA;

uint8_t EEAR;
uint8_t EECR;
uint8_t EEDR;

uint8_t DDRC;
uint8_t PORTC;
uint8_t PCMSK1;
uint8_t PCICR;

uint8_t SMCR;

#define PC0 0x00
#define PC1 0x01
#define PC2 0x02
#define PC3 0x03
#define PC4 0x04

#define PCINT8 0x00
#define PCINT9 0x01
#define PCINT10 0x02
#define PCINT11 0x03
#define PCINT13 0x04

#define PCIE1 0x01
#define PINC 0x02

#define CS00 0x01
#define CS02 0x02

#define OCIE0A 0x01

#define WGM01 0x01

#define ADPS0 0x00
#define ADPS1 0x01
#define ADPS2 0x02
#define ADEN 0x03
#define ADSC 0x04
#define ADCL 0x05
#define ADCH 0x06

#define EEPE 0x01
#define EERE 0x02
#define EEMPE 0x03

#define SM1 0x01
#define SM2 0x02

#endif
14 changes: 14 additions & 0 deletions test/mock/avr/sleep.c
@@ -0,0 +1,14 @@
/* sleep.c: Mock definitions for testing */

#include <inttypes.h>
#include <stdio.h>

void sleep_cpu() {
printf("%s:%d\n", __FILE__, __LINE__);
}
void sleep_enable() {
printf("%s:%d\n", __FILE__, __LINE__);
}
void sleep_disable() {
printf("%s:%d\n", __FILE__, __LINE__);
}
9 changes: 9 additions & 0 deletions test/mock/avr/sleep.h
@@ -0,0 +1,9 @@
/* sleep.h: Mock definitions for testing */
#ifndef __SLEEP_H_
#define __SLEEP_H_

void sleep_cpu();
void sleep_enable();
void sleep_disable();

#endif
10 changes: 10 additions & 0 deletions test/mock/inttypes.h
@@ -0,0 +1,10 @@
/* inttypes.h: Mock definitions for testing */
#ifndef __INTTYPES_H_
#define __INTTYPES_H_

typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned short uint16_t;
typedef signed short int16_t;

#endif
32 changes: 32 additions & 0 deletions test/mock/lcd.c
@@ -0,0 +1,32 @@
/* lcd.c: Mock definitions for testing */

#include <inttypes.h>
#include <stdio.h>

void lcd_goto_position(uint8_t row, uint8_t col) {
printf("%s:%d\n", __FILE__, __LINE__);
}
void lcd_write_data(char c) {
printf("%s:%d\n", __FILE__, __LINE__);
}
void lcd_clear_and_home() {
printf("%s:%d\n", __FILE__, __LINE__);
}
void lcd_write_string(const char *x) {
printf("%s:%d\n", __FILE__, __LINE__);
}
void lcd_write_int16(int16_t in) {
printf("%s:%d\n", __FILE__, __LINE__);
}
void lcd_write_byte(char c) {
printf("%s:%d\n", __FILE__, __LINE__);
}
void lcd_init() {
printf("%s:%d\n", __FILE__, __LINE__);
}
void lcd_set_type_command() {
printf("%s:%d\n", __FILE__, __LINE__);
}
void lcd_home() {
printf("%s:%d\n", __FILE__, __LINE__);
}
15 changes: 15 additions & 0 deletions test/mock/lcd.h
@@ -0,0 +1,15 @@
/* lcd.h: Mock definitions for testing */
#ifndef __LCD_H
#define __LCD_H

void lcd_goto_position(uint8_t row, uint8_t col);
void lcd_write_data(char c);
void lcd_clear_and_home();
void lcd_write_string(const char *x);
void lcd_write_int16(int16_t in);
void lcd_write_byte(char c);
void lcd_init();
void lcd_set_type_command();
void lcd_home();

#endif

0 comments on commit ffaa2df

Please sign in to comment.