First coverage reports. Tests don't get near enough coverage but running the program does.
This commit is contained in:
parent
988edf13d7
commit
97255eb813
7 changed files with 127 additions and 5 deletions
5
Makefile
5
Makefile
|
@ -14,7 +14,7 @@ ragel:
|
||||||
ragel -o .\ansi_parser.cpp .\ansi_parser.rl
|
ragel -o .\ansi_parser.cpp .\ansi_parser.rl
|
||||||
|
|
||||||
build: ansi_parser.cpp
|
build: ansi_parser.cpp
|
||||||
meson compile -j 4 -C builddir
|
meson compile -j 10 -C builddir
|
||||||
|
|
||||||
test: build
|
test: build
|
||||||
./builddir/runtests
|
./builddir/runtests
|
||||||
|
@ -28,3 +28,6 @@ clean:
|
||||||
|
|
||||||
debug:
|
debug:
|
||||||
gdb --nx -x .gdbinit builddir/roguish.exe
|
gdb --nx -x .gdbinit builddir/roguish.exe
|
||||||
|
|
||||||
|
cover:
|
||||||
|
gcovr --html coverage/coverage_report.html --gcov-ignore-errors=no_working_dir_found --exclude "scratchpad.*" --exclude "subprojects.*" --html-nested coverage/
|
||||||
|
|
|
@ -4,6 +4,8 @@ namespace components {
|
||||||
struct Combat {
|
struct Combat {
|
||||||
int hp;
|
int hp;
|
||||||
int damage;
|
int damage;
|
||||||
|
|
||||||
|
/* NOTE: This is used to _mark_ entities as dead, to detect ones that have just died. Don't make attack automatically set it.*/
|
||||||
bool dead;
|
bool dead;
|
||||||
|
|
||||||
int attack(Combat &target);
|
int attack(Combat &target);
|
||||||
|
|
|
@ -18,6 +18,7 @@ runtests = executable('runtests', [
|
||||||
'map.cpp',
|
'map.cpp',
|
||||||
'rand.cpp',
|
'rand.cpp',
|
||||||
'sound.cpp',
|
'sound.cpp',
|
||||||
|
'combat.cpp',
|
||||||
'collider.cpp',
|
'collider.cpp',
|
||||||
'ansi_parser.cpp',
|
'ansi_parser.cpp',
|
||||||
'config.cpp',
|
'config.cpp',
|
||||||
|
@ -27,6 +28,7 @@ runtests = executable('runtests', [
|
||||||
'tests/dbc.cpp',
|
'tests/dbc.cpp',
|
||||||
'tests/map.cpp',
|
'tests/map.cpp',
|
||||||
'tests/collider.cpp',
|
'tests/collider.cpp',
|
||||||
|
'tests/components.cpp',
|
||||||
'tests/sound.cpp',
|
'tests/sound.cpp',
|
||||||
'tests/dinkyecs.cpp',
|
'tests/dinkyecs.cpp',
|
||||||
'tests/ansi_parser.cpp',
|
'tests/ansi_parser.cpp',
|
||||||
|
@ -53,7 +55,7 @@ roguish = executable('roguish', [
|
||||||
],
|
],
|
||||||
dependencies: dependencies)
|
dependencies: dependencies)
|
||||||
|
|
||||||
roguish = executable('img2ansi', [
|
img2ansi = executable('img2ansi', [
|
||||||
'dbc.cpp',
|
'dbc.cpp',
|
||||||
'panel.cpp',
|
'panel.cpp',
|
||||||
'ansi_parser.cpp',
|
'ansi_parser.cpp',
|
||||||
|
|
7
scripts/coverage_reset.ps1
Normal file
7
scripts/coverage_reset.ps1
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
mv .\subprojects\packagecache .
|
||||||
|
rm -recurse -force .\subprojects\,.\builddir\
|
||||||
|
mkdir subprojects
|
||||||
|
mv .\packagecache .\subprojects\
|
||||||
|
mkdir builddir
|
||||||
|
cp wraps\*.wrap subprojects\
|
||||||
|
meson setup --default-library=static --prefer-static -Db_coverage=true builddir
|
|
@ -8,4 +8,4 @@ mv packagecache ./subprojects/
|
||||||
mkdir builddir
|
mkdir builddir
|
||||||
cp wraps/*.wrap subprojects/
|
cp wraps/*.wrap subprojects/
|
||||||
# on OSX you can't do this with static
|
# on OSX you can't do this with static
|
||||||
meson setup builddir
|
meson setup -Db_coverage=true builddir
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
TODAY'S GOAL:
|
TODAY'S GOAL:
|
||||||
* Neighbors needs a rewrite
|
* Neighbors needs a rewrite
|
||||||
* Neighbors algo isn't using greater parameter
|
* Neighbors algo isn't using greater parameter
|
||||||
* Think up an enemy system.
|
|
||||||
* Revisit map generation.
|
|
||||||
* How do we do coverage reports in C++?
|
* How do we do coverage reports in C++?
|
||||||
|
* Better tests and more coverage.
|
||||||
|
* Clean up and document as much code as possible.
|
||||||
|
* Doxygen? Other docs tool?
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
|
* Think up an enemy system.
|
||||||
|
* Revisit map generation.
|
||||||
* Write a method for renderer that can translate coordinates.
|
* Write a method for renderer that can translate coordinates.
|
||||||
* Can std::any be defaulted to a noop in the events?
|
* Can std::any be defaulted to a noop in the events?
|
||||||
* Save file isn't saving gold.
|
* Save file isn't saving gold.
|
||||||
|
|
105
tests/components.cpp
Normal file
105
tests/components.cpp
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
#include "components.hpp"
|
||||||
|
#include "dinkyecs.hpp"
|
||||||
|
|
||||||
|
using namespace components;
|
||||||
|
using namespace DinkyECS;
|
||||||
|
|
||||||
|
TEST_CASE("all components can work in the world", "[components]") {
|
||||||
|
World world;
|
||||||
|
auto ent1 = world.entity();
|
||||||
|
|
||||||
|
world.set<Player>(ent1, {ent1});
|
||||||
|
world.set<Position>(ent1, {{10,1}});
|
||||||
|
world.set<Motion>(ent1, {1,0});
|
||||||
|
world.set<Loot>(ent1, {100});
|
||||||
|
world.set<Inventory>(ent1, {0});
|
||||||
|
world.set<Tile>(ent1, {"Z"});
|
||||||
|
world.set<EnemyConfig>(ent1, {4});
|
||||||
|
|
||||||
|
auto player = world.get<Player>(ent1);
|
||||||
|
REQUIRE(player.entity == ent1);
|
||||||
|
|
||||||
|
auto position = world.get<Position>(ent1);
|
||||||
|
REQUIRE(position.location.x == 10);
|
||||||
|
REQUIRE(position.location.y == 1);
|
||||||
|
|
||||||
|
auto motion = world.get<Motion>(ent1);
|
||||||
|
REQUIRE(motion.dx == 1);
|
||||||
|
REQUIRE(motion.dy == 0);
|
||||||
|
|
||||||
|
auto loot = world.get<Loot>(ent1);
|
||||||
|
REQUIRE(loot.amount == 100);
|
||||||
|
|
||||||
|
auto inv = world.get<Inventory>(ent1);
|
||||||
|
REQUIRE(inv.gold == 0);
|
||||||
|
|
||||||
|
auto tile = world.get<Tile>(ent1);
|
||||||
|
REQUIRE(tile.chr == "Z");
|
||||||
|
|
||||||
|
auto enemy = world.get<EnemyConfig>(ent1);
|
||||||
|
REQUIRE(enemy.HEARING_DISTANCE == 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("all components can be facts", "[components]") {
|
||||||
|
World world;
|
||||||
|
auto ent1 = world.entity();
|
||||||
|
|
||||||
|
world.set_the<Player>({ent1});
|
||||||
|
world.set_the<Position>({{10,1}});
|
||||||
|
world.set_the<Motion>({1,0});
|
||||||
|
world.set_the<Loot>({100});
|
||||||
|
world.set_the<Inventory>({0});
|
||||||
|
world.set_the<Tile>({"Z"});
|
||||||
|
world.set_the<EnemyConfig>({4});
|
||||||
|
|
||||||
|
auto player = world.get_the<Player>();
|
||||||
|
REQUIRE(player.entity == ent1);
|
||||||
|
|
||||||
|
auto position = world.get_the<Position>();
|
||||||
|
REQUIRE(position.location.x == 10);
|
||||||
|
REQUIRE(position.location.y == 1);
|
||||||
|
|
||||||
|
auto motion = world.get_the<Motion>();
|
||||||
|
REQUIRE(motion.dx == 1);
|
||||||
|
REQUIRE(motion.dy == 0);
|
||||||
|
|
||||||
|
auto loot = world.get_the<Loot>();
|
||||||
|
REQUIRE(loot.amount == 100);
|
||||||
|
|
||||||
|
auto inv = world.get_the<Inventory>();
|
||||||
|
REQUIRE(inv.gold == 0);
|
||||||
|
|
||||||
|
auto tile = world.get_the<Tile>();
|
||||||
|
REQUIRE(tile.chr == "Z");
|
||||||
|
|
||||||
|
auto enemy = world.get_the<EnemyConfig>();
|
||||||
|
REQUIRE(enemy.HEARING_DISTANCE == 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("confirm combat works", "[components]") {
|
||||||
|
World world;
|
||||||
|
auto player = world.entity();
|
||||||
|
auto enemy = world.entity();
|
||||||
|
|
||||||
|
world.set<Combat>(player, {100, 10});
|
||||||
|
world.set<Combat>(enemy, {20, 10});
|
||||||
|
|
||||||
|
auto p_fight = world.get<Combat>(player);
|
||||||
|
REQUIRE(p_fight.hp == 100);
|
||||||
|
REQUIRE(p_fight.damage == 10);
|
||||||
|
REQUIRE(p_fight.dead == false);
|
||||||
|
|
||||||
|
auto e_fight = world.get<Combat>(enemy);
|
||||||
|
REQUIRE(e_fight.hp == 20);
|
||||||
|
REQUIRE(e_fight.damage == 10);
|
||||||
|
REQUIRE(e_fight.dead == false);
|
||||||
|
|
||||||
|
for(int i = 0; e_fight.hp > 0 && i < 100; i++) {
|
||||||
|
p_fight.attack(e_fight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("MapConfig loads from JSON", "[components]") {
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue