#include "test.h"

#include "render_queue.h"

void add_some(RenderQueue* rq, size_t epoch, size_t num) {
	for (size_t i = 0; i < num; ++i) {
		stringstream ss;
		ss << i << "_" << epoch;
		rq->add(new FormatString(ss.str()), i, epoch);
	}
}

void nothing_for(RenderQueue* rq, size_t epoch) {
	FormatString* fs = nullptr;
	size_t pos = G::NO_POS;
	bool ret = rq->remove(epoch, &pos, &fs);
	CHECK(!ret);
	CHECK(fs == nullptr);
	CHECK(pos == G::NO_POS);
}

void something_for(RenderQueue* rq, size_t epoch, size_t num) {
	for (size_t i = 0; i < num; ++i) {
		FormatString* fs = nullptr;
		size_t pos = G::NO_POS;
		bool ret = rq->remove(epoch, &pos, &fs);
		CHECK(ret);
		string s = *fs;
		stringstream ss;
		ss << pos << "_" << epoch;
		CHECK(s == ss.str());
		delete fs;
	}
}

TEST_CASE("add and remove") {
	RenderQueue rq;
	add_some(&rq, 1, 5);
	nothing_for(&rq, 0);
	something_for(&rq, 1, 5);
	nothing_for(&rq, 1);
	CHECK(rq.empty());
	nothing_for(&rq, 2);
}

TEST_CASE("stale epoch") {
	RenderQueue rq;
	add_some(&rq, 0, 5);
	add_some(&rq, 1, 5);
	something_for(&rq, 1, 1);
	nothing_for(&rq, 0);
	something_for(&rq, 1, 1);
	CHECK(!rq.empty());
	nothing_for(&rq, 2);
	nothing_for(&rq, 1);
	CHECK(rq.empty());
	nothing_for(&rq, 2);
}

TEST_CASE("future epoch") {
	RenderQueue rq;
	add_some(&rq, 1, 5);
	something_for(&rq, 1, 2);
	add_some(&rq, 2, 5);
	something_for(&rq, 1, 2);
	something_for(&rq, 2, 1);
	nothing_for(&rq, 1);
}

