Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
kostiakoval committed Feb 7, 2016
2 parents 0a17bd2 + 558eacc commit 5e9278b
Show file tree
Hide file tree
Showing 4 changed files with 228 additions and 14 deletions.
4 changes: 4 additions & 0 deletions Mirror.xcodeproj/project.pbxproj
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
B5721AC41B7E28590060F1F7 /* MirrorSimpleTypeTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5721AC31B7E28590060F1F7 /* MirrorSimpleTypeTest.swift */; };
B5A964D81B7CC2180039130D /* MirrorOptionalsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A964D71B7CC2180039130D /* MirrorOptionalsTest.swift */; };
B5F3D7F51B50579100528EF4 /* Mirror.h in Headers */ = {isa = PBXBuildFile; fileRef = B5F3D7F41B50579100528EF4 /* Mirror.h */; settings = {ATTRIBUTES = (Public, ); }; };
B5F3D7FB1B50579100528EF4 /* Mirror.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5F3D7F01B50579100528EF4 /* Mirror.framework */; };
Expand Down Expand Up @@ -57,6 +58,7 @@
38655085F436530DA0A592AD /* Pods_Mirror_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Mirror_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
436B6CAEFB5068A8D66BBFE5 /* Pods_Mirror_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Mirror_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8A2F702DE49FD9A40531D887 /* Pods-MirrorTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MirrorTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-MirrorTests/Pods-MirrorTests.release.xcconfig"; sourceTree = "<group>"; };
B5721AC31B7E28590060F1F7 /* MirrorSimpleTypeTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MirrorSimpleTypeTest.swift; sourceTree = "<group>"; };
B5A964D71B7CC2180039130D /* MirrorOptionalsTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MirrorOptionalsTest.swift; sourceTree = "<group>"; };
B5F3D7F01B50579100528EF4 /* Mirror.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Mirror.framework; sourceTree = BUILT_PRODUCTS_DIR; };
B5F3D7F31B50579100528EF4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -170,6 +172,7 @@
B5F3D7FE1B50579100528EF4 /* MirrorTests */ = {
isa = PBXGroup;
children = (
B5721AC31B7E28590060F1F7 /* MirrorSimpleTypeTest.swift */,
B5F3D8011B50579100528EF4 /* MirrorTests.swift */,
B5A964D71B7CC2180039130D /* MirrorOptionalsTest.swift */,
B5F3D7FF1B50579100528EF4 /* Supporting Files */,
Expand Down Expand Up @@ -423,6 +426,7 @@
files = (
B5A964D81B7CC2180039130D /* MirrorOptionalsTest.swift in Sources */,
B5F3D8021B50579100528EF4 /* MirrorTests.swift in Sources */,
B5721AC41B7E28590060F1F7 /* MirrorSimpleTypeTest.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
74 changes: 60 additions & 14 deletions Mirror/Mirror.swift
Expand Up @@ -48,12 +48,12 @@ public struct Mirror<T> {
/// Instance type short name, just a type name, without Module
public var shortName: String {
let name = "\(instance.dynamicType)"
let shortName = name.convertOptionals()
return shortName.pathExtension
return name.sortNameStyle
}

}

// MARK: - Type detection
extension Mirror {

public var isClass: Bool {
Expand Down Expand Up @@ -91,9 +91,11 @@ extension Mirror {
public var memorySize: Int {
return sizeofValue(instance)
}

//MARK: - Children Inpection

}

//MARK: - Children Inpection
extension Mirror {

/// Properties Names
public var names: [String] {
return map(self) { $0.name }
Expand All @@ -111,15 +113,20 @@ extension Mirror {

/// Short style for type names
public var typesShortName: [String] {
return map(self) { "\($0.type)".convertOptionals().pathExtension }
return map(self) {
let conv = "\($0.type)".sortNameStyle
return conv //.pathExtension
}
}

/// Mirror types for every children property
public var children: [MirrorItem] {
return map(self) { $0 }
}

//MARK: - Quering
}

//MARK: - Quering
extension Mirror {

/// Returns a property value for a property name
public subscript (key: String) -> Any? {
Expand All @@ -133,7 +140,11 @@ extension Mirror {
let res = findFirst(self) { $0.name == key }
return res.flatMap { $0.value as? U }
}

}

// MARK: - Converting
extension Mirror {

/// Convert to a dicitonary with [PropertyName : PropertyValue] notation
public var toDictionary: [String : Any] {

Expand All @@ -158,6 +169,7 @@ extension Mirror {
}
}

// MARK: - CollectionType
extension Mirror : CollectionType, SequenceType {

public func generate() -> IndexingGenerator<[MirrorItem]> {
Expand All @@ -177,7 +189,7 @@ extension Mirror : CollectionType, SequenceType {
}
}


// MARK: - Mirror helpers
extension String {

func contains(x: String) -> Bool {
Expand All @@ -186,12 +198,46 @@ extension String {

func convertOptionals() -> String {
var x = self
while let range = x.rangeOfString("Optional<") {
if let endOfOptional = x.rangeOfString(">", range: range.startIndex..<x.endIndex) {
x.replaceRange(endOfOptional, with: "?")
while let start = x.rangeOfString("Optional<") {
if let end = x.rangeOfString(">", range: start.startIndex..<x.endIndex) {
let subtypeRange = start.endIndex..<end.startIndex
let subType = x[subtypeRange]
x.replaceRange(end, with: "?")
x.replaceRange(subtypeRange, with: subType.sortNameStyle)
}
x.removeRange(start)
}
return x
}

func convertArray() -> String {
var x = self
while let start = x.rangeOfString("Array<") {
if let end = x.rangeOfString(">", range: start.startIndex..<x.endIndex) {
let subtypeRange = start.endIndex..<end.startIndex
let arrayType = x[subtypeRange]
x.replaceRange(end, with: "]")
x.replaceRange(subtypeRange, with: arrayType.sortNameStyle)

}
x.removeRange(range)
x.replaceRange(start, with:"[")
}
return x
}

func removeTypeModuleName() -> String {
var x = self
if let range = self.rangeOfString(".") {
x = self.substringFromIndex(range.endIndex)
}
return x
}

var sortNameStyle: String {
return self
.removeTypeModuleName()
.convertOptionals()
.convertArray()
}

}
109 changes: 109 additions & 0 deletions MirrorTests/MirrorSimpleTypeTest.swift
@@ -0,0 +1,109 @@
//
// MirrorTests.swift
// MirrorTests
//
// Created by Kostiantyn Koval on 10/07/15.
// Copyright (c) 2015 CocoaPods. All rights reserved.
//

import Quick
import Nimble
import Mirror

class MirrorSimpleTypeSpec: QuickSpec {
override func spec() {
let mirrorInt = Mirror(10)
let mirrorStr = Mirror("String")

describe("Mirror") {

//MARK: - Type Info

it("can get its type name") {
expect(mirrorInt.name) == "Swift.Int"
expect(mirrorStr.name) == "Swift.String"
}

it("can get its type short name") {
expect(mirrorInt.shortName) == "Int"
expect(mirrorStr.shortName) == "String"
}

it("can get its properties count") {
expect(mirrorInt.childrenCount) == 0
expect(mirrorStr.childrenCount) == 0
}

it("can get momory size for the type") {
expect(mirrorInt.memorySize) == sizeof(Int)
expect(mirrorStr.memorySize) == sizeof(String)
}

it("can check if it's a class") {
expect(mirrorInt.isClass) == false
expect(mirrorStr.isClass) == false
}

it("can check if it's a struct ") {
expect(mirrorInt.isStruct) == true
expect(mirrorStr.isStruct) == true
}
}

describe("Mirror Children") {
it("can get names") {
expect(mirrorInt.names.isEmpty) == true
expect(mirrorStr.names.isEmpty) == true
}

it("can get values") {
expect(mirrorInt.values.isEmpty) == true
expect(mirrorStr.values.isEmpty) == true
}

it("can get types") {
expect(mirrorInt.types.isEmpty) == true
expect(mirrorStr.types.isEmpty) == true
}

it("can get types names with short style") {
expect(mirrorInt.typesShortName.isEmpty) == true
expect(mirrorStr.typesShortName.isEmpty) == true
}

it("can get children mirrors") {
expect(mirrorInt.children.isEmpty) == true
expect(mirrorStr.children.isEmpty) == true
}
}

describe("Converting") {
it("can be exported to Dictionary") {
expect(mirrorInt.toDictionary.count) == 0
expect(mirrorStr.toDictionary.count) == 0
}

it("can be exported to NSDictioanry") {
expect(mirrorInt.toNSDictionary.count) == 0
expect(mirrorStr.toNSDictionary.count) == 0
}

context("The Collection type") {

it("has a generator") {
var intGenerator = mirrorInt.generate()
var stringGenerator = mirrorStr.generate()

expect(intGenerator.next()).to(beNil())
expect(stringGenerator.next()).to(beNil())
}

it("has count") {
expect(count(mirrorInt)) == 0
expect(count(mirrorStr)) == 0
}
}
}
}
}

55 changes: 55 additions & 0 deletions MirrorTests/MirrorTests.swift
Expand Up @@ -19,6 +19,11 @@ struct Person {
}
}

struct Records {
let name: [String]
let maybeIds: [Int?]
}

class MirrorSpec: QuickSpec {
override func spec() {

Expand Down Expand Up @@ -176,5 +181,55 @@ class MirrorSpec: QuickSpec {
}
}

describe("Subtypes") {
it("Arrays name") {
let ar = [1, 2, 3]
let mirror = Mirror(ar)
expect(mirror.name) == "Swift.Array<Swift.Int>"
}

it("Array shortName") {
let ar = [1, 2, 3]
let mirror = Mirror(ar)
expect(mirror.shortName) == "[Int]"
}

it("handle Optionals name") {
let x: Int? = 1
let mirror = Mirror(x)
expect(mirror.name) == "Swift.Optional<Swift.Int>"
}

it("handle Optionals shortName") {
let x: Int? = 1
let mirror = Mirror(x)
expect(mirror.shortName) == "Int?"
}

}

describe("Mirror and Arrays") {

let records = Records(name: ["One", "Two"], maybeIds: [1, nil])
let mirror = Mirror(records)

it("can get types") {
struct Records {
let name: [String]
let maybeIds: [Int?]
}

let types = mirror.types
let stringTypes = types.map { "\($0)" }
expect(stringTypes) == ["Swift.Array<Swift.String>", "Swift.Array<Swift.Optional<Swift.Int>>"]
}


xit("can get types names with short style") {
let typesName = mirror.typesShortName
expect(typesName) == ["[String]", "[Int?]"]
}

}
}
}

0 comments on commit 5e9278b

Please sign in to comment.