blob: 012918c70c2ceadb4312953916bf7b8ba90589fd [file] [log] [blame]
//===--- CollectionCasts.swift.gyb ----------------------------*- swift -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
// RUN: %empty-directory(%t)
// RUN: %gyb %s -o %t/CollectionCasts.swift
// RUN: %line-directive %t/CollectionCasts.swift -- %target-build-swift %t/CollectionCasts.swift -o %t/a.out
// RUN: %target-codesign %t/a.out && %line-directive %t/CollectionCasts.swift -- %target-run %t/a.out 2>&1
// REQUIRES: executable_test
import StdlibUnittest
class Base : Hashable {
var value: Int
init(_ value: Int) {
self.value = value
}
func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
}
func == (lhs: Base, rhs: Base) -> Bool {
return lhs.value == rhs.value
}
class Derived : Base {}
protocol AnyFoo {
init(_ value: Int)
}
extension Int : AnyFoo { }
var tests = TestSuite("CollectionCasts")
// A wrapper for an as? cast that suppresses warnings when the cast always
// succeeds.
func cast<T, U>(_ x: T, to result: U.Type) -> U? {
return x as? U
}
%{
classKeys = ('Derived', 'Base')
classValues = classKeys + ('AnyObject', 'Any')
nonClassKeys = ('Int',)
nonClassValues = ('Int', 'AnyFoo', 'Any')
}%
% for keys, values in [ (classKeys, classValues), (nonClassKeys, nonClassValues) ]:
% for ki0, Key0 in enumerate(keys):
% DynamicKey = keys[0] if Key0.startswith('Any') else Key0
% for Key1 in keys[ki0:]:
% for Collection in 'Array', 'Set':
tests.test("${Collection}/Up/${Key0}=>${Key1}") {
let source : ${Collection} = [
${DynamicKey}(42) as ${Key0},
${DynamicKey}(17) as ${Key0}]
let upcasted = source as ${Collection}<${Key1}>
expectEqual(source.count, upcasted.count)
for x in source {
expectTrue(upcasted.contains(x))
}
}
% if Key1 != Key0:
% for method in 'Direct', 'Indirect':
tests.test("${Collection}/Down/${method}/${Key1}=>${Key0}") {
let source : ${Collection} = [
${DynamicKey}(42) as ${Key1},
${DynamicKey}(17) as ${Key1}]
% if method == 'Direct':
guard let downcasted = expectNotNil(source as? ${Collection}<${Key0}>)
else { return }
% else:
guard let downcasted = expectNotNil(cast(source, to: ${Collection}<${Key0}>.self))
else { return }
% end
expectEqual(source.count, downcasted.count)
for x in downcasted {
expectTrue(source.contains(x))
}
}
% end
% end
% end
% for vi0, Value0 in enumerate(values):
% DynamicValue = values[0] if Value0.startswith('Any') else Value0
% for Value1 in values[vi0:]:
% for method in 'Direct', 'Indirect':
tests.test(
"Dictionary/Up/${method}/[${Key0}:${Value0}]=>[${Key1}:${Value1}]") {
// Check that the cast type-checks
let source = [
${DynamicKey}(42) as ${Key0} : ${DynamicValue}(42) as ${Value0},
${DynamicKey}(17) as ${Key0} : ${DynamicValue}(17) as ${Value0}]
% if method == 'Direct':
let upcasted = source as [${Key1}:${Value1}]
% else:
let upcasted_ = source as Any as? [${Key1}:${Value1}]
guard let upcasted = expectNotNil(upcasted_) else { return }
% end
expectEqual(source.count, upcasted.count)
for (k0, v0) in source {
guard let v1 = expectNotNil(upcasted[k0]) else { continue }
guard let dv0 = expectNotNil(
cast(v0, to: ${DynamicValue}.self)) else { continue }
guard let dv1 = expectNotNil(
cast(v1, to: ${DynamicValue}.self)) else { continue }
expectEqual(dv0, dv1)
}
}
% end
% if Key1 != Key0 or Value1 != Value0:
tests.test(
"Dictionary/Down/[${Key1}:${Value1}]=>[${Key0}:${Value0}]") {
// Check that the cast type-checks
let source = [
${DynamicKey}(42) as ${Key1} : ${DynamicValue}(42) as ${Value1},
${DynamicKey}(17) as ${Key1} : ${DynamicValue}(17) as ${Value1}]
guard let downcasted = expectNotNil(source as? [${Key0}:${Value0}])
else { return }
expectEqual(source.count, downcasted.count)
for (k0, v0) in downcasted {
guard let v1 = expectNotNil(source[k0]) else { continue }
guard let dv0 = expectNotNil(
cast(v0, to: ${DynamicValue}.self)) else { continue }
guard let dv1 = expectNotNil(
cast(v1, to: ${DynamicValue}.self)) else { continue }
expectEqual(dv0, dv1)
}
}
% end
% end
% end
% end
% end
% end
runAllTests()