Commit 0445831ea2
Unsigned
Layout: unified · split
octosentryTests/UpdateStoreTests.swift added +83
| @@ -0,0 +1,83 @@ | |||
| 1 | // | ||
| 2 | // UpdateStoreTests.swift | ||
| 3 | // octosentryTests | ||
| 4 | // | ||
| 5 | // isNewer decides whether anyone ever hears about a release: too strict and | ||
| 6 | // updates go unnoticed, too loose and every user is nagged to install what | ||
| 7 | // they already have. | ||
| 8 | // | ||
| 9 | |||
| 10 | import Foundation | ||
| 11 | import Testing | ||
| 12 | @testable import octosentry | ||
| 13 | |||
| 14 | // isNewer is a pure function but inherits the target's MainActor isolation. | ||
| 15 | @MainActor | ||
| 16 | struct UpdateStoreTests { | ||
| 17 | |||
| 18 | // MARK: - Ordering | ||
| 19 | |||
| 20 | @Test func aNewerPatchMinorOrMajorIsOffered() { | ||
| 21 | #expect(UpdateStore.isNewer("1.1.1", than: "1.1.0")) | ||
| 22 | #expect(UpdateStore.isNewer("1.2.0", than: "1.1.9")) | ||
| 23 | #expect(UpdateStore.isNewer("2.0.0", than: "1.9.9")) | ||
| 24 | } | ||
| 25 | |||
| 26 | @Test func theSameVersionIsNotOffered() { | ||
| 27 | #expect(!UpdateStore.isNewer("1.1.1", than: "1.1.1")) | ||
| 28 | #expect(!UpdateStore.isNewer("1.0.0", than: "1.0.0")) | ||
| 29 | } | ||
| 30 | |||
| 31 | @Test func anOlderReleaseIsNotOffered() { | ||
| 32 | #expect(!UpdateStore.isNewer("1.1.0", than: "1.1.1")) | ||
| 33 | #expect(!UpdateStore.isNewer("1.0.1", than: "1.1.0")) | ||
| 34 | #expect(!UpdateStore.isNewer("0.7.0", than: "1.0.0")) | ||
| 35 | } | ||
| 36 | |||
| 37 | // A local build ahead of the latest release must not prompt for the | ||
| 38 | // release it already contains. | ||
| 39 | @Test func aBundleAheadOfTheLatestReleaseIsNotPrompted() { | ||
| 40 | #expect(!UpdateStore.isNewer("1.1", than: "1.1.1")) | ||
| 41 | } | ||
| 42 | |||
| 43 | // MARK: - Numeric, not lexical | ||
| 44 | |||
| 45 | // The comparison that a string compare gets wrong: "1.10" sorts before | ||
| 46 | // "1.9" as text, and after it as versions. | ||
| 47 | @Test func componentsCompareNumericallyNotAsText() { | ||
| 48 | #expect(UpdateStore.isNewer("1.10.0", than: "1.9.0")) | ||
| 49 | #expect(!UpdateStore.isNewer("1.9.0", than: "1.10.0")) | ||
| 50 | #expect(UpdateStore.isNewer("1.1.10", than: "1.1.9")) | ||
| 51 | } | ||
| 52 | |||
| 53 | // MARK: - Shapes the tag names actually take | ||
| 54 | |||
| 55 | @Test func missingTrailingComponentsCountAsZero() { | ||
| 56 | #expect(!UpdateStore.isNewer("1.1", than: "1.1.0")) | ||
| 57 | #expect(!UpdateStore.isNewer("1.1.0", than: "1.1")) | ||
| 58 | #expect(UpdateStore.isNewer("1.1.1", than: "1.1")) | ||
| 59 | } | ||
| 60 | |||
| 61 | @Test func aLeadingVIsIgnored() { | ||
| 62 | #expect(UpdateStore.isNewer("v1.1.1", than: "1.1.0")) | ||
| 63 | #expect(!UpdateStore.isNewer("v1.1.1", than: "1.1.1")) | ||
| 64 | #expect(UpdateStore.isNewer("v2.0.0", than: "v1.9.9")) | ||
| 65 | } | ||
| 66 | |||
| 67 | // Rather than crash or throw on a tag that isn't a version. | ||
| 68 | @Test func unparseableComponentsCountAsZero() { | ||
| 69 | #expect(!UpdateStore.isNewer("nightly", than: "1.1.1")) | ||
| 70 | #expect(UpdateStore.isNewer("1.1.1", than: "nightly")) | ||
| 71 | } | ||
| 72 | |||
| 73 | // MARK: - This repo's real tags | ||
| 74 | |||
| 75 | @Test func everyShippedTagIsNewerThanTheOneBefore() { | ||
| 76 | let shipped = ["0.1.0", "0.3.0", "0.4.0", "0.5.0", "0.6.0", "0.7.0", "1.0.0", "1.0.1", "1.1", "1.1.1"] | ||
| 77 | |||
| 78 | for (earlier, later) in zip(shipped, shipped.dropFirst()) { | ||
| 79 | #expect(UpdateStore.isNewer(later, than: earlier), "\(later) should be newer than \(earlier)") | ||
| 80 | #expect(!UpdateStore.isNewer(earlier, than: later), "\(earlier) should not be newer than \(later)") | ||
| 81 | } | ||
| 82 | } | ||
| 83 | } | ||