Tests/KeycaskCoreTests/GeneratorTests.swift
57 lines · 2033 bytes
1import Testing
2
3@testable import KeycaskCore
4
5@Suite struct GeneratorTests {
6 struct Counter: RandomNumberGenerator {
7 var n: UInt64 = 0
8 mutating func next() -> UInt64 {
9 n &+= 0x9E37_79B9_7F4A_7C15
10 return n
11 }
12 }
13
14 @Test func wordlistHas7776UniqueWords() {
15 #expect(Wordlist.words.count == 7776)
16 #expect(Set(Wordlist.words).count == 7776)
17 #expect(Wordlist.words.first == "abacus")
18 #expect(Wordlist.words.allSatisfy { !$0.isEmpty && !$0.contains(" ") })
19 }
20
21 @Test func passwordHasRequestedLengthFromTheAlphabet() {
22 let allowed = Set(Generator.alphabet)
23 for length in [1, 8, 24, 64] {
24 let p = Generator.password(length: length)
25 #expect(p.count == length)
26 #expect(p.allSatisfy { allowed.contains($0) })
27 }
28 #expect(Generator.password(length: 0) == "")
29 }
30
31 @Test func alphabetCoversAllClasses() {
32 let s = String(Generator.alphabet)
33 #expect(s.contains("A") && s.contains("z") && s.contains("7") && s.contains("!"))
34 #expect(Set(Generator.alphabet).count == Generator.alphabet.count)
35 }
36
37 @Test func passphraseUsesWordsFromTheList() {
38 var a = Counter()
39 var b = Counter()
40 let produced = Generator.passphrase(words: 5, using: &a)
41 let count = UInt32(Wordlist.words.count)
42 let expected = (0..<5).map { _ in Wordlist.words[Int(b.next(upperBound: count))] }
43 .joined(separator: Generator.wordSeparator)
44 #expect(produced == expected)
45 #expect(Generator.passphrase(words: 0) == "")
46 #expect(!Generator.passphrase(words: 3).isEmpty)
47 }
48
49 @Test func seededOutputIsReproducible() {
50 var a = Counter()
51 var b = Counter()
52 #expect(
53 Generator.password(length: 16, using: &a) == Generator.password(length: 16, using: &b))
54 #expect(
55 Generator.passphrase(words: 3, using: &a) == Generator.passphrase(words: 3, using: &b))
56 }
57}