In this article I will be looking at defining the enums for Qualifier
and MechanismKind
. I will also be adding tests to ensure that the functions work as expected. Further I will implement a simple asMechanism()
as a proof of concept.
Qualifier
As mentioned in an earlier article. The Qualifier will consist of the following values.
+
Pass-
Fail~
SoftFail?
Neutral- None
I expect that I will want to be able to obtain the character value (rawValue) at some point in the future.
Definition
enum Qualifier: String {
case Pass
case Fail
case SoftFail
case Neutral
case None
func get() -> String {
switch self {
case .Pass:
return "+"
case .Fail:
return "-"
case .SoftFail:
return "~"
case .Neutral:
return "?"
case .None:
return ""
}
}
}
At this point I have diverged from the original definition. This gave me a chance to look at the switch statement in Swift. I think will change this in a refactor session, as I expect to be able to access the Raw Value. Scroll down to find the actual documentation.
Testing
To make testing a little cleaner and manageable moving forward. I also created a new file under DeconfSpfTests
called DeconfSpfQualifierTests.swift
.
This contains the following code.
import XCTest
@testable import DeconSpf;
final class SPFQualifierTests: XCTestCase {
func testQualifierPass() {
let Q = Qualifier.Pass;
XCTAssertEqual(Q.get(), "+");
}
func testQualifierFail() {
let Q = Qualifier.Fail;
XCTAssertEqual(Q.get(), "-");
}
func testQualifierSoftFail() {
let Q = Qualifier.SoftFail;
XCTAssertEqual(Q.get(), "~");
}
func testQualifierNeutral() {
let Q = Qualifier.Neutral;
XCTAssertEqual(Q.get(), "?");
}
func testQualifierNone() {
let Q = Qualifier.None;
XCTAssertEqual(Q.get(), "");
}
static var allTests = [
("testQualifierPass", testQualifierPass),
("testQualifierFail", testQualifierFail),
("testQualifierSoftFail", testQualifierSoftFail),
("testQualifierNeutral", testQualifierNeutral),
("testQualifierNone", testQualifierNone),
]
}
- Note: The class name needs to be unique
final class SPFQualifierTests: XCTestCase
- I am using
SPFQualifierTests
MechanismKind
I took the same approach here with MechanismKind
.
Definition
enum MechanismKind {
case Redirect, Include, A, MX, ip4, ip6, All;
func get() -> String {
switch self {
case .Redirect:
return "redirect="
case .Include:
return "include:"
case .A:
return "a"
case .MX:
return "mx"
case .ip4:
return "ip4:"
case .ip6:
return "ip6:"
case .All:
return "all"
}
}
}
Testing
I also again created a new test file called DeconfSpfMechanismKindTests
.
This also has a unique class name SPFMechanimsKindTests
.
import XCTest
@testable import DeconSpf;
final class SPFMechanimsKindTests: XCTestCase {
func testMechanimsKindRedirect() {
let MK = MechanismKind.Redirect;
XCTAssertEqual(MK.get(), "redirect=");
}
func testMechanimsKindInclude() {
let MK = MechanismKind.Include;
XCTAssertEqual(MK.get(), "include:");
}
func testMechanimsKindA() {
let MK = MechanismKind.A;
XCTAssertEqual(MK.get(), "a");
}
func testMechanimsKindMX() {
let MK = MechanismKind.MX;
XCTAssertEqual(MK.get(), "mx");
}
func testMechanimsKindIp4() {
let MK = MechanismKind.ip4;
XCTAssertEqual(MK.get(), "ip4:");
}
func testMechanimsKindIp6() {
let MK = MechanismKind.ip6;
XCTAssertEqual(MK.get(), "ip6:");
}
func testMechanimsKindAll() {
let MK = MechanismKind.All;
XCTAssertEqual(MK.get(), "all");
}
static var allTests = [
("testMechanismKindRedirect", testMechanimsKindRedirect),
("testMechanismKindInclude", testMechanimsKindInclude),
("testMechanismKindA", testMechanimsKindA),
("testMechanismKindMX", testMechanimsKindMX),
("testMechanismKindIp4", testMechanimsKindIp4),
("testMechanismKindIp6", testMechanimsKindIp6),
("testMechanismKindAll", testMechanimsKindAll),
]
}
asMechanism
Here I would refer you to the documentation on Strings and Characters.
Code
I have updated struct Mechanism
as shown below
struct Mechanims {
--snip--
func asMechanism() -> String {
var mechanismString = String();
// TODO: Qualifier
// Access the string for this mechanism's kind.
mechanismString += self.kind.get();
// Access the string for the mechanim
mechanismString += self.mechanism;
return mechanismString;
}
--snip--
}
Tests
I now have my previous test working as well as a few new ones.
func testAsMechanismIp4() {
let Mech = Mechanism(k: MechanismKind.ip4, q: Qualifier.None, m: "192.168.1.0/24");
XCTAssertEqual(Mech.asMechanism(), "ip4:192.168.1.0/24");
}
func testAsMechanismIp6() {
let Mech = Mechanism(k: MechanismKind.ip6, q: Qualifier.None, m: "X:X:X:X/16");
XCTAssertEqual(Mech.asMechanism(), "ip6:X:X:X:X/16");
}
func testAsMechanismRedirect() {
let Mech = Mechanism(k: MechanismKind.Redirect, q: Qualifier.None, m: "_spf.example.com");
XCTAssertEqual(Mech.asMechanism(), "redirect=_spf.example.com");
}
func testAsMechanismInclude() {
let Mech = Mechanism(k: MechanismKind.Include, q: Qualifier.None, m: "_spf1.example.com");
XCTAssertEqual(Mech.asMechanism(), "include:_spf1.example.com");
}
func testAsMechanismA() {
let Mech = Mechanism(k: MechanismKind.A, q: Qualifier.None, m: "");
XCTAssertEqual(Mech.asMechanism(), "a");
}
func testAsMechanismMx() {
let Mech = Mechanism(k: MechanismKind.MX, q: Qualifier.None, m: "");
XCTAssertEqual(Mech.asMechanism(), "mx");
}
Note that these tests are not complete. And do not yet cover all cases. In particular these tests will fail with several examples of A
and MX
Mechanisms.
The code for this project can now be found here.
This is the diff between Initial and Initial-asMechanism.
Closing
Today I implemented an initial get()
function for both Qualifier
and MechanismKind
. I also did an initial implementation for asMechanism()
.