   }
 }
 
-func test_CustomStringInterpolation() {
-  assertEquals("<segment aaa><segment 1><segment bbb>",
-               ("aaa\(1)bbb" as MyString).value)
-
-  print("test_CustomStringInterpolation done")
-}
-test_CustomStringInterpolation()
-// CHECK: test_CustomStringInterpolation done
-
-func test_StdoutUTF8Printing() {
-  print("\u{00B5}")
-// CHECK: {{^}}µ{{$}}
-
-  print("test_StdoutUTF8Printing done")
-}
-test_StdoutUTF8Printing()
-// CHECK: test_StdoutUTF8Printing done
-
-func test_varargs() {
-  print("", 1, 2, 3, 4, "", separator: "|") // CHECK: |1|2|3|4|
-  print(1, 2, 3, separator: "\n", terminator: "===")
-  print(4, 5, 6, separator: "\n")
-  // CHECK-NEXT: 1
-  // CHECK-NEXT: 2
-  // CHECK-NEXT: 3===4
-  // CHECK-NEXT: 5
-  // CHECK-NEXT: 6
-
-  debugPrint("", 1, 2, 3, 4, "", separator: "|")
-   // CHECK-NEXT: ""|1|2|3|4|""
-  debugPrint(1, 2, 3, separator: "\n", terminator: "===")
-  debugPrint(4, 5, 6, separator: "\n")
-  // CHECK-NEXT: 1
-  // CHECK-NEXT: 2
-  // CHECK-NEXT: 3===4
-  // CHECK-NEXT: 5
-  // CHECK-NEXT: 6
-
-  var output = ""
-  print(
-    "", 1, 2, 3, 4, "", separator: "|", toStream: &output)
-  print(output == "|1|2|3|4|\n") // CHECK-NEXT: true
-  output = ""
-  debugPrint(
-    "", 1, 2, 3, 4, "", separator: "|", terminator: "", toStream: &output)
-  print(output == "\"\"|1|2|3|4|\"\"") // CHECK-NEXT: true
-  print("test_varargs done")
-}
-test_varargs()
-// CHECK: test_varargs done
-
-func test_playgroundPrintHook() {
-  
-  var printed: String? = nil
+PrintTests.test("CustomStringInterpolation") {
+  expectEqual("<segment aaa><segment 1><segment bbb>",
+    ("aaa\(1)bbb" as MyString).value)
+}
+
+PrintTests.test("StdoutUTF8") {
+  expectPrinted("µ", "\u{00B5}")
+}
+
+PrintTests.test("Varargs") {
+  var s0 = ""
+  print("", 1, 2, 3, 4, "", separator: "|", toStream: &s0)
+  expectEqual("|1|2|3|4|\n", s0)
+  
+  var s1 = ""
+  print(1, 2, 3, separator: "\n", terminator: "===", toStream: &s1)
+  expectEqual("1\n2\n3===", s1)
+  
+  var s2 = ""
+  print(4, 5, 6, separator: "\n", toStream: &s2)
+  expectEqual("4\n5\n6\n", s2)
+  
+  var s3 = ""
+  print("", 1, 2, 3, 4, "", separator: "|", toStream: &s3)
+  expectEqual("|1|2|3|4|\n", s3)
+}
+
+PrintTests.test("PlaygroundPrintHook") {
+  var printed = ""
   _playgroundPrintHook = { printed = $0 }
   
-  print("", 1, 2, 3, 4, "", separator: "|") // CHECK: |1|2|3|4|
-  print("%\(printed!)%") // CHECK-NEXT: %|1|2|3|4|
-  // CHECK-NEXT: %
-  
-  printed = nil
-  debugPrint("", 1, 2, 3, 4, "", separator: "|")
-  // CHECK-NEXT: ""|1|2|3|4|""
-  print("%\(printed!)%") // CHECK-NEXT: %""|1|2|3|4|""
-  // CHECK-NEXT: %
-  
-  var explicitStream = ""
-  printed = nil
-  print("", 1, 2, 3, 4, "", separator: "!", toStream: &explicitStream)
-  print(printed)               // CHECK-NEXT: nil
-  print("%\(explicitStream)%") // CHECK-NEXT: %!1!2!3!4!
-  // CHECK-NEXT: %
-  
-  explicitStream = ""
-  printed = nil
-  debugPrint(
-    "", 1, 2, 3, 4, "", separator: "!", toStream: &explicitStream)
-  print(printed) // CHECK-NEXT: nil
-  print("%\(explicitStream)%") // CHECK-NEXT: %""!1!2!3!4!""
-  // CHECK-NEXT: %
-  
-  _playgroundPrintHook = nil
-  print("test_playgroundPrintHook done")
-  // CHECK-NEXT: test_playgroundPrintHook done
-}
-test_playgroundPrintHook()
-
-if !failed {
-  print("OK")
-}
-// CHECK: OK
-
+  var s0 = ""
+  print("", 1, 2, 3, 4, "", separator: "|", toStream: &s0)
+  expectEqual("|1|2|3|4|\n", s0)
+  print("%\(s0)%")
+  expectEqual("%|1|2|3|4|\n%\n", printed)
+  
+  printed = ""
+  var s1 = ""
+  print("", 1, 2, 3, 4, "", separator: "!", toStream: &s1)
+  expectEqual("", printed)
+  print("%\(s1)%")
+  expectEqual("%!1!2!3!4!\n%\n", printed)
+}
+
+runAllTests()
}

PrintTests.test("optional strings") {
  expectEqual("nil", String!())
  expectEqual("meow", String!("meow"))
  expectEqual("nil", String?())
  expectEqual("Optional(\"meow\")", String?("meow"))
}

PrintTests.test("custom string convertible structs") {

    ClassPrintable(2), ClassPrintable(3) ] as Array<AnyObject>)
}

PrintTests.test("Dictionary") {
  expectPrinted("[:]", [String: Int]())
  expectDebugPrinted("[:]", [String: Int]())
  
  expectPrinted("[\"aaa\": 1]", [ "aaa": 1 ])
  expectDebugPrinted("[\"aaa\": 1]", [ "aaa": 1 ])
  
  let d0 = [ "aaa": 1, "bbb": 2 ]
  expectPrinted(expectedOneOf: [ "[\"aaa\": 1, \"bbb\": 2]",
    "[\"bbb\": 2, \"aaa\": 1]" ], d0)
  expectDebugPrinted(expectedOneOf: [ "[\"aaa\": 1, \"bbb\": 2]",
    "[\"bbb\": 2, \"aaa\": 1]" ], d0)
  
  let d1 = [ "aaa": "bbb" ]
  expectPrinted("[\"aaa\": \"bbb\"]", d1)
  expectDebugPrinted("[\"aaa\": \"bbb\"]", d1)
}

PrintTests.test("Set") {
  expectPrinted("[]", Set<Int>())
  expectDebugPrinted("Set([])", Set<Int>())
  
  let s0 = Set<Int>([11, 22])
  expectPrinted(expectedOneOf: [ "[11, 22]", "[22, 11]" ], s0)
  expectDebugPrinted(expectedOneOf: [ "Set([11, 22])",
    "Set([22, 11])" ], s0)
  
  let s1 = Set<String>(["Hello", "world"])
  expectPrinted(expectedOneOf: [ "[\"Hello\", \"world\"]",
    "[\"world\", \"Hello\"]" ], s1)
  expectDebugPrinted(expectedOneOf: [ "Set([\"Hello\", \"world\"])",
    "Set([\"world\", \"Hello\"])" ], s1)
}

PrintTests.test("Tuple") {
  expectPrinted("(42, ())", (42, ()))
  expectPrinted("((), 42)", ((), 42))
  expectPrinted("(42, ►3◀︎)", (42, StructPrintable(3)))
  expectPrinted("(42, <10 20 30 40>)",
    (42, LargeStructPrintable(10, 20, 30, 40)))
  expectPrinted("(42, ►3◀︎)", (42, ClassPrintable(3)))
  expectPrinted("([123: 123], (1, 2, \"3\"))",
    ([123: 123], (1, 2, "3")))
  
  let t0 = [ (1, "two", StructPrintable(3), StructDebugPrintable(4),
    WithoutDescription(5)) ]
  expectPrinted("[(1, \"two\", ►3◀︎, ►4◀︎, a.WithoutDescription(x: 5))]",
    t0)
  
  let t1 = [ (1, "two", WithoutDescription(3)),
    (11, "twenty-two", WithoutDescription(33)),
    (111, "two hundred twenty-two", WithoutDescription(333)) ]
  expectPrinted("[(1, \"two\", a.WithoutDescription(x: 3)), (11, \"twenty-two\", a.WithoutDescription(x: 33)), (111, \"two hundred twenty-two\", a.WithoutDescription(x: 333))]", t1)
}

PrintTests.test("ArbitraryStruct") {
  let s0 = [ WithoutDescription(1), WithoutDescription(2), WithoutDescription(3) ]
  expectPrinted(
  "[a.WithoutDescription(x: 1), a.WithoutDescription(x: 2), a.WithoutDescription(x: 3)]",
  s0)
  expectDebugPrinted(
  "[a.WithoutDescription(x: 1), a.WithoutDescription(x: 2), a.WithoutDescription(x: 3)]",
  s0)
  
  expectPrinted("EmptyStructWithoutDescription()",
    EmptyStructWithoutDescription())
  expectDebugPrinted("a.EmptyStructWithoutDescription()",
    EmptyStructWithoutDescription())
  
  expectPrinted(
    "ValuesWithoutDescription<Double, String, Array<Int>>(t: 1.25, u: \"abc\", v: [1, 2, 3])",
    ValuesWithoutDescription(1.25, "abc", [ 1, 2, 3 ]))
  expectDebugPrinted(
    "a.ValuesWithoutDescription<Swift.Double, Swift.String, Swift.Array<Swift.Int>>(t: 1.25, u: \"abc\", v: [1, 2, 3])", ValuesWithoutDescription(1.25, "abc", [ 1, 2, 3 ]))
}

PrintTests.test("Metatype") {
  expectPrinted("Int", Int.self)
  expectDebugPrinted("Swift.Int", Int.self)
}

PrintTests.test("StringInterpolation") {
  expectEqual("1", "\(1)")
  expectEqual("2", "\(1 + 1)")
  expectEqual("aaa1bbb2ccc", "aaa\(1)bbb\(2)ccc")
  
  expectEqual("1.0", "\(1.0)")
  expectEqual("1.5", "\(1.5)")
  expectEqual("1e-12", "\(1.0 / (1000000000000))")
  
  expectEqual("inf", "\(1 / 0.0)")
  expectEqual("-inf", "\(-1 / 0.0)")
  expectEqual("nan", "\(0 / 0.0)")
  
  expectEqual("<[►1◀︎, ►2◀︎, ►3◀︎]>", "<\([ StructPrintable(1), StructPrintable(2), StructPrintable(3) ])>")
  expectEqual("WithoutDescription(x: 1)", "\(WithoutDescription(1))")
}

struct MyString : StringLiteralConvertible, StringInterpolationConvertible {
  init(str: String) {
