-
-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #85 from tayloraswift/adopt-swift-testing
Adopt swift testing
- Loading branch information
Showing
26 changed files
with
1,167 additions
and
1,529 deletions.
There are no files selected for viewing
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
#if DEBUG | ||
@testable | ||
import LZ77 | ||
import Testing | ||
|
||
@Suite | ||
enum CompressionInternals | ||
{ | ||
@Test | ||
static func BitstreamDecoding() | ||
{ | ||
var bits:LZ77.InflatorIn = [ | ||
0b1001_1110, | ||
0b1111_0110, | ||
0b0010_0011, | ||
] | ||
#expect(bits[ 0] == 0b1111_0110_1001_1110) | ||
#expect(bits[ 1] == 0b1_1111_0110_1001_111) | ||
#expect(bits[ 2] == 0b11_1111_0110_1001_11) | ||
#expect(bits[ 3] == 0b011_1111_0110_1001_1) | ||
#expect(bits[ 4] == 0b0011_1111_0110_1001) | ||
#expect(bits[ 5] == 0b0_0011_1111_0110_100) | ||
#expect(bits[ 6] == 0b10_0011_1111_0110_10) | ||
#expect(bits[ 7] == 0b010_0011_1111_0110_1) | ||
#expect(bits[ 8] == 0b0010_0011_1111_0110) | ||
#expect(bits[ 9] == 0b0_0010_0011_1111_011) | ||
#expect(bits[23] == 0b0000_0000_0000_0000) | ||
|
||
#expect(bits[0, count: 4, as: Int.self] == 0b1110) | ||
#expect(bits[1, count: 4, as: Int.self] == 0b1_111) | ||
#expect(bits[1, count: 6, as: Int.self] == 0b001_111) | ||
#expect(bits[2, count: 6, as: Int.self] == 0b1001_11) | ||
#expect(bits[2, count: 16, as: Int.self] == 0b11_1111_0110_1001_11) | ||
|
||
// test rebase | ||
// { 0010_0011, 1111_0110, 1001_1110 } | ||
// ^ | ||
// b = 20 | ||
// -> | ||
// { 0001_1000, 1010_1101, 0010_0011 } | ||
// ^ | ||
// b = 4 | ||
var b:Int = 20 | ||
|
||
bits.rebase([0b1010_1101, 0b0001_1000], pointer: &b) | ||
|
||
#expect(bits[b ] == 0b1000_1010_1101_0010) | ||
#expect(bits[b + 1] == 0b1_1000_1010_1101_001) | ||
|
||
// test rebase | ||
// { 0001_1000, 1010_1101, 0010_0011 } | ||
// ^ | ||
// b = 4 | ||
// { 1111_1100, 0011_1111, 0001_1000, 1010_1101, 0010_0011 } | ||
bits.rebase([0b0011_1111, 0b1111_1100], pointer: &b) | ||
|
||
#expect(bits[b ] == 0b1000_1010_1101_0010) | ||
#expect(bits[b + 8] == 0b1111_0001_1000_1010) | ||
} | ||
@Test | ||
static func BitstreamEncoding() | ||
{ | ||
var bits:LZ77.DeflatorOut = .init(hint: 4) | ||
|
||
bits.append(0b11, count: 2) | ||
bits.append(0b01_10, count: 4) | ||
|
||
bits.append(0b0110, count: 0) | ||
|
||
bits.append(0b1_1111_11, count: 7) | ||
bits.append(0b1010_1010_1010_101, count: 15) | ||
bits.append(0b000, count: 3) | ||
bits.append(0b0_1101_1, count: 6) | ||
bits.append(0b1_0000_0000_111, count: 12) | ||
|
||
var encoded:[UInt8] = [] | ||
|
||
while let chunk:[UInt8] = bits.pop() | ||
{ | ||
encoded.append(contentsOf: chunk) | ||
} | ||
|
||
encoded.append(contentsOf: bits.pull()) | ||
|
||
#expect(encoded == [ | ||
0b1101_1011, | ||
0b1011_1111, | ||
0b1010_1010, | ||
0b1000_1010, | ||
0b1110_1101, | ||
0b0000_0000, | ||
0b0000_0001 | ||
]) | ||
} | ||
|
||
@Test | ||
static func Matching() | ||
{ | ||
let segments:[[UInt8]] = [ | ||
[1, 2, 3, 3, 1, 2, 3, 3, 1, 2, 3, 1, 2, 2, 2, 2, 2, 2, 0, 1, 2], | ||
[2, 2, 2, 2, 0, 1, 2, 2, 0, 0, 0, 0, 2, 3, 2, 1, 2, 3, 3, 1, 5], | ||
[1, 1, 3, 3, 1, 2, 3, 1, 2, 4, 4, 2, 1] | ||
] | ||
var input:LZ77.DeflatorIn<LZ77.MRC32> = .init() | ||
var window:LZ77.DeflatorWindow = .init(exponent: 4) | ||
var output:[[UInt8]] = [] | ||
for (s, segment):(Int, [UInt8]) in segments.enumerated() | ||
{ | ||
input.enqueue(contentsOf: segment[...]) | ||
|
||
let lookahead:Int = (s == segments.count - 1 ? 0 : 10) | ||
while window.endIndex < 0, input.count > lookahead | ||
{ | ||
window.initialize(with: input.dequeue()) | ||
} | ||
while input.count > lookahead | ||
{ | ||
let head:(index:Int, next:UInt16?) = window.update(with: input.dequeue()) | ||
if let match:(run:Int, distance:Int) = window.match(from: head, | ||
lookahead: input, | ||
attempts: .max, | ||
goal: .max) | ||
{ | ||
var run:[UInt8] = [window.literal] | ||
for _:Int in 1 ..< match.run | ||
{ | ||
window.update(with: input.dequeue()) | ||
run.append(window.literal) | ||
} | ||
output.append(run) | ||
} | ||
else | ||
{ | ||
output.append([window.literal]) | ||
} | ||
} | ||
|
||
guard s == segments.count - 1 | ||
else | ||
{ | ||
continue | ||
} | ||
|
||
// epilogue: get the matches still sitting in the pipeline | ||
let epilogue:Int = -3 - min(0, window.endIndex) | ||
while input.count > epilogue | ||
{ | ||
window.update(with: input.dequeue()) | ||
output.append([window.literal]) | ||
} | ||
} | ||
#expect(output == [ | ||
[1], | ||
[2], | ||
[3], | ||
[3], | ||
[1, 2, 3, 3, 1, 2, 3], | ||
[1], | ||
[2], [2], [2], [2], [2], [2], | ||
[0], | ||
[1, 2, 2, 2, 2, 2], | ||
[0], | ||
[1], | ||
[2], [2], | ||
[0], [0], [0], [0], | ||
[2], | ||
[3], | ||
[2], | ||
[1], | ||
[2], | ||
[3], [3], | ||
[1], | ||
[5], | ||
[1], [1], | ||
[3], [3], | ||
[1], | ||
[2], | ||
[3], | ||
[1], | ||
[2], | ||
[4], [4], | ||
[2], | ||
[1] | ||
]) | ||
} | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import LZ77 | ||
import Testing | ||
|
||
@Suite | ||
enum Compression | ||
{ | ||
@Test(arguments: [4, 7, 9], [5, 15, 100, 200, 2000, 5000]) | ||
static func LZ77(_ level:Int, _ count:Int) throws | ||
{ | ||
let input:[UInt8] = (0 ..< count).map{ _ in .random(in: .min ... .max) } | ||
|
||
var deflator:LZ77.Deflator = .init(level: level, exponent: 8, hint: 16) | ||
deflator.push(input[...], last: true) | ||
|
||
var compressed:[UInt8] = [] | ||
while let part:[UInt8] = deflator.pull() | ||
{ | ||
compressed += part | ||
} | ||
|
||
var inflator:LZ77.Inflator = .init() | ||
try inflator.push(compressed[...]) | ||
|
||
let output:[UInt8] = inflator.pull() | ||
|
||
#expect(input == output) | ||
} | ||
|
||
@Test(arguments: [5, 15, 100, 200, 2000, 5000]) | ||
static func Gzip(_ count:Int) throws | ||
{ | ||
let input:[UInt8] = (0 ..< count).map{ _ in .random(in: .min ... .max) } | ||
|
||
var deflator:Gzip.Deflator = .init(level: 7, exponent: 15, hint: 64 << 10) | ||
deflator.push(input[...], last: true) | ||
|
||
var compressed:[UInt8] = [] | ||
while let part:[UInt8] = deflator.pull() | ||
{ | ||
compressed += part | ||
} | ||
|
||
var inflator:Gzip.Inflator = .init() | ||
try inflator.push(compressed[...]) | ||
|
||
let output:[UInt8] = inflator.pull() | ||
|
||
#expect(input == output) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import LZ77 | ||
import Testing | ||
|
||
@Suite | ||
enum CompressionMicro | ||
{ | ||
@Test(arguments: [[], [1], [2, 3], [4, 5, 6]]) | ||
static func Roundtrip(_ bytes:[UInt8]) throws | ||
{ | ||
let archive:[UInt8] = Gzip.archive(bytes: bytes[...], level: 10) | ||
#expect(try Gzip.extract(from: archive[...]) == bytes) | ||
} | ||
|
||
@Test | ||
static func InParts() throws | ||
{ | ||
var deflator:Gzip.Deflator = .init(level: 13, exponent: 15) | ||
deflator.push([1], last: false) | ||
deflator.push([2], last: true) | ||
|
||
var archive:[UInt8] = [] | ||
while let part:[UInt8] = deflator.pull() | ||
{ | ||
archive += part | ||
} | ||
|
||
#expect(try Gzip.extract(from: archive[...]) == [1, 2]) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#if DEBUG | ||
@testable | ||
import LZ77 | ||
import Testing | ||
|
||
@Suite | ||
enum HardwareAcceleration | ||
{ | ||
@Test | ||
static func DictionarySemantics() | ||
{ | ||
let dictionary:F14.HashTable = .init(exponent: 10) | ||
|
||
#expect(nil == dictionary.update(key: 0, value: 1)) | ||
#expect(nil == dictionary.update(key: 1, value: 2)) | ||
#expect(dictionary.update(key: 0, value: 3) == 1) | ||
#expect(nil == dictionary.update(key: 2, value: 4)) | ||
#expect(nil != dictionary.remove(key: 1, value: 5)) | ||
#expect(dictionary.update(key: 1, value: 6) == 2) | ||
#expect(nil != dictionary.remove(key: 1, value: 6)) | ||
#expect(nil == dictionary.update(key: 1, value: 7)) | ||
|
||
var a:F14.HashTable = .init(exponent: 15), | ||
b:[UInt32: UInt16] = [:] | ||
for i:UInt16 in ((0 ... .max).map{ $0 & 0x00ff }) | ||
{ | ||
let key:UInt32 = .random(in: 0 ... 1000) | ||
|
||
#expect(a.update(key: key, value: i) == b.updateValue(i, forKey: key)) | ||
} | ||
for i:UInt16 in ((0 ... .max).map{ $0 & 0x00ff }) | ||
{ | ||
let key:UInt32 = .random(in: 0 ... 1000) | ||
|
||
if b[key] == i | ||
{ | ||
b[key] = nil | ||
} | ||
|
||
a.remove(key: key, value: i) | ||
} | ||
for i:UInt16 in ((0 ... .max).map{ $0 & 0x00ff }) | ||
{ | ||
let key:UInt32 = .random(in: 0 ... 1000) | ||
|
||
#expect(a.update(key: key, value: i) == b.updateValue(i, forKey: key)) | ||
} | ||
} | ||
} | ||
#endif |
Oops, something went wrong.