Adds a few tests for Date extensions, Permissions, and FilePermissions

This commit is contained in:
Sami Samhuri 2019-12-31 15:41:25 -08:00
parent a27a3e482c
commit da56d10818
10 changed files with 251 additions and 40 deletions

View file

@ -0,0 +1,24 @@
//
// Date+Sugar.swift
// samhuri.net
//
// Created by Sami Samhuri on 2019-12-19.
//
import Foundation
extension Date {
static var defaultCalendar = Calendar.current
var year: Int {
Date.defaultCalendar.dateComponents([.year], from: self).year!
}
var month: Int {
Date.defaultCalendar.dateComponents([.month], from: self).month!
}
var day: Int {
Date.defaultCalendar.dateComponents([.day], from: self).day!
}
}

View file

@ -1,22 +0,0 @@
//
// Date+Sugar.swift
// samhuri.net
//
// Created by Sami Samhuri on 2019-12-19.
//
import Foundation
extension Date {
var year: Int {
Calendar.current.dateComponents([.year], from: self).year!
}
var month: Int {
Calendar.current.dateComponents([.month], from: self).month!
}
var day: Int {
Calendar.current.dateComponents([.day], from: self).day!
}
}

View file

@ -13,6 +13,8 @@ protocol DirectoryCreating {
extension FileManager: DirectoryCreating {
func createDirectory(at url: URL) throws {
try createDirectory(at: url, withIntermediateDirectories: true, attributes: [.posixPermissions: FilePermissions.directoryDefault.rawValue])
try createDirectory(at: url, withIntermediateDirectories: true, attributes: [
.posixPermissions: FilePermissions.directoryDefault.rawValue,
])
}
}

View file

@ -7,7 +7,7 @@
import Foundation
struct FilePermissions: CustomStringConvertible {
struct FilePermissions: Equatable, CustomStringConvertible {
let user: Permissions
let group: Permissions
let other: Permissions
@ -16,15 +16,22 @@ struct FilePermissions: CustomStringConvertible {
[user, group, other].map { $0.description }.joined()
}
static let `default`: FilePermissions = "rw-r--r--"
static let fileDefault: FilePermissions = "rw-r--r--"
static let directoryDefault: FilePermissions = "rwxr-xr-x"
}
extension FilePermissions {
init(string: String) {
user = Permissions(string: String(string.prefix(3)))
group = Permissions(string: String(string.dropFirst(3).prefix(3)))
other = Permissions(string: String(string.dropFirst(6).prefix(3)))
init?(string: String) {
guard let user = Permissions(string: String(string.prefix(3))),
let group = Permissions(string: String(string.dropFirst(3).prefix(3))),
let other = Permissions(string: String(string.dropFirst(6).prefix(3)))
else {
return nil
}
self.user = user
self.group = group
self.other = other
}
}
@ -34,14 +41,14 @@ extension FilePermissions: RawRepresentable {
}
init(rawValue: Int16) {
user = Permissions(rawValue: rawValue >> 6 & 7)
group = Permissions(rawValue: rawValue >> 3 & 7)
other = Permissions(rawValue: rawValue >> 0 & 7)
user = Permissions(rawValue: rawValue >> 6 & 0b111)
group = Permissions(rawValue: rawValue >> 3 & 0b111)
other = Permissions(rawValue: rawValue >> 0 & 0b111)
}
}
extension FilePermissions: ExpressibleByStringLiteral {
init(stringLiteral value: String) {
self.init(string: value)
self.init(string: value)!
}
}

View file

@ -17,10 +17,10 @@ protocol FileWriting {
extension FileWriting {
func write(data: Data, to fileURL: URL) throws {
try write(data: data, to: fileURL, permissions: .default)
try write(data: data, to: fileURL, permissions: .fileDefault)
}
func write(string: String, to fileURL: URL) throws {
try write(string: string, to: fileURL, permissions: .default)
try write(string: string, to: fileURL, permissions: .fileDefault)
}
}

View file

@ -10,6 +10,10 @@ import Foundation
struct Permissions: OptionSet {
let rawValue: Int16
static let none = Permissions(rawValue: 0)
// These raw values match those used by Unix file systems and must not be changed.
static let execute = Permissions(rawValue: 1 << 0)
static let write = Permissions(rawValue: 1 << 1)
static let read = Permissions(rawValue: 1 << 2)
@ -18,16 +22,34 @@ struct Permissions: OptionSet {
self.rawValue = rawValue
}
init(string: String) {
init?(string: String) {
self.init(rawValue: 0)
if string[string.startIndex] == "r" {
switch string[string.startIndex] {
case "r":
insert(.read)
case "-":
break
default:
return nil
}
if string[string.index(string.startIndex, offsetBy: 1)] == "w" {
switch string[string.index(string.startIndex, offsetBy: 1)] {
case "w":
insert(.write)
case "-":
break
default:
return nil
}
if string[string.index(string.startIndex, offsetBy: 2)] == "x" {
switch string[string.index(string.startIndex, offsetBy: 2)] {
case "x":
insert(.execute)
case "-":
break
default:
return nil
}
}
}
@ -44,6 +66,6 @@ extension Permissions: CustomStringConvertible {
extension Permissions: ExpressibleByStringLiteral {
init(stringLiteral value: String) {
self.init(string: value)
self.init(string: value)!
}
}

View file

@ -0,0 +1,45 @@
//
// Date+SugarTests.swift
// samhuri.net
//
// Created by Sami Samhuri on 2019-12-31.
//
import XCTest
@testable import samhuri_net
extension Date {
final class Tests: XCTestCase {
var date: Date!
override func setUp() {
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = TimeZone(secondsFromGMT: 0)!
Date.defaultCalendar = calendar
date = Date(timeIntervalSince1970: 0)
}
override func tearDown() {
Date.defaultCalendar = .current
date = nil
}
func testYear() {
XCTAssertEqual(1970, date.year)
}
func testMonth() {
XCTAssertEqual(1, date.month)
}
func testDay() {
XCTAssertEqual(1, date.day)
}
static var allTests = [
("testYear", testYear),
("testMonth", testMonth),
("testDay", testDay),
]
}
}

View file

@ -0,0 +1,63 @@
//
// FilePermissionsTests.swift
// samhuri.net
//
// Created by Sami Samhuri on 2019-12-31.
//
import XCTest
@testable import samhuri_net
extension FilePermissions {
final class Tests: XCTestCase {
func testDescription() {
XCTAssertEqual("---------", FilePermissions(user: "---", group: "---", other: "---").description)
XCTAssertEqual("r--r--r--", FilePermissions(user: "r--", group: "r--", other: "r--").description)
XCTAssertEqual("-w--w--w-", FilePermissions(user: "-w-", group: "-w-", other: "-w-").description)
XCTAssertEqual("--x--x--x", FilePermissions(user: "--x", group: "--x", other: "--x").description)
XCTAssertEqual("rwxr-xr--", FilePermissions(user: "rwx", group: "r-x", other: "r--").description)
}
func testInitFromString() {
XCTAssertEqual(FilePermissions(user: "---", group: "---", other: "---"), FilePermissions(string: "---------"))
XCTAssertEqual(FilePermissions(user: "r--", group: "r--", other: "r--"), FilePermissions(string: "r--r--r--"))
XCTAssertEqual(FilePermissions(user: "-w-", group: "-w-", other: "-w-"), FilePermissions(string: "-w--w--w-"))
XCTAssertEqual(FilePermissions(user: "--x", group: "--x", other: "--x"), FilePermissions(string: "--x--x--x"))
XCTAssertEqual(FilePermissions(user: "rwx", group: "r-x", other: "r--"), FilePermissions(string: "rwxr-xr--"))
// Refuses to initialize with nonsense.
XCTAssertNil(FilePermissions(string: "abcdefghi"))
XCTAssertNil(FilePermissions(string: "abcrwxrwx"))
XCTAssertNil(FilePermissions(string: "rwxabcrwx"))
XCTAssertNil(FilePermissions(string: "rwxrwxabc"))
}
func testInitFromRawValue() {
XCTAssertEqual("---------", FilePermissions(rawValue: 0o000))
XCTAssertEqual("rwxr-xr-x", FilePermissions(rawValue: 0o755))
XCTAssertEqual("rw-r--r--", FilePermissions(rawValue: 0o644))
XCTAssertEqual("rw-------", FilePermissions(rawValue: 0o600))
XCTAssertEqual("rwxrwxrwx", FilePermissions(rawValue: 0o777))
}
func testRawValue() {
XCTAssertEqual(0o000, FilePermissions(string: "---------")!.rawValue)
XCTAssertEqual(0o755, FilePermissions(string: "rwxr-xr-x")!.rawValue)
XCTAssertEqual(0o644, FilePermissions(string: "rw-r--r--")!.rawValue)
XCTAssertEqual(0o600, FilePermissions(string: "rw-------")!.rawValue)
XCTAssertEqual(0o777, FilePermissions(string: "rwxrwxrwx")!.rawValue)
}
func testExpressibleByStringLiteral() {
XCTAssertEqual(FilePermissions(user: "rwx", group: "r-x", other: "r-x"), "rwxr-xr-x")
}
static var allTests = [
("testDescription", testDescription),
("testInitFromString", testInitFromString),
("testInitFromRawValue", testInitFromRawValue),
("testRawValue", testRawValue),
("testExpressibleByStringLiteral", testExpressibleByStringLiteral),
]
}
}

View file

@ -0,0 +1,67 @@
//
// PermissionsTests.swift
// samhuri.net
//
// Created by Sami Samhuri on 2019-12-31.
//
import XCTest
@testable import samhuri_net
extension Permissions {
final class Tests: XCTestCase {
func testOptionsAreMutuallyExclusive() {
// If any of the bits overlap then the `or` value will be less than the sum of the raw values.
let allValues = [Permissions.execute, Permissions.write, Permissions.read].map { $0.rawValue }
XCTAssertEqual(allValues.reduce(0, +), allValues.reduce(0, |))
}
func testRawValuesAreUnixy() {
XCTAssertEqual(0o0, Permissions.none.rawValue)
XCTAssertEqual(0o4, Permissions.read.rawValue)
XCTAssertEqual(0o2, Permissions.write.rawValue)
XCTAssertEqual(0o1, Permissions.execute.rawValue)
}
func testInitFromString() {
XCTAssertEqual([.none], Permissions(string: "---"))
XCTAssertEqual([.execute], Permissions(string: "--x"))
XCTAssertEqual([.write], Permissions(string: "-w-"))
XCTAssertEqual([.read], Permissions(string: "r--"))
XCTAssertEqual([.read, .write], Permissions(string: "rw-"))
XCTAssertEqual([.read, .execute], Permissions(string: "r-x"))
XCTAssertEqual([.write, .execute], Permissions(string: "-wx"))
XCTAssertEqual([.read, .write, .execute], Permissions(string: "rwx"))
// Refuses to initialize with nonsense.
XCTAssertNil(Permissions(string: "abc"))
XCTAssertNil(Permissions(string: "awx"))
XCTAssertNil(Permissions(string: "rax"))
XCTAssertNil(Permissions(string: "rwa"))
}
func testDescription() {
XCTAssertEqual("---", Permissions.none.description)
XCTAssertEqual("r--", Permissions.read.description)
XCTAssertEqual("-w-", Permissions.write.description)
XCTAssertEqual("--x", Permissions.execute.description)
XCTAssertEqual("rw-", Permissions(arrayLiteral: [.read, .write]).description)
XCTAssertEqual("r-x", Permissions(arrayLiteral: [.read, .execute]).description)
XCTAssertEqual("-wx", Permissions(arrayLiteral: [.write, .execute]).description)
XCTAssertEqual("rwx", Permissions(arrayLiteral: [.read, .write, .execute]).description)
}
func testExpressibleByStringLiteral() {
XCTAssertEqual(Permissions.read, "r--")
}
static var allTests = [
("testOptionsAreMutuallyExclusive", testOptionsAreMutuallyExclusive),
("testRawValuesAreUnixy", testRawValuesAreUnixy),
("testInitFromString", testInitFromString),
("testDescription", testDescription),
("testExpressibleByStringLiteral", testExpressibleByStringLiteral),
]
}
}

View file

@ -3,6 +3,9 @@ import XCTest
#if !canImport(ObjectiveC)
public func allTests() -> [XCTestCaseEntry] {
return [
testCase(Date.Tests.allTests),
testCase(Permissions.Tests.allTests),
testCase(FilePermissions.Tests.allTests),
testCase(samhuri.net.Tests.allTests),
]
}