aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorColin Snover2017-01-06 22:25:22 -0600
committerColin Snover2017-01-08 13:20:23 -0600
commit2558b20cdda438bb0816791b1193776ff55aefde (patch)
treed0c916bb95dfb3567e73eea3ce7204ecce101058 /test
parent7e0b40173f1b57a81e9e3cd17709162410ac1269 (diff)
downloadscummvm-rg350-2558b20cdda438bb0816791b1193776ff55aefde.tar.gz
scummvm-rg350-2558b20cdda438bb0816791b1193776ff55aefde.tar.bz2
scummvm-rg350-2558b20cdda438bb0816791b1193776ff55aefde.zip
COMMON: Improve test coverage for Span and fix bugs from testing
Diffstat (limited to 'test')
-rw-r--r--test/common/span.h365
1 files changed, 321 insertions, 44 deletions
diff --git a/test/common/span.h b/test/common/span.h
index 6586d491ec..82b63a58d5 100644
--- a/test/common/span.h
+++ b/test/common/span.h
@@ -67,6 +67,9 @@ public:
byte data[] = { 'h', 'e', 'l', 'l', 'o' };
Common::Span<byte> span(data, sizeof(data));
+ // empty iterator should default construct OK
+ Common::Span<byte>::iterator defaultIt;
+
Common::Span<byte>::iterator it = span.begin();
Common::Span<byte>::iterator sameIt(it);
@@ -126,6 +129,31 @@ public:
}
}
+ void test_span_iterator_integers() {
+ const byte data[] = { 0xFF, 1, 2, 3, 2, 1, 0xFF };
+ Common::Span<const byte> span(data, sizeof(data));
+ Common::Span<const byte>::const_iterator it = span.cbegin();
+
+ TS_ASSERT_EQUALS(it.getInt8(), -1);
+ TS_ASSERT_EQUALS(it.getUint8(), 255);
+ TS_ASSERT_EQUALS(it.getInt16BE(), -255);
+ TS_ASSERT_EQUALS(it.getUint16BE(), 65281U);
+ TS_ASSERT_EQUALS((it + 5).getInt16LE(), -255);
+ TS_ASSERT_EQUALS((it + 5).getUint16LE(), 65281U);
+ TS_ASSERT_EQUALS(it.getUint24LE(), 131583U);
+#ifdef SCUMM_LITTLE_ENDIAN
+ TS_ASSERT_EQUALS((it + 3).getUint32(), 4278256131U);
+#elif SCUMM_BIG_ENDIAN
+ TS_ASSERT_EQUALS(it.getUint32(), 4278256131U);
+#else
+#error No endianness detected
+#endif
+ TS_ASSERT_EQUALS(it.getInt32BE(), -16711165);
+ TS_ASSERT_EQUALS(it.getUint32BE(), 4278256131U);
+ TS_ASSERT_EQUALS((it + 3).getInt32LE(), -16711165);
+ TS_ASSERT_EQUALS((it + 3).getUint32LE(), 4278256131U);
+ }
+
void test_span_iterator_ptr() {
Foo foo[2];
foo[0].a = 1;
@@ -179,6 +207,18 @@ public:
TS_ASSERT_EQUALS((bool)owner, false);
TS_ASSERT(owner->data() == nullptr);
TS_ASSERT_EQUALS(owner2->data(), dataPtr);
+
+ // tests destruction of held pointer by reassignment
+ owner2 = owner;
+ }
+
+ {
+ char *data = new char[6];
+ Common::strlcpy(data, "hello", 6);
+ const Common::SpanOwner<Common::Span<const char> > constOwner(Common::Span<const char>(data, 6));
+ TS_ASSERT_EQUALS((*constOwner)[0], 'h');
+ TS_ASSERT_EQUALS(constOwner->getUint8At(1), 'e');
+ TS_ASSERT_EQUALS(constOwner[2], 'l');
}
{
@@ -203,26 +243,151 @@ public:
}
}
+ void test_span_owner_named_span() {
+ Common::SpanOwner<Common::NamedSpan<byte> > owner;
+ owner->allocate(3, "foo");
+ owner[0] = 'a';
+ owner[1] = 'b';
+ owner[2] = 'c';
+ for (int i = 0; i < 3; ++i) {
+ TS_ASSERT_EQUALS(owner->getUint8At(i), 'a' + i);
+ TS_ASSERT_EQUALS((*owner)[i], 'a' + i);
+ }
+ TS_ASSERT(owner->name() == "foo");
+
+ {
+ Common::SpanOwner<Common::NamedSpan<byte> > owner2;
+ TS_ASSERT(owner2->data() == nullptr);
+ owner2->allocateFromSpan(*owner);
+ TS_ASSERT(owner2->data() != nullptr);
+ TS_ASSERT_DIFFERS(owner->data(), owner2->data());
+ TS_ASSERT(owner2->name() == "foo");
+
+ for (int i = 0; i < 3; ++i) {
+ TS_ASSERT_EQUALS(owner2->getUint8At(i), 'a' + i);
+ TS_ASSERT_EQUALS((*owner2)[i], 'a' + i);
+ }
+
+ TS_ASSERT_EQUALS((bool)owner2, true);
+ owner2.release();
+ TS_ASSERT_EQUALS((bool)owner2, false);
+ }
+
+ {
+ Common::SpanOwner<Common::NamedSpan<byte> > owner2;
+ TS_ASSERT_EQUALS((bool)owner, true);
+ void *dataPtr = owner->data();
+ owner2 = owner;
+ TS_ASSERT_EQUALS((bool)owner, false);
+ TS_ASSERT(owner->data() == nullptr);
+ TS_ASSERT_EQUALS(owner2->data(), dataPtr);
+
+ // tests destruction of held pointer by reassignment
+ owner2 = owner;
+ }
+
+ {
+ char *data = new char[6];
+ Common::strlcpy(data, "hello", 6);
+ const Common::SpanOwner<Common::NamedSpan<const char> > constOwner(Common::NamedSpan<const char>(data, 6));
+ TS_ASSERT_EQUALS((*constOwner)[0], 'h');
+ TS_ASSERT_EQUALS(constOwner->getUint8At(1), 'e');
+ TS_ASSERT_EQUALS(constOwner[2], 'l');
+ }
+
+ {
+ TS_ASSERT_EQUALS((bool)owner, false);
+ Common::SpanOwner<Common::NamedSpan<byte> > owner2(owner);
+ TS_ASSERT_EQUALS((bool)owner2, false);
+ }
+
+ {
+ owner->allocate(1);
+ TS_ASSERT_EQUALS((bool)owner, true);
+ Common::SpanOwner<Common::NamedSpan<byte> > owner2(owner);
+ TS_ASSERT_EQUALS((bool)owner2, true);
+ TS_ASSERT_DIFFERS(owner->data(), owner2->data());
+ }
+
+ {
+ TS_ASSERT_EQUALS((bool)owner, true);
+ void *dataPtr = owner->data();
+ TS_ASSERT_EQUALS(owner.release(), dataPtr);
+ TS_ASSERT_EQUALS((bool)owner, false);
+ }
+ }
+
+ void test_span_allocate_from_stream() {
+ byte data[] = "hello";
+ Common::MemoryReadStream stream(data, sizeof(data));
+ Common::SpanOwner<Common::Span<byte> > owner;
+ owner->allocateFromStream(stream, 2);
+ TS_ASSERT(owner->data() != data);
+ TS_ASSERT_EQUALS(owner->size(), 2U);
+ TS_ASSERT_EQUALS(owner[0], 'h');
+ TS_ASSERT_EQUALS(owner[1], 'e');
+ owner.clear();
+ TS_ASSERT(owner->data() == nullptr);
+ stream.seek(0, SEEK_SET);
+
+ owner->allocateFromStream(stream);
+ TS_ASSERT(owner->data() != data);
+ TS_ASSERT_EQUALS(owner->size(), sizeof(data));
+ TS_ASSERT_EQUALS(owner[0], 'h');
+ TS_ASSERT_EQUALS(owner[1], 'e');
+ TS_ASSERT_EQUALS(owner[2], 'l');
+ TS_ASSERT_EQUALS(owner[3], 'l');
+ TS_ASSERT_EQUALS(owner[4], 'o');
+
+ Common::SpanOwner<Common::NamedSpan<const byte> > owner2;
+ stream.seek(0, SEEK_SET);
+ owner2->allocateFromStream(stream, Common::kSpanMaxSize, "streamname");
+ TS_ASSERT(owner2->data() != data);
+ TS_ASSERT_EQUALS(owner2->size(), sizeof(data));
+ TS_ASSERT_EQUALS(owner2[0], 'h');
+ TS_ASSERT_EQUALS(owner2[1], 'e');
+ TS_ASSERT_EQUALS(owner2[2], 'l');
+ TS_ASSERT_EQUALS(owner2[3], 'l');
+ TS_ASSERT_EQUALS(owner2[4], 'o');
+ TS_ASSERT_EQUALS(owner2->name(), "streamname");
+ }
+
void test_span_byte() {
- byte data[] = { 'h', 'e', 'l', 'l', 'o' };
- Common::Span<byte> span(data, sizeof(data));
+ {
+ byte data[] = { 'h', 'e', 'l', 'l', 'o' };
+ Common::Span<byte> span(data, sizeof(data));
+
+ TS_ASSERT_EQUALS(span.size(), sizeof(data));
+ TS_ASSERT_EQUALS(span.byteSize(), sizeof(data));
- TS_ASSERT_EQUALS(span.size(), sizeof(data));
- TS_ASSERT_EQUALS(span.byteSize(), sizeof(data));
+ Common::Span<byte> other(span);
+ TS_ASSERT_EQUALS(span, other);
+ other.clear();
+ TS_ASSERT(span != other);
- Common::Span<byte> other(span);
- TS_ASSERT_EQUALS(span, other);
- other.clear();
- TS_ASSERT(span != other);
+ TS_ASSERT_EQUALS(span[0], 'h');
+ TS_ASSERT_EQUALS(span[1], 'e');
+ span[1] = 'o';
+ TS_ASSERT_EQUALS(span[1], 'o');
- TS_ASSERT_EQUALS(span[0], 'h');
- TS_ASSERT_EQUALS(span[1], 'e');
- span[1] = 'o';
- TS_ASSERT_EQUALS(span[1], 'o');
+ TS_ASSERT((bool)span);
+ span.clear();
+ TS_ASSERT(!(bool)span);
+ }
+
+ {
+ byte data[] = { 'h', 'e', 'l', 'l', 'o' };
+ const Common::Span<const byte> span(data, sizeof(data));
- TS_ASSERT((bool)span);
- span.clear();
- TS_ASSERT(!(bool)span);
+ TS_ASSERT_EQUALS(span.size(), sizeof(data));
+ TS_ASSERT_EQUALS(span.byteSize(), sizeof(data));
+
+ const Common::Span<const byte> other(span);
+ TS_ASSERT_EQUALS(span, other);
+
+ TS_ASSERT_EQUALS(span[0], 'h');
+ TS_ASSERT_EQUALS(span[1], 'e');
+ }
}
void test_span_integers() {
@@ -265,50 +430,107 @@ public:
void test_span_unsafe_data() {
char data[] = "hello";
Common::Span<char> span(data, sizeof(data));
- TS_ASSERT_EQUALS(span.getUnsafeDataAt(0, 6), data);
+
+ char *ptr = span.getUnsafeDataAt(0, 6);
+ TS_ASSERT_EQUALS(ptr, data);
+ ptr = span.getUnsafeDataAt(0);
+ TS_ASSERT_EQUALS(ptr, data);
+
+ const Common::Span<const char> span2(data, sizeof(data));
+ const char *ptr2 = span2.getUnsafeDataAt(0, 6);
+ TS_ASSERT_EQUALS(ptr2, data);
+ ptr2 = span2.getUnsafeDataAt(0);
+ TS_ASSERT_EQUALS(ptr2, data);
}
void test_span_subspan() {
- byte data[] = { 1, 2, 3, 4, 5, 6 };
- Common::Span<byte> span(data, sizeof(data));
+ {
+ byte data[] = { 1, 2, 3, 4, 5, 6 };
+ Common::Span<byte> span(data, sizeof(data));
+
+ TS_ASSERT_EQUALS(span.subspan(0).size(), sizeof(data) - 0);
+ TS_ASSERT_EQUALS(span.subspan(2).size(), sizeof(data) - 2);
+ TS_ASSERT_EQUALS(span.subspan(2, 2).size(), 2U);
+ TS_ASSERT_EQUALS(span.subspan<uint16>(0).size(), sizeof(data) / 2);
+ TS_ASSERT_EQUALS(span.subspan<uint16>(0).byteSize(), sizeof(data));
+ TS_ASSERT_EQUALS(span.subspan<uint16>(0, 2).size(), 1U);
+ TS_ASSERT_EQUALS(span.subspan<uint16>(0, 2).byteSize(), 2U);
+
+#ifdef SCUMM_LITTLE_ENDIAN
+ TS_ASSERT_EQUALS(span.subspan<uint16>(0)[1], 4 << 8 | 3);
+#elif SCUMM_BIG_ENDIAN
+ TS_ASSERT_EQUALS(span.subspan<uint16>(0)[1], 3 << 8 | 4);
+#else
+#error No endianness detected
+#endif
+
+ Common::Span<uint16> shortSpan = span.subspan<uint16>(0);
+ TS_ASSERT_EQUALS(shortSpan.byteSize(), span.byteSize());
+ TS_ASSERT(shortSpan.size() != span.size());
+ shortSpan[1] = 0xFFFF;
+ Common::Span<byte> byteSpan = shortSpan.subspan<byte>(1);
+ TS_ASSERT_EQUALS(byteSpan.size(), sizeof(data) - 1 * sizeof(uint16));
+ TS_ASSERT_EQUALS(byteSpan[0], 0xFF);
+ TS_ASSERT_EQUALS(byteSpan[1], 0xFF);
+ }
+
+ {
+ byte data[] = { 1, 2, 3, 4, 5, 6 };
+ const Common::Span<const byte> span(data, sizeof(data));
- TS_ASSERT_EQUALS(span.subspan(0).size(), sizeof(data) - 0);
- TS_ASSERT_EQUALS(span.subspan(2).size(), sizeof(data) - 2);
- TS_ASSERT_EQUALS(span.subspan(2, 2).size(), 2U);
- TS_ASSERT_EQUALS(span.subspan<uint16>(0).size(), sizeof(data) / 2);
- TS_ASSERT_EQUALS(span.subspan<uint16>(0).byteSize(), sizeof(data));
- TS_ASSERT_EQUALS(span.subspan<uint16>(0, 2).size(), 1U);
- TS_ASSERT_EQUALS(span.subspan<uint16>(0, 2).byteSize(), 2U);
+ TS_ASSERT_EQUALS(span.subspan(0).size(), sizeof(data) - 0);
+ TS_ASSERT_EQUALS(span.subspan(2).size(), sizeof(data) - 2);
+ TS_ASSERT_EQUALS(span.subspan(2, 2).size(), 2U);
+ TS_ASSERT_EQUALS(span.subspan<uint16>(0).size(), sizeof(data) / 2);
+ TS_ASSERT_EQUALS(span.subspan<uint16>(0).byteSize(), sizeof(data));
+ TS_ASSERT_EQUALS(span.subspan<uint16>(0, 2).size(), 1U);
+ TS_ASSERT_EQUALS(span.subspan<uint16>(0, 2).byteSize(), 2U);
#ifdef SCUMM_LITTLE_ENDIAN
- TS_ASSERT_EQUALS(span.subspan<uint16>(0)[1], 4 << 8 | 3);
+ TS_ASSERT_EQUALS(span.subspan<uint16>(0)[1], 4 << 8 | 3);
#elif SCUMM_BIG_ENDIAN
- TS_ASSERT_EQUALS(span.subspan<uint16>(0)[1], 3 << 8 | 4);
+ TS_ASSERT_EQUALS(span.subspan<uint16>(0)[1], 3 << 8 | 4);
#else
#error No endianness detected
#endif
- Common::Span<uint16> shortSpan = span.subspan<uint16>(0);
- TS_ASSERT_EQUALS(shortSpan.byteSize(), span.byteSize());
- TS_ASSERT(shortSpan.size() != span.size());
- shortSpan[1] = 0xFFFF;
- Common::Span<byte> byteSpan = shortSpan.subspan<byte>(1);
- TS_ASSERT_EQUALS(byteSpan.size(), sizeof(data) - 1 * sizeof(uint16));
- TS_ASSERT_EQUALS(byteSpan[0], 0xFF);
- TS_ASSERT_EQUALS(byteSpan[1], 0xFF);
+ const Common::Span<uint16> shortSpan = span.subspan<uint16>(0);
+ TS_ASSERT_EQUALS(shortSpan.byteSize(), span.byteSize());
+ TS_ASSERT(shortSpan.size() != span.size());
+ Common::Span<byte> byteSpan = shortSpan.subspan<byte>(1);
+ TS_ASSERT_EQUALS(byteSpan.size(), sizeof(data) - 1 * sizeof(uint16));
+ TS_ASSERT_EQUALS(byteSpan[0], 3);
+ TS_ASSERT_EQUALS(byteSpan[1], 4);
+ }
}
void test_span_to_stream() {
- const byte data[] = { 0, 1, 2, 3, 4, 5 };
+ const byte data[] = { 0, 1, 2, 3 };
Common::Span<const byte> span(data, sizeof(data));
- Common::MemoryReadStream stream(span.toStream(1, 2));
- byte out;
- TS_ASSERT_EQUALS(stream.read(&out, 1), 1U);
- TS_ASSERT_EQUALS(out, 1);
- TS_ASSERT_EQUALS(stream.read(&out, 1), 1U);
- TS_ASSERT_EQUALS(out, 2);
- TS_ASSERT_EQUALS(stream.read(&out, 1), 0U);
+ {
+ Common::MemoryReadStream stream(span.toStream(1, 2));
+ byte out;
+ TS_ASSERT_EQUALS(stream.read(&out, 1), 1U);
+ TS_ASSERT_EQUALS(out, 1);
+ TS_ASSERT_EQUALS(stream.read(&out, 1), 1U);
+ TS_ASSERT_EQUALS(out, 2);
+ TS_ASSERT_EQUALS(stream.read(&out, 1), 0U);
+ }
+
+ {
+ Common::MemoryReadStream stream = span.toStream();
+ byte out;
+ TS_ASSERT_EQUALS(stream.read(&out, 1), 1U);
+ TS_ASSERT_EQUALS(out, 0);
+ TS_ASSERT_EQUALS(stream.read(&out, 1), 1U);
+ TS_ASSERT_EQUALS(out, 1);
+ TS_ASSERT_EQUALS(stream.read(&out, 1), 1U);
+ TS_ASSERT_EQUALS(out, 2);
+ TS_ASSERT_EQUALS(stream.read(&out, 1), 1U);
+ TS_ASSERT_EQUALS(out, 3);
+ TS_ASSERT_EQUALS(stream.read(&out, 1), 0U);
+ }
}
void test_span_copying() {
@@ -396,7 +618,7 @@ public:
TS_ASSERT_EQUALS(span0 - span4, -2);
}
- void test_namedspan() {
+ void test_named_span() {
byte data[6] = { 0, 1, 2, 3, 4, 5 };
Common::NamedSpan<byte> span(data, sizeof(data), "foo.data");
TS_ASSERT_EQUALS(span.name(), "foo.data");
@@ -430,7 +652,62 @@ public:
TS_ASSERT_EQUALS(actual, expected);
}
+ Common::NamedSpan<byte> span2;
+ span2 = span;
+ TS_ASSERT_EQUALS(span2, span);
+
Common::Span<byte> superclassInstance;
superclassInstance = span;
+ TS_ASSERT_EQUALS(span, superclassInstance);
+
+ Common::Span<byte> subclassInstance(superclassInstance);
+ TS_ASSERT_EQUALS(subclassInstance, superclassInstance);
+
+ const Common::NamedSpan<const byte> constSpan(span);
+
+ {
+ Common::NamedSpan<const byte> subspan = constSpan.subspan(2);
+
+ expected = "Access violation reading foo.data: 23 + 45 > 4 (abs: 25 + 45 > 6)";
+ actual = subspan.getValidationMessage(23, 45, Common::kValidateRead);
+ TS_ASSERT_EQUALS(actual, expected);
+ TS_ASSERT_EQUALS(subspan.sourceByteOffset(), 2U);
+ }
+
+ {
+ Common::NamedSpan<const byte> subspan = constSpan.subspan(2, Common::kSpanMaxSize, "new.data");
+ expected = "Access violation reading new.data: -34 + -56 > 4 (abs: -32 + -56 > 6)";
+ actual = subspan.getValidationMessage(-34, -56, Common::kValidateRead);
+ TS_ASSERT_EQUALS(actual, expected);
+ }
+
+ {
+ Common::NamedSpan<const byte> subspan = constSpan.subspan(2, Common::kSpanMaxSize, "new.data", 0);
+ expected = "Access violation reading new.data: -34 + -56 > 4 (abs: -34 + -56 > 4)";
+ actual = subspan.getValidationMessage(-34, -56, Common::kValidateRead);
+ TS_ASSERT_EQUALS(actual, expected);
+ }
+
+ {
+ Common::NamedSpan<const byte> subspan = constSpan.subspan(2, Common::kSpanMaxSize, "new.data", 0);
+ subspan.sourceByteOffset() = 2;
+ expected = "Access violation reading new.data: -34 + -56 > 4 (abs: -32 + -56 > 6)";
+ actual = subspan.getValidationMessage(-34, -56, Common::kValidateRead);
+ TS_ASSERT_EQUALS(actual, expected);
+ }
+
+ {
+ Common::MemoryReadStream *stream = new Common::MemoryReadStream(data, sizeof(data));
+ Common::File file;
+ file.open(stream, "test.txt");
+ Common::SpanOwner<Common::NamedSpan<const byte> > fileOwner;
+ fileOwner->allocateFromStream(file);
+ TS_ASSERT_EQUALS(fileOwner->size(), (uint)file.size());
+ file.close();
+ TS_ASSERT(fileOwner->name() == "test.txt");
+ for (uint i = 0; i < fileOwner->size(); ++i) {
+ TS_ASSERT_EQUALS(fileOwner->getInt8At(i), data[i]);
+ }
+ }
}
};