Add `ConstructorTests.swift`

This commit is contained in:
Norio Nomura 2016-12-23 18:28:43 +09:00
parent 4677810740
commit adc4e6b7ef
No known key found for this signature in database
GPG Key ID: D4A7318EB7F7138D
7 changed files with 511 additions and 27 deletions

View File

@ -92,10 +92,10 @@ public final class Constructor {
public func bool(from node: Node) -> Any {
guard let string = node.string else { fatalError("Never happen this") }
switch string {
case "true", "True", "TRUE":
switch string.lowercased() {
case "true", "yes", "on":
return true
case "false", "False", "FALSE":
case "false", "no", "off":
return false
default:
return string
@ -103,7 +103,7 @@ public final class Constructor {
}
public func float(from node: Node) -> Any {
guard let string = node.string else { fatalError("Never happen this") }
guard var string = node.string else { fatalError("Never happen this") }
switch string {
case ".inf", ".Inf", ".INF", "+.inf", "+.Inf", "+.INF":
return Double.infinity
@ -112,6 +112,24 @@ public final class Constructor {
case ".nan", ".NaN", ".NAN":
return Double.nan
default:
string = string.replacingOccurrences(of: "_", with: "")
if string.contains(":") {
var sign: Double = 1
if string.hasPrefix("-") {
sign = -1
string = string.substring(from: string.index(after: string.startIndex))
} else if string.hasPrefix("+") {
string = string.substring(from: string.index(after: string.startIndex))
}
let digits = string.components(separatedBy: ":").flatMap(Double.init).reversed()
var base = 1.0
var value = 0.0
digits.forEach {
value += $0 * base
base *= 60
}
return sign * value
}
return Double(string) ?? string
}
}
@ -119,7 +137,7 @@ public final class Constructor {
public func null(from node: Node) -> Any {
guard let string = node.string else { fatalError("Never happen this") }
switch string {
case "~", "null", "Null", "NULL":
case "", "~", "null", "Null", "NULL":
return NSNull()
default:
return string
@ -127,18 +145,43 @@ public final class Constructor {
}
public func int(from node: Node) -> Any {
guard let string = node.string else { fatalError("Never happen this") }
guard var string = node.string else { fatalError("Never happen this") }
string = string.replacingOccurrences(of: "_", with: "")
if string == "0" {
return 0
}
if string.hasPrefix("0x") {
let hexadecimal = string.substring(from: string.index(string.startIndex, offsetBy: 2))
return Int(hexadecimal, radix: 16) ?? string
}
if string.hasPrefix("0b") {
let octal = string.substring(from: string.index(string.startIndex, offsetBy: 2))
return Int(octal, radix: 2) ?? string
}
if string.hasPrefix("0o") {
let octal = string.substring(from: string.index(string.startIndex, offsetBy: 2))
return Int(octal, radix: 8) ?? string
}
if string.hasPrefix("0b") {
let octal = string.substring(from: string.index(string.startIndex, offsetBy: 2))
return Int(octal, radix: 2) ?? string
if string.hasPrefix("0") {
let octal = string.substring(from: string.index(after: string.startIndex))
return Int(octal, radix: 8) ?? string
}
if string.contains(":") {
var sign = 1
if string.hasPrefix("-") {
sign = -1
string = string.substring(from: string.index(after: string.startIndex))
} else if string.hasPrefix("+") {
string = string.substring(from: string.index(after: string.startIndex))
}
let digits = string.components(separatedBy: ":").flatMap({ Int($0) }).reversed()
var base = 1
var value = 0
digits.forEach {
value += $0 * base
base *= 60
}
return sign * value
}
return Int(string) ?? string
}
@ -151,10 +194,66 @@ public final class Constructor {
public func timestamp(from node: Node) -> Any {
guard let string = node.string else { fatalError("Never happen this") }
return ISO8601Formatter.date(from: string) ?? string
let range = NSRange(location: 0, length: string.utf16.count)
guard let result = timestampPattern.firstMatch(in: string, options: [], range: range),
result.range.location != NSNotFound else {
return string
}
#if os(Linux)
let components = (1..<result.numberOfRanges).map(result.range(at:)).map(string.substring)
#else
let components = (1..<result.numberOfRanges).map(result.rangeAt).map(string.substring)
#endif
var datecomponents = DateComponents()
datecomponents.calendar = Calendar(identifier: .gregorian)
datecomponents.year = components[0].flatMap { Int($0) }
datecomponents.month = components[1].flatMap { Int($0) }
datecomponents.day = components[2].flatMap { Int($0) }
datecomponents.hour = components[3].flatMap { Int($0) }
datecomponents.minute = components[4].flatMap { Int($0) }
datecomponents.second = components[5].flatMap { Int($0) }
datecomponents.nanosecond = components[6].flatMap {
let length = $0.characters.count
let nanosecond: Int?
if length < 9 {
nanosecond = Int($0 + String(repeating: "0", count: 9 - length))
} else {
nanosecond = Int($0.substring(to: $0.index($0.startIndex, offsetBy: 9)))
}
return nanosecond
}
datecomponents.timeZone = {
// guard components[7] != nil else { return TimeZone(secondsFromGMT: 0) }
var seconds = 0
seconds += components[9].flatMap({ Int($0) }).map({ $0 * 60 * 60 }) ?? 0 // hour
seconds += components[10].flatMap({ Int($0) }).map({ $0 * 60 }) ?? 0 // minute
if components[8] == "-" { // sign
seconds *= -1
}
return TimeZone(secondsFromGMT: seconds)
}()
// Using `DateComponents.date` causes crash on Linux
return NSCalendar(identifier: .gregorian)?.date(from: datecomponents) ?? string
}
}
fileprivate let timestampPattern: NSRegularExpression = pattern([
"^([0-9][0-9][0-9][0-9])", // year
"-([0-9][0-9]?)", // month
"-([0-9][0-9]?)", // day
"(?:(?:[Tt]|[ \\t]+)",
"([0-9][0-9]?)", // hour
":([0-9][0-9])", // minute
":([0-9][0-9])", // second
"(?:\\.([0-9]*))?", // fraction
"(?:[ \\t]*(Z|([-+])([0-9][0-9]?)", // tz_sign, tz_hour
"(?::([0-9][0-9]))?))?)?$" // tz_minute
].joined()
)
extension Constructor {
public static let `default` = Constructor([
// Failsafe Schema
@ -181,6 +280,19 @@ fileprivate let ISO8601Formatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
dateFormatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"
dateFormatter.dateFormat = "yyyy-MM-ddTHH:mm:ssZ"
return dateFormatter
}()
fileprivate extension String {
func substring(with range: NSRange) -> String? {
guard range.location != NSNotFound else { return nil }
let utf16lowerBound = utf16.index(utf16.startIndex, offsetBy: range.location)
let utf16upperBound = utf16.index(utf16lowerBound, offsetBy: range.length)
guard let lowerBound = utf16lowerBound.samePosition(in: self),
let upperBound = utf16upperBound.samePosition(in: self) else {
fatalError("Never happen this")
}
return substring(with: lowerBound..<upperBound)
}
}

View File

@ -49,21 +49,23 @@ extension Resolver {
"|[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$"
].joined()),
(.float, [
"^(?:[-+]?(\\.[0-9]+|[0-9]+(\\.[0-9]*)?)([eE][-+]?[0-9]+)?",
"^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?",
"|\\.[0-9_]+(?:[eE][-+][0-9]+)?",
"|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*",
"|[-+]?\\.(?:inf|Inf|INF)",
"|\\.(?:nan|NaN|NAN))$"
].joined()),
(.merge, "^(?:<<)$"),
(.null, [
"^(?: ~",
"^(?:~",
"|null|Null|NULL",
"| )$"
"|)$"
].joined()),
(.timestamp, [
"^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]",
"|[0-9][0-9][0-9][0-9] -[0-9][0-9]? -[0-9][0-9]?",
"|[0-9][0-9][0-9][0-9]-[0-9][0-9]?-[0-9][0-9]?",
"(?:[Tt]|[ \\t]+)[0-9][0-9]?",
":[0-9][0-9] :[0-9][0-9] (?:\\.[0-9]*)?",
":[0-9][0-9]:[0-9][0-9](?:\\.[0-9]*)?",
"(?:[ \\t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$"
].joined()),
(.value, "^(?:=)$")
@ -76,7 +78,7 @@ extension Resolver {
func pattern(_ string: String) -> NSRegularExpression {
do {
return try .init(pattern: string, options: .allowCommentsAndWhitespace)
return try .init(pattern: string, options: [])
} catch {
fatalError("Never happen this!")
}

View File

@ -3,6 +3,7 @@ import XCTest
@testable import YamsTests
XCTMain([
testCase(ConstructorTests.allTests),
testCase(ParserTests.allTests),
testCase(ResolverTests.allTests),
testCase(StringTests.allTests),

View File

@ -0,0 +1,332 @@
//
// ConstructorTests.swift
// Yams
//
// Created by Norio Nomura on 12/23/16.
// Copyright (c) 2016 Yams. All rights reserved.
//
import Foundation
import XCTest
import Yams
class ConstructorTests: XCTestCase { // swiftlint:disable:this type_body_length
// Samples come from PyYAML.
func testBinary() throws {
let example = [
"canonical: !!binary \"\\",
" R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\\",
" OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\\",
" +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\\",
" AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=\"",
"generic: !!binary |",
" R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5",
" OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+",
" +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC",
" AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=",
"description:",
" The binary value above is a tiny arrow encoded as a gif image.",
""
].joined(separator: "\n")
let objects = try Yams.load(yaml: example)
let data = Data(base64Encoded: [
" R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5",
" OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+",
" +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC",
" AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs="
].joined(), options: .ignoreUnknownCharacters)!
let expected: [String:Any] = [
"canonical": data,
"generic": data,
"description": "The binary value above is a tiny arrow encoded as a gif image."
]
YamsAssertEqual(objects, expected)
}
func testBool() throws {
let example = [
"canonical: yes",
"answer: NO",
"logical: True",
"option: on",
"",
"",
"but:",
" y: is a string",
" n: is a string",
""
].joined(separator: "\n")
let objects = try Yams.load(yaml: example)
let expected: [String:Any] = [
"canonical": true,
"answer": false,
"logical": true,
"option": true,
"but": [
"y": "is a string",
"n": "is a string"
]
]
YamsAssertEqual(objects, expected)
}
func testFloat() throws {
let example = [
"canonical: 6.8523015e+5",
"exponential: 685.230_15e+03",
"fixed: 685_230.15",
"sexagesimal: 190:20:30.15",
"negative infinity: -.inf",
"not a number: .NaN",
""
].joined(separator: "\n")
let objects = try Yams.load(yaml: example)
let expected: [String:Any] = [
"canonical": 685230.15,
"exponential": 685230.15,
"fixed": 685230.15,
"sexagesimal": 685230.15,
"negative infinity": -Double.infinity,
"not a number": Double.nan
]
YamsAssertEqual(objects, expected)
}
func testInt() throws {
let example = [
"canonical: 685230",
"decimal: +685_230",
"octal: 02472256",
"hexadecimal: 0x_0A_74_AE",
"binary: 0b1010_0111_0100_1010_1110",
"sexagesimal: 190:20:30",
""
].joined(separator: "\n")
let objects = try Yams.load(yaml: example)
let expected: [String:Any] = [
"canonical": 685230,
"decimal": 685230,
"octal": 685230,
"hexadecimal": 685230,
"binary": 685230,
"sexagesimal": 685230
]
YamsAssertEqual(objects, expected)
}
func testMap() throws {
let example = [
"# Unordered set of key: value pairs.",
"Block style: !!map",
" Clark : Evans",
" Brian : Ingerson",
" Oren : Ben-Kiki",
"Flow style: !!map { Clark: Evans, Brian: Ingerson, Oren: Ben-Kiki }",
""
].joined(separator: "\n")
let objects = try Yams.load(yaml: example)
let expected: [String:Any] = [
"Block style": [
"Clark" : "Evans",
"Brian" : "Ingerson",
"Oren" : "Ben-Kiki"
],
"Flow style": ["Clark": "Evans", "Brian": "Ingerson", "Oren": "Ben-Kiki"]
]
YamsAssertEqual(objects, expected)
}
func testMerge() throws { // swiftlint:disable:this function_body_length
let example = [
"---",
"- &CENTER { x: 1, 'y': 2 }",
"- &LEFT { x: 0, 'y': 2 }",
"- &BIG { r: 10 }",
"- &SMALL { r: 1 }",
"",
"# All the following maps are equal:",
"",
"- # Explicit keys",
" x: 1",
" 'y': 2",
" r: 10",
" label: center/big",
"",
"- # Merge one map",
" << : *CENTER",
" r: 10",
" label: center/big",
"",
"- # Merge multiple maps",
" << : [ *CENTER, *BIG ]",
" label: center/big",
"",
"- # Override",
" << : [ *BIG, *LEFT, *SMALL ]",
" x: 1",
" label: center/big",
""
].joined(separator: "\n")
let objects = try Yams.load(yaml: example)
let expected: [[String:Any]] = [
[ "x": 1, "y": 2 ],
[ "x": 0, "y": 2 ],
[ "r": 10 ],
[ "r": 1 ],
[ "x": 1, "y": 2, "r": 10, "label": "center/big" ],
[ "x": 1, "y": 2, "r": 10, "label": "center/big" ],
[ "x": 1, "y": 2, "r": 10, "label": "center/big" ],
[ "x": 1, "y": 2, "r": 10, "label": "center/big" ]
]
YamsAssertEqual(objects, expected)
}
func testNull() throws {
let example = [
"# A document may be null.",
"---",
"---",
"# This mapping has four keys,",
"# one has a value.",
"empty:",
"canonical: ~",
"english: null",
"~: null key",
"---",
"# This sequence has five",
"# entries, two have values.",
"sparse:",
" - ~",
" - 2nd entry",
" -",
" - 4th entry",
" - Null",
""
].joined(separator: "\n")
let objects = Array(try Yams.load_all(yaml: example))
let expected: [Any] = [
NSNull(),
[
"empty": NSNull(),
"canonical": NSNull(),
"english": NSNull(),
"~": "null key" // null key is not supported yet.
], [
"sparse": [
NSNull(),
"2nd entry",
NSNull(),
"4th entry",
NSNull()
]
]
]
YamsAssertEqual(objects, expected)
}
func testSeq() throws {
let example = [
"# Ordered sequence of nodes",
"Block style: !!seq",
"- Mercury # Rotates - no light/dark sides.",
"- Venus # Deadliest. Aptly named.",
"- Earth # Mostly dirt.",
"- Mars # Seems empty.",
"- Jupiter # The king.",
"- Saturn # Pretty.",
"- Uranus # Where the sun hardly shines.",
"- Neptune # Boring. No rings.",
"- Pluto # You call this a planet?",
"Flow style: !!seq [ Mercury, Venus, Earth, Mars, # Rocks",
" Jupiter, Saturn, Uranus, Neptune, # Gas",
" Pluto ] # Overrated",
"",
""
].joined(separator: "\n")
let objects = try Yams.load(yaml: example)
let expected: [String:Any] = [
"Block style": [
"Mercury",
"Venus",
"Earth",
"Mars",
"Jupiter",
"Saturn",
"Uranus",
"Neptune",
"Pluto"
],
"Flow style": [ "Mercury", "Venus", "Earth", "Mars",
"Jupiter", "Saturn", "Uranus", "Neptune",
"Pluto" ]
]
YamsAssertEqual(objects, expected)
}
func testTimestamp() throws {
let example = [
"canonical: 2001-12-15T02:59:43.1Z",
"valid iso8601: 2001-12-14t21:59:43.10-05:00",
"space separated: 2001-12-14 21:59:43.10 -5",
"no time zone (Z): 2001-12-15 2:59:43.10",
"date (00:00:00Z): 2002-12-14",
""
].joined(separator: "\n")
let objects = try Yams.load(yaml: example)
let expected: [String:Any] = [
"canonical": timestamp( 0, 2001, 12, 15, 02, 59, 43, 0.1),
"valid iso8601": timestamp(-5, 2001, 12, 14, 21, 59, 43, 0.1),
"space separated": timestamp(-5, 2001, 12, 14, 21, 59, 43, 0.1),
"no time zone (Z)": timestamp( 0, 2001, 12, 15, 02, 59, 43, 0.1),
"date (00:00:00Z)": timestamp( 0, 2002, 12, 14)
]
YamsAssertEqual(objects, expected)
}
func testValue() throws {
let example = [
"--- # Old schema",
"link with:",
" - library1.dll",
" - library2.dll",
"--- # New schema",
"link with:",
" - = : library1.dll",
" version: 1.2",
" - = : library2.dll",
" version: 2.3",
""
].joined(separator: "\n")
let objects = Array(try Yams.load_all(yaml: example))
let expected: [Any] = [
[
"link with": [ "library1.dll", "library2.dll" ]
], [
"link with": [
[ "=": "library1.dll", "version": 1.2 ],
[ "=": "library2.dll", "version": 2.3 ]
]
]
]
YamsAssertEqual(objects, expected)
}
}
extension ConstructorTests {
static var allTests: [(String, (ConstructorTests) -> () throws -> Void)] {
return [
("testBinary", testBinary),
("testBool", testBool),
("testFloat", testFloat),
("testInt", testInt),
("testMap", testMap),
("testMerge", testMerge),
("testNull", testNull),
("testSeq", testSeq),
("testTimestamp", testTimestamp),
("testValue", testValue)
]
}
}

View File

@ -166,12 +166,18 @@ class ParserTests: XCTestCase { // swiftlint:disable:this type_body_length
"action: grand slam",
"..."
].joined(separator: "\n")
let objects = try Yams.load(yaml: example)
let expected: [String:Any] = [
"time": "20:03:20",
"player": "Sammy Sosa",
"action": "strike (miss)"
let objects = Array(try Yams.load_all(yaml: example))
let expected: [[String:Any]] = [
[
"time": 72200,
"player": "Sammy Sosa",
"action": "strike (miss)"
], [
"time": 72227,
"player": "Sammy Sosa",
"action": "grand slam"
]
]
YamsAssertEqual(objects, expected)
}
@ -502,7 +508,7 @@ class ParserTests: XCTestCase { // swiftlint:disable:this type_body_length
]
let expected: [String:Any] = [
"invoice" : 34843,
"date" : "2001-01-23",
"date" : timestamp(0, 2001, 1, 23),
"bill-to" : billTo,
"ship-to" : billTo,
"product" : [
@ -559,17 +565,17 @@ class ParserTests: XCTestCase { // swiftlint:disable:this type_body_length
let objects = Array(try Yams.load_all(yaml: example))
let expected: [Any] = [
[
"Time": "2001-11-23 15:01:42 -5",
"Time": timestamp(-5, 2001, 11, 23, 15, 1, 42),
"User": "ed",
"Warning": "This is an error message for the log file"
],
[
"Time": "2001-11-23 15:02:31 -5",
"Time": timestamp(-5, 2001, 11, 23, 15, 2, 31),
"User": "ed",
"Warning": "A slightly different error message."
],
[
"Date": "2001-11-23 15:03:17 -5",
"Date": timestamp(-5, 2001, 11, 23, 15, 3, 17),
"User": "ed",
"Fatal": "Unknown variable \"bar\"",
"Stack": [

View File

@ -6,8 +6,33 @@
// Copyright (c) 2016 Yams. All rights reserved.
//
import Foundation
import XCTest
func timestamp(_ timeZoneHour: Int = 0,
_ year: Int? = nil,
_ month: Int? = nil,
_ day: Int? = nil,
_ hour: Int? = nil,
_ minute: Int? = nil,
_ second: Int? = nil,
_ fraction: Double? = nil ) -> Date {
let calendar = Calendar(identifier: .gregorian)
let timeZone = TimeZone(secondsFromGMT: timeZoneHour * 60 * 60)
#if os(Linux)
let NSEC_PER_SEC = 1000000000
#endif
let nanosecond = fraction.map { Int($0 * Double(NSEC_PER_SEC)) }
let datecomponents = DateComponents(calendar: calendar, timeZone: timeZone,
year: year, month: month, day: day,
hour: hour, minute: minute, second: second, nanosecond: nanosecond)
// Using `DateComponents.date` causes crash on Linux
guard let date = NSCalendar(identifier: .gregorian)?.date(from: datecomponents) else {
fatalError("Never happen this")
}
return date
}
/// AssertEqual for Any
///
/// - Parameters:
@ -17,10 +42,12 @@ import XCTest
/// - file: file path string
/// - line: line number
/// - Returns: true if lhs is equal to rhs
@discardableResult func YamsAssertEqual(_ lhs: Any?, _ rhs: Any?,
@discardableResult func YamsAssertEqual(_ lhs: Any?, _ rhs: Any?, // swiftlint:disable:this function_body_length
_ context: @autoclosure @escaping () -> String = "",
file: StaticString = #file, line: UInt = #line) -> Bool {
// use inner function for capturing `file` and `line`
// swiftlint:disable:next cyclomatic_complexity
@discardableResult func equal(_ lhs: Any?, _ rhs: Any?,
_ context: @autoclosure @escaping () -> String = "") -> Bool {
switch (lhs, rhs) {

View File

@ -8,6 +8,7 @@
/* Begin PBXBuildFile section */
6C0488EC1E0BE113006F9F80 /* TestHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C0488EB1E0BE113006F9F80 /* TestHelper.swift */; };
6C0488EE1E0CBD56006F9F80 /* ConstructorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C0488ED1E0CBD56006F9F80 /* ConstructorTests.swift */; };
6C0D2A361E0A934B00C45545 /* Constructor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C0D2A351E0A934B00C45545 /* Constructor.swift */; };
6C4A22071DF8553C002A0206 /* String+Yams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4A22061DF8553C002A0206 /* String+Yams.swift */; };
6C4A22091DF855BB002A0206 /* StringTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4A22081DF855BB002A0206 /* StringTests.swift */; };
@ -43,6 +44,7 @@
/* Begin PBXFileReference section */
6C0488EB1E0BE113006F9F80 /* TestHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestHelper.swift; sourceTree = "<group>"; };
6C0488ED1E0CBD56006F9F80 /* ConstructorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstructorTests.swift; sourceTree = "<group>"; };
6C0D2A351E0A934B00C45545 /* Constructor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Constructor.swift; sourceTree = "<group>"; };
6C4A22061DF8553C002A0206 /* String+Yams.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Yams.swift"; sourceTree = "<group>"; };
6C4A22081DF855BB002A0206 /* StringTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringTests.swift; sourceTree = "<group>"; };
@ -123,6 +125,7 @@
OBJ_24 /* YamsTests */ = {
isa = PBXGroup;
children = (
6C0488ED1E0CBD56006F9F80 /* ConstructorTests.swift */,
6C6834D01E0297390047B4D1 /* ParserTests.swift */,
6C6834D41E02BC1F0047B4D1 /* ResolverTests.swift */,
6C4A22081DF855BB002A0206 /* StringTests.swift */,
@ -307,6 +310,7 @@
files = (
6C4A22091DF855BB002A0206 /* StringTests.swift in Sources */,
6C0488EC1E0BE113006F9F80 /* TestHelper.swift in Sources */,
6C0488EE1E0CBD56006F9F80 /* ConstructorTests.swift in Sources */,
OBJ_59 /* YamlErrorTests.swift in Sources */,
6C6834D11E0297390047B4D1 /* ParserTests.swift in Sources */,
6C6834D51E02BC1F0047B4D1 /* ResolverTests.swift in Sources */,