         return try PropertyListDecoder().decode(T.self, from: data)
     }
 
-    expectRoundTripEquality(of: value, encode: encode, decode: decode)
+    expectRoundTripEquality(of: value, encode: encode, decode: decode, lineNumber: lineNumber)
 }
 
 // MARK: - Helper Types

    func test_DateComponents_JSON() {
        let calendar = Calendar(identifier: .gregorian)
        let components = calendar.dateComponents(dateComponents, from: Date())
        expectRoundTripEqualityThroughJSON(for: components)
    }

    func test_DateComponents_Plist() {
        let calendar = Calendar(identifier: .gregorian)
        let components = calendar.dateComponents(dateComponents, from: Date())
        expectRoundTripEqualityThroughPlist(for: components)
    }

    // MARK: - DateInterval
    @available(OSX 10.12, iOS 10.10, watchOS 3.0, tvOS 10.0, *)
    lazy var dateIntervalValues: [DateInterval] = [
        DateInterval(),
        DateInterval(start: Date.distantPast, end: Date()),
        DateInterval(start: Date(), end: Date.distantFuture),
        DateInterval(start: Date.distantPast, end: Date.distantFuture)
    ]

    @available(OSX 10.12, iOS 10.10, watchOS 3.0, tvOS 10.0, *)
    func test_DateInterval_JSON() {
        for interval in dateIntervalValues {
            expectRoundTripEqualityThroughJSON(for: interval)
        }
    }

    @available(OSX 10.12, iOS 10.10, watchOS 3.0, tvOS 10.0, *)
    func test_DateInterval_Plist() {
        for interval in dateIntervalValues {
            expectRoundTripEqualityThroughPlist(for: interval)
        }
    }

    // MARK: - Decimal
    lazy var decimalValues: [Decimal] = [
        Decimal.leastFiniteMagnitude,
        Decimal.greatestFiniteMagnitude,
        Decimal.leastNormalMagnitude,
        Decimal.leastNonzeroMagnitude,
        Decimal(),

        // Decimal.pi does not round-trip at the moment.
        // See rdar://problem/33165355
        // Decimal.pi,
    ]

    func test_Decimal_JSON() {
        for decimal in decimalValues {
            // Decimal encodes as a number in JSON and cannot be encoded at the top level.
            expectRoundTripEqualityThroughJSON(for: TopLevelWrapper(decimal))
        }
    }

    func test_Decimal_Plist() {
        for decimal in decimalValues {
            expectRoundTripEqualityThroughPlist(for: decimal)
        }
    }

    // MARK: - IndexPath
    lazy var indexPathValues: [IndexPath] = [
        IndexPath(), // empty
        IndexPath(index: 0), // single
        IndexPath(indexes: [1, 2]), // pair
        IndexPath(indexes: [3, 4, 5, 6, 7, 8]), // array
    ]

    func test_IndexPath_JSON() {
        for indexPath in indexPathValues {
            expectRoundTripEqualityThroughJSON(for: indexPath)
        }
    }

    func test_IndexPath_Plist() {
        for indexPath in indexPathValues {
            expectRoundTripEqualityThroughPlist(for: indexPath)
        }
    }

    // MARK: - IndexSet
    lazy var indexSetValues: [IndexSet] = [
        IndexSet(),
        IndexSet(integer: 42),
        IndexSet(integersIn: 0 ..< Int.max)
    ]

    func test_IndexSet_JSON() {
        for indexSet in indexSetValues {
            expectRoundTripEqualityThroughJSON(for: indexSet)
        }
    }

    func test_IndexSet_Plist() {
        for indexSet in indexSetValues {
            expectRoundTripEqualityThroughPlist(for: indexSet)
        }
    }

    // MARK: - Locale
    lazy var localeValues: [Locale] = [
        Locale(identifier: ""),
        Locale(identifier: "en"),
        Locale(identifier: "en_US"),
        Locale(identifier: "en_US_POSIX"),
        Locale(identifier: "uk"),
        Locale(identifier: "fr_FR"),
        Locale(identifier: "fr_BE"),
        Locale(identifier: "zh-Hant-HK")
    ]

    func test_Locale_JSON() {
        for locale in localeValues {
            expectRoundTripEqualityThroughJSON(for: locale)
        }
    }

    func test_Locale_Plist() {
        for locale in localeValues {
            expectRoundTripEqualityThroughPlist(for: locale)
        }
    }

    // MARK: - Measurement
    @available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *)
    lazy var unitValues: [Dimension] = [
        UnitAcceleration.metersPerSecondSquared,
        UnitMass.kilograms,
        UnitLength.miles
    ]

    @available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *)
    func test_Measurement_JSON() {
        for unit in unitValues {
            expectRoundTripEqualityThroughJSON(for: Measurement(value: 42, unit: unit))
        }
    }

    @available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *)
    func test_Measurement_Plist() {
        for unit in unitValues {
            expectRoundTripEqualityThroughJSON(for: Measurement(value: 42, unit: unit))
        }
    }

    // MARK: - NSRange
    lazy var nsrangeValues: [NSRange] = [
        NSRange(),
        NSRange(location: 0, length: Int.max),
        NSRange(location: NSNotFound, length: 0),
    ]

    func test_NSRange_JSON() {
        for range in nsrangeValues {
            expectRoundTripEqualityThroughJSON(for: range)
        }
    }

    func test_NSRange_Plist() {
        for range in nsrangeValues {
            expectRoundTripEqualityThroughPlist(for: range)
        }
    }

    // MARK: - PersonNameComponents
    @available(OSX 10.11, iOS 9.0, *)
    lazy var personNameComponentsValues: [PersonNameComponents] = [
        makePersonNameComponents(givenName: "John", familyName: "Appleseed"),
        makePersonNameComponents(givenName: "John", familyName: "Appleseed", nickname: "Johnny"),
        makePersonNameComponents(namePrefix: "Dr.", givenName: "Jane", middleName: "A.", familyName: "Appleseed", nameSuffix: "Esq.", nickname: "Janie")
    ]

    @available(OSX 10.11, iOS 9.0, *)
    func test_PersonNameComponents_JSON() {
        for components in personNameComponentsValues {
            expectRoundTripEqualityThroughJSON(for: components)
        }
    }

    @available(OSX 10.11, iOS 9.0, *)
    func test_PersonNameComponents_Plist() {
        for components in personNameComponentsValues {
            expectRoundTripEqualityThroughPlist(for: components)
        }
    }

    // MARK: - TimeZone
    lazy var timeZoneValues: [TimeZone] = [
        TimeZone(identifier: "America/Los_Angeles")!,
        TimeZone(identifier: "UTC")!,
        TimeZone.current
    ]

    func test_TimeZone_JSON() {
        for timeZone in timeZoneValues {
            expectRoundTripEqualityThroughJSON(for: timeZone)
        }
    }

    func test_TimeZone_Plist() {
        for timeZone in timeZoneValues {
            expectRoundTripEqualityThroughPlist(for: timeZone)
        }
    }

    // MARK: - URL
    lazy var urlValues: [URL] = {
        var values: [URL] = [
            URL(fileURLWithPath: NSTemporaryDirectory()),
            URL(fileURLWithPath: "/"),
            URL(string: "http://apple.com")!,
            URL(string: "swift", relativeTo: URL(string: "http://apple.com")!)!
        ]

        if #available(OSX 10.11, iOS 9.0, *) {
            values.append(URL(fileURLWithPath: "bin/sh", relativeTo: URL(fileURLWithPath: "/")))
        }

        return values
    }()

    func test_URL_JSON() {
        for url in urlValues {
            // URLs encode as single strings in JSON. They lose their baseURL this way.
            // For relative URLs, we don't expect them to be equal to the original.
            if url.baseURL == nil {
                // This is an absolute URL; we can expect equality.
                expectRoundTripEqualityThroughJSON(for: TopLevelWrapper(url))
            } else {
                // This is a relative URL. Make it absolute first.
                let absoluteURL = URL(string: url.absoluteString)!
                expectRoundTripEqualityThroughJSON(for: TopLevelWrapper(absoluteURL))
            }
        }
    }

    func test_URL_Plist() {
        for url in urlValues {
            expectRoundTripEqualityThroughPlist(for: url)
        }
    }

    // MARK: - UUID
    lazy var uuidValues: [UUID] = [
        UUID(),
        UUID(uuidString: "E621E1F8-C36C-495A-93FC-0C247A3E6E5F")!,
        UUID(uuidString: "e621e1f8-c36c-495a-93fc-0c247a3e6e5f")!,
        UUID(uuid: uuid_t(0xe6,0x21,0xe1,0xf8,0xc3,0x6c,0x49,0x5a,0x93,0xfc,0x0c,0x24,0x7a,0x3e,0x6e,0x5f))
    ]

    func test_UUID_JSON() {
        for uuid in uuidValues {
            // We have to wrap the UUID since we cannot have a top-level string.
            expectRoundTripEqualityThroughJSON(for: UUIDCodingWrapper(uuid))
        }
    }

    func test_UUID_Plist() {
        for uuid in uuidValues {
            // We have to wrap the UUID since we cannot have a top-level string.
            expectRoundTripEqualityThroughPlist(for: UUIDCodingWrapper(uuid))
        }
    }
}

        return try decoder.decode(T.self, from: data)
    }

    expectRoundTripEquality(of: value, encode: encode, decode: decode, lineNumber: lineNumber)
}

func expectRoundTripEqualityThroughPlist<T : Codable>(for value: T, lineNumber: Int) where T : Equatable {
    let encode = { (_ value: T) throws -> Data in
        return try PropertyListEncoder().encode(value)
    }
