mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-27 06:35:04 +00:00
Added some extra tests, performed some basic tidying. Probably should do more.
This commit is contained in:
parent
6a0c7f22ee
commit
72ca06cf8d
@ -16,6 +16,8 @@
|
||||
|
||||
@implementation PCMPatchedTrackTests
|
||||
|
||||
#pragma mark - Prebuilt tracks
|
||||
|
||||
- (std::shared_ptr<Storage::Disk::Track>)togglingTrack
|
||||
{
|
||||
Storage::Disk::PCMSegment segment;
|
||||
@ -30,110 +32,6 @@
|
||||
return std::shared_ptr<Storage::Disk::Track>(new Storage::Disk::PCMPatchedTrack(track));
|
||||
}
|
||||
|
||||
- (void)assertOneThirtyTwosForTrack:(std::shared_ptr<Storage::Disk::Track>)track
|
||||
{
|
||||
// Confirm that there are now flux transitions (just the first five will do)
|
||||
// located 1/32nd of a rotation apart.
|
||||
for(int c = 0; c < 5; c++)
|
||||
{
|
||||
Storage::Disk::Track::Event event = track->get_next_event();
|
||||
XCTAssert(
|
||||
event.length == (c ? Storage::Time(1, 32) : Storage::Time(1, 64)),
|
||||
@"flux transitions should be 1/32nd of a track apart");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testUnpatchedRawTrack
|
||||
{
|
||||
[self assertOneThirtyTwosForTrack:self.togglingTrack];
|
||||
}
|
||||
|
||||
- (void)testUnpatchedTrack
|
||||
{
|
||||
[self assertOneThirtyTwosForTrack:self.patchableTogglingTrack];
|
||||
}
|
||||
|
||||
- (void)testSingleSplice
|
||||
{
|
||||
std::shared_ptr<Storage::Disk::Track> patchableTrack = self.patchableTogglingTrack;
|
||||
Storage::Disk::PCMPatchedTrack *patchable = static_cast<Storage::Disk::PCMPatchedTrack *>(patchableTrack.get());
|
||||
|
||||
// add a single one, at 1/32 length at 3/128. So that should shift the location of the second flux transition
|
||||
Storage::Disk::PCMSegment one_segment;
|
||||
one_segment.data = {0xff};
|
||||
one_segment.number_of_bits = 1;
|
||||
one_segment.length_of_a_bit.length = 1;
|
||||
one_segment.length_of_a_bit.clock_rate = 32;
|
||||
patchable->add_segment(Storage::Time(3, 128), one_segment);
|
||||
|
||||
Storage::Time total_length;
|
||||
std::vector<Storage::Disk::Track::Event> events;
|
||||
while(1)
|
||||
{
|
||||
events.push_back(patchableTrack->get_next_event());
|
||||
total_length += events.back().length;
|
||||
if(events.back().type == Storage::Disk::Track::Event::IndexHole) break;
|
||||
}
|
||||
|
||||
XCTAssert(events.size() == 33, @"Should still be 33 total events");
|
||||
XCTAssert(events[0].length == Storage::Time(1, 64), @"First event should be after 1/64 as usual");
|
||||
XCTAssert(events[1].length == Storage::Time(3, 128), @"Second event should be 3/128 later"); // ... as it was inserted at 3/128 and runs at the same rate as the main data, so first inserted event is at 3/128+1/64-1/64
|
||||
XCTAssert(events[2].length == Storage::Time(5, 128), @"Should still be 33 total events"); // 1/64 = 2/128 to exit the patch, plus 3/128 to get to the next event, having spliced in 1/128 ahead of the normal clock
|
||||
XCTAssert(total_length == Storage::Time(1), @"Total track length should still be 1");
|
||||
}
|
||||
|
||||
- (void)testLeftReplace
|
||||
{
|
||||
std::shared_ptr<Storage::Disk::Track> patchableTrack = self.patchableTogglingTrack;
|
||||
Storage::Disk::PCMPatchedTrack *patchable = static_cast<Storage::Disk::PCMPatchedTrack *>(patchableTrack.get());
|
||||
|
||||
Storage::Disk::PCMSegment zero_segment;
|
||||
zero_segment.data = {0x00};
|
||||
zero_segment.number_of_bits = 8;
|
||||
zero_segment.length_of_a_bit.length = 1;
|
||||
zero_segment.length_of_a_bit.clock_rate = 16;
|
||||
patchable->add_segment(Storage::Time(0), zero_segment);
|
||||
|
||||
Storage::Time total_length;
|
||||
std::vector<Storage::Disk::Track::Event> events;
|
||||
while(1)
|
||||
{
|
||||
events.push_back(patchableTrack->get_next_event());
|
||||
total_length += events.back().length;
|
||||
if(events.back().type == Storage::Disk::Track::Event::IndexHole) break;
|
||||
}
|
||||
|
||||
XCTAssert(events.size() == 17, @"Should still be 17 total events");
|
||||
XCTAssert(events[0].length == Storage::Time(33, 64), @"First event should not occur until 33/64");
|
||||
XCTAssert(total_length == Storage::Time(1), @"Total track length should still be 1");
|
||||
}
|
||||
|
||||
- (void)testRightReplace
|
||||
{
|
||||
std::shared_ptr<Storage::Disk::Track> patchableTrack = self.patchableTogglingTrack;
|
||||
Storage::Disk::PCMPatchedTrack *patchable = static_cast<Storage::Disk::PCMPatchedTrack *>(patchableTrack.get());
|
||||
|
||||
Storage::Disk::PCMSegment zero_segment;
|
||||
zero_segment.data = {0x00};
|
||||
zero_segment.number_of_bits = 8;
|
||||
zero_segment.length_of_a_bit.length = 1;
|
||||
zero_segment.length_of_a_bit.clock_rate = 16;
|
||||
patchable->add_segment(Storage::Time(1, 2), zero_segment);
|
||||
|
||||
Storage::Time total_length;
|
||||
std::vector<Storage::Disk::Track::Event> events;
|
||||
while(1)
|
||||
{
|
||||
events.push_back(patchableTrack->get_next_event());
|
||||
total_length += events.back().length;
|
||||
if(events.back().type == Storage::Disk::Track::Event::IndexHole) break;
|
||||
}
|
||||
|
||||
XCTAssert(events.size() == 17, @"Should still be 17 total events");
|
||||
XCTAssert(events[16].length == Storage::Time(33, 64), @"Final event should take 33/64");
|
||||
XCTAssert(total_length == Storage::Time(1), @"Total track length should still be 1");
|
||||
}
|
||||
|
||||
- (std::shared_ptr<Storage::Disk::Track>)fourSegmentPatchedTrack
|
||||
{
|
||||
std::shared_ptr<Storage::Disk::Track> patchableTrack = self.patchableTogglingTrack;
|
||||
@ -152,18 +50,129 @@
|
||||
return patchableTrack;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (std::vector<Storage::Disk::Track::Event>)eventsFromTrack:(std::shared_ptr<Storage::Disk::Track>)track
|
||||
{
|
||||
std::vector<Storage::Disk::Track::Event> events;
|
||||
while(1)
|
||||
{
|
||||
events.push_back(track->get_next_event());
|
||||
if(events.back().type == Storage::Disk::Track::Event::IndexHole) break;
|
||||
}
|
||||
return events;
|
||||
}
|
||||
|
||||
- (Storage::Time)timeForEvents:(const std::vector<Storage::Disk::Track::Event> &)events
|
||||
{
|
||||
Storage::Time result(0);
|
||||
for(auto event : events)
|
||||
{
|
||||
result += event.length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#pragma mark - Repeating Asserts
|
||||
|
||||
- (void)assertOneThirtyTwosForTrack:(std::shared_ptr<Storage::Disk::Track>)track
|
||||
{
|
||||
// Confirm that there are now flux transitions (just the first five will do)
|
||||
// located 1/32nd of a rotation apart.
|
||||
for(int c = 0; c < 5; c++)
|
||||
{
|
||||
Storage::Disk::Track::Event event = track->get_next_event();
|
||||
XCTAssert(
|
||||
event.length == (c ? Storage::Time(1, 32) : Storage::Time(1, 64)),
|
||||
@"flux transitions should be 1/32nd of a track apart");
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Unpatched tracks
|
||||
|
||||
- (void)testUnpatchedRawTrack
|
||||
{
|
||||
[self assertOneThirtyTwosForTrack:self.togglingTrack];
|
||||
}
|
||||
|
||||
- (void)testUnpatchedTrack
|
||||
{
|
||||
[self assertOneThirtyTwosForTrack:self.patchableTogglingTrack];
|
||||
}
|
||||
|
||||
#pragma mark - Insertions affecting one existing segment
|
||||
|
||||
- (void)testSingleSplice
|
||||
{
|
||||
std::shared_ptr<Storage::Disk::Track> patchableTrack = self.patchableTogglingTrack;
|
||||
Storage::Disk::PCMPatchedTrack *patchable = static_cast<Storage::Disk::PCMPatchedTrack *>(patchableTrack.get());
|
||||
|
||||
// add a single one, at 1/32 length at 3/128. So that should shift the location of the second flux transition
|
||||
Storage::Disk::PCMSegment one_segment;
|
||||
one_segment.data = {0xff};
|
||||
one_segment.number_of_bits = 1;
|
||||
one_segment.length_of_a_bit.length = 1;
|
||||
one_segment.length_of_a_bit.clock_rate = 32;
|
||||
patchable->add_segment(Storage::Time(3, 128), one_segment);
|
||||
|
||||
std::vector<Storage::Disk::Track::Event> events = [self eventsFromTrack:patchableTrack];
|
||||
Storage::Time total_length = [self timeForEvents:events];
|
||||
|
||||
XCTAssert(events.size() == 33, @"Should still be 33 total events");
|
||||
XCTAssert(events[0].length == Storage::Time(1, 64), @"First event should be after 1/64 as usual");
|
||||
XCTAssert(events[1].length == Storage::Time(3, 128), @"Second event should be 3/128 later"); // ... as it was inserted at 3/128 and runs at the same rate as the main data, so first inserted event is at 3/128+1/64-1/64
|
||||
XCTAssert(events[2].length == Storage::Time(5, 128), @"Should still be 33 total events"); // 1/64 = 2/128 to exit the patch, plus 3/128 to get to the next event, having spliced in 1/128 ahead of the normal clock
|
||||
XCTAssert(total_length == Storage::Time(1), @"Total track length should still be 1");
|
||||
}
|
||||
|
||||
- (void)testLeftReplace
|
||||
{
|
||||
std::shared_ptr<Storage::Disk::Track> patchableTrack = self.patchableTogglingTrack;
|
||||
Storage::Disk::PCMPatchedTrack *patchable = static_cast<Storage::Disk::PCMPatchedTrack *>(patchableTrack.get());
|
||||
|
||||
Storage::Disk::PCMSegment zero_segment;
|
||||
zero_segment.data = {0x00};
|
||||
zero_segment.number_of_bits = 8;
|
||||
zero_segment.length_of_a_bit.length = 1;
|
||||
zero_segment.length_of_a_bit.clock_rate = 16;
|
||||
patchable->add_segment(Storage::Time(0), zero_segment);
|
||||
|
||||
std::vector<Storage::Disk::Track::Event> events = [self eventsFromTrack:patchableTrack];
|
||||
Storage::Time total_length = [self timeForEvents:events];
|
||||
|
||||
XCTAssert(events.size() == 17, @"Should still be 17 total events");
|
||||
XCTAssert(events[0].length == Storage::Time(33, 64), @"First event should not occur until 33/64");
|
||||
XCTAssert(total_length == Storage::Time(1), @"Total track length should still be 1");
|
||||
}
|
||||
|
||||
- (void)testRightReplace
|
||||
{
|
||||
std::shared_ptr<Storage::Disk::Track> patchableTrack = self.patchableTogglingTrack;
|
||||
Storage::Disk::PCMPatchedTrack *patchable = static_cast<Storage::Disk::PCMPatchedTrack *>(patchableTrack.get());
|
||||
|
||||
Storage::Disk::PCMSegment zero_segment;
|
||||
zero_segment.data = {0x00};
|
||||
zero_segment.number_of_bits = 8;
|
||||
zero_segment.length_of_a_bit.length = 1;
|
||||
zero_segment.length_of_a_bit.clock_rate = 16;
|
||||
patchable->add_segment(Storage::Time(1, 2), zero_segment);
|
||||
|
||||
std::vector<Storage::Disk::Track::Event> events = [self eventsFromTrack:patchableTrack];
|
||||
Storage::Time total_length = [self timeForEvents:events];
|
||||
|
||||
XCTAssert(events.size() == 17, @"Should still be 17 total events");
|
||||
XCTAssert(events[16].length == Storage::Time(33, 64), @"Final event should take 33/64");
|
||||
XCTAssert(total_length == Storage::Time(1), @"Total track length should still be 1");
|
||||
}
|
||||
|
||||
#pragma mark - Insertions affecting three existing segments
|
||||
|
||||
- (void)testMultiSegmentTrack
|
||||
{
|
||||
std::shared_ptr<Storage::Disk::Track> patchableTrack = self.fourSegmentPatchedTrack;
|
||||
|
||||
Storage::Time total_length;
|
||||
std::vector<Storage::Disk::Track::Event> events;
|
||||
while(1)
|
||||
{
|
||||
events.push_back(patchableTrack->get_next_event());
|
||||
total_length += events.back().length;
|
||||
if(events.back().type == Storage::Disk::Track::Event::IndexHole) break;
|
||||
}
|
||||
std::vector<Storage::Disk::Track::Event> events = [self eventsFromTrack:patchableTrack];
|
||||
Storage::Time total_length = [self timeForEvents:events];
|
||||
|
||||
XCTAssert(events.size() == 33, @"Should still be 33 total events");
|
||||
XCTAssert(total_length == Storage::Time(1), @"Total track length should still be 1");
|
||||
@ -181,14 +190,8 @@
|
||||
segment.length_of_a_bit.clock_rate = 16;
|
||||
patchable->add_segment(Storage::Time(1, 8), segment);
|
||||
|
||||
Storage::Time total_length;
|
||||
std::vector<Storage::Disk::Track::Event> events;
|
||||
while(1)
|
||||
{
|
||||
events.push_back(patchableTrack->get_next_event());
|
||||
total_length += events.back().length;
|
||||
if(events.back().type == Storage::Disk::Track::Event::IndexHole) break;
|
||||
}
|
||||
std::vector<Storage::Disk::Track::Event> events = [self eventsFromTrack:patchableTrack];
|
||||
Storage::Time total_length = [self timeForEvents:events];
|
||||
|
||||
XCTAssert(events.size() == 17, @"Should still be 17 total events");
|
||||
XCTAssert(events[4].length == Storage::Time(17, 32), @"Should have added a 17/32 gap after the fourth event");
|
||||
@ -207,14 +210,8 @@
|
||||
segment.length_of_a_bit.clock_rate = 8;
|
||||
patchable->add_segment(Storage::Time(1, 8), segment);
|
||||
|
||||
Storage::Time total_length;
|
||||
std::vector<Storage::Disk::Track::Event> events;
|
||||
while(1)
|
||||
{
|
||||
events.push_back(patchableTrack->get_next_event());
|
||||
total_length += events.back().length;
|
||||
if(events.back().type == Storage::Disk::Track::Event::IndexHole) break;
|
||||
}
|
||||
std::vector<Storage::Disk::Track::Event> events = [self eventsFromTrack:patchableTrack];
|
||||
Storage::Time total_length = [self timeForEvents:events];
|
||||
|
||||
XCTAssert(events.size() == 21, @"Should still be 17 total events");
|
||||
XCTAssert(events[4].length == Storage::Time(13, 32), @"Should have added a 13/32 gap after the fourth event");
|
||||
@ -233,18 +230,95 @@
|
||||
segment.length_of_a_bit.clock_rate = 8;
|
||||
patchable->add_segment(Storage::Time(1, 4), segment);
|
||||
|
||||
Storage::Time total_length;
|
||||
std::vector<Storage::Disk::Track::Event> events;
|
||||
while(1)
|
||||
{
|
||||
events.push_back(patchableTrack->get_next_event());
|
||||
total_length += events.back().length;
|
||||
if(events.back().type == Storage::Disk::Track::Event::IndexHole) break;
|
||||
}
|
||||
std::vector<Storage::Disk::Track::Event> events = [self eventsFromTrack:patchableTrack];
|
||||
Storage::Time total_length = [self timeForEvents:events];
|
||||
|
||||
XCTAssert(events.size() == 21, @"Should still be 17 total events");
|
||||
XCTAssert(events[8].length == Storage::Time(13, 32), @"Should have added a 13/32 gap after the eighth event");
|
||||
XCTAssert(total_length == Storage::Time(1), @"Total track length should still be 1");
|
||||
}
|
||||
|
||||
#pragma mark - Insertions affecting two existing segments
|
||||
|
||||
- (void)testTwoSegmentOverlap
|
||||
{
|
||||
std::shared_ptr<Storage::Disk::Track> patchableTrack = self.fourSegmentPatchedTrack;
|
||||
Storage::Disk::PCMPatchedTrack *patchable = static_cast<Storage::Disk::PCMPatchedTrack *>(patchableTrack.get());
|
||||
|
||||
Storage::Disk::PCMSegment segment;
|
||||
segment.data = {0x00};
|
||||
segment.number_of_bits = 8;
|
||||
segment.length_of_a_bit.length = 1;
|
||||
segment.length_of_a_bit.clock_rate = 32;
|
||||
patchable->add_segment(Storage::Time(1, 8), segment);
|
||||
|
||||
std::vector<Storage::Disk::Track::Event> events = [self eventsFromTrack:patchableTrack];
|
||||
Storage::Time total_length = [self timeForEvents:events];
|
||||
|
||||
XCTAssert(events.size() == 25, @"Should still be 25 total events");
|
||||
XCTAssert(events[4].length == Storage::Time(18, 64), @"Should have added an 18/64 gap after the fourth event");
|
||||
XCTAssert(total_length == Storage::Time(1), @"Total track length should still be 1");
|
||||
}
|
||||
|
||||
- (void)testTwoSegmentRightReplace
|
||||
{
|
||||
std::shared_ptr<Storage::Disk::Track> patchableTrack = self.fourSegmentPatchedTrack;
|
||||
Storage::Disk::PCMPatchedTrack *patchable = static_cast<Storage::Disk::PCMPatchedTrack *>(patchableTrack.get());
|
||||
|
||||
Storage::Disk::PCMSegment segment;
|
||||
segment.data = {0x00};
|
||||
segment.number_of_bits = 1;
|
||||
segment.length_of_a_bit.length = 3;
|
||||
segment.length_of_a_bit.clock_rate = 8;
|
||||
patchable->add_segment(Storage::Time(1, 8), segment);
|
||||
|
||||
std::vector<Storage::Disk::Track::Event> events = [self eventsFromTrack:patchableTrack];
|
||||
Storage::Time total_length = [self timeForEvents:events];
|
||||
|
||||
XCTAssert(events.size() == 21, @"Should still be 25 total events");
|
||||
XCTAssert(events[4].length == Storage::Time(13, 32), @"Should have added an 13/32 gap after the fourth event");
|
||||
XCTAssert(total_length == Storage::Time(1), @"Total track length should still be 1");
|
||||
}
|
||||
|
||||
- (void)testTwoSegmentLeftReplace
|
||||
{
|
||||
std::shared_ptr<Storage::Disk::Track> patchableTrack = self.fourSegmentPatchedTrack;
|
||||
Storage::Disk::PCMPatchedTrack *patchable = static_cast<Storage::Disk::PCMPatchedTrack *>(patchableTrack.get());
|
||||
|
||||
Storage::Disk::PCMSegment segment;
|
||||
segment.data = {0x00};
|
||||
segment.number_of_bits = 1;
|
||||
segment.length_of_a_bit.length = 3;
|
||||
segment.length_of_a_bit.clock_rate = 8;
|
||||
patchable->add_segment(Storage::Time(0), segment);
|
||||
|
||||
std::vector<Storage::Disk::Track::Event> events = [self eventsFromTrack:patchableTrack];
|
||||
Storage::Time total_length = [self timeForEvents:events];
|
||||
|
||||
XCTAssert(events.size() == 21, @"Should still be 25 total events");
|
||||
XCTAssert(events[0].length == Storage::Time(25, 64), @"Should have added an 25/64 gap after the fourth event");
|
||||
XCTAssert(total_length == Storage::Time(1), @"Total track length should still be 1");
|
||||
}
|
||||
|
||||
#pragma mark - Wrapping segment
|
||||
|
||||
- (void)testWrappingSegment
|
||||
{
|
||||
std::shared_ptr<Storage::Disk::Track> patchableTrack = self.patchableTogglingTrack;
|
||||
Storage::Disk::PCMPatchedTrack *patchable = static_cast<Storage::Disk::PCMPatchedTrack *>(patchableTrack.get());
|
||||
|
||||
Storage::Disk::PCMSegment segment;
|
||||
segment.data = {0x00};
|
||||
segment.number_of_bits = 1;
|
||||
segment.length_of_a_bit.length = 5;
|
||||
segment.length_of_a_bit.clock_rate = 2;
|
||||
patchable->add_segment(Storage::Time(0), segment);
|
||||
|
||||
std::vector<Storage::Disk::Track::Event> events = [self eventsFromTrack:patchableTrack];
|
||||
Storage::Time total_length = [self timeForEvents:events];
|
||||
|
||||
XCTAssert(events.size() == 1, @"Should be only one event");
|
||||
XCTAssert(total_length == Storage::Time(1), @"Total track length should still be 1");
|
||||
}
|
||||
|
||||
@end
|
||||
|
Loading…
x
Reference in New Issue
Block a user