Compare commits
160 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e7adba0cb9 | |||
| 5a288f4197 | |||
| 56bfdfc953 | |||
| 34efc031a4 | |||
| 3541842cd3 | |||
| d75fe1429b | |||
| f8d5a75dd5 | |||
| 596a7d2c1b | |||
| f2a320bc6b | |||
| f36353d61f | |||
| fb30ee0cc3 | |||
| 4234d43565 | |||
| 77d0b4937a | |||
| 4c89d79979 | |||
| 397e3e4c20 | |||
| a4abc2ee8b | |||
| 2e54a9935b | |||
| ea47632047 | |||
| 1d9696939a | |||
| 1a26252cf7 | |||
| 0d73c529f2 | |||
| 42030fb42a | |||
| e689725b4d | |||
| b896bb0751 | |||
| 37bfcd67b2 | |||
| cb7638e658 | |||
| 95e5cc9c11 | |||
| 917cb33775 | |||
| 0b061bb25d | |||
| 1d439a86ed | |||
| be3d9f1c69 | |||
| f89f30b9d1 | |||
| 9821943fff | |||
| d609a252f8 | |||
| 642d7e34f4 | |||
| 9faf5ab0ea | |||
| f1a207a3e6 | |||
| aeac204817 | |||
| 32ef58d871 | |||
| 6ee0ceaa48 | |||
| 0b6c95022e | |||
| b733108558 | |||
| 14cb718fe2 | |||
| 77dbbf1c1f | |||
| 4be64d3c09 | |||
| 2699924867 | |||
| 87b46f36e1 | |||
| 28cd25d536 | |||
| 122814a5cd | |||
| b49641a892 | |||
| f8630257e6 | |||
| 46d4c52934 | |||
| fb66d1e9d8 | |||
| 638d4ae0d1 | |||
| f3d18a63fa | |||
| d01a024ae7 | |||
| a9a37b7978 | |||
| d87cac83e5 | |||
| 754d4096da | |||
| c5d09d3bc0 | |||
| 5877a0a683 | |||
| 5b6c8e3541 | |||
| 502a9e128e | |||
| be22dfd473 | |||
| a027b5c88b | |||
| 5f71a748f5 | |||
| 220b435d2a | |||
| 1120534fde | |||
| 3dfa4db66a | |||
| 3fe91a8722 | |||
| efb886e6c9 | |||
| a0b52c1d28 | |||
| ccb19e2f1d | |||
| 7d2362fe63 | |||
| 117efdb7bd | |||
| d84ddf7f40 | |||
| 73ee947220 | |||
| 9715568f02 | |||
| 751bbe1bcc | |||
| af87ceac65 | |||
| 99f26c7f93 | |||
| 8e43c679de | |||
| b18549782d | |||
| 5b4de32ee2 | |||
| 64924a208c | |||
| 310c182dc3 | |||
| c7ac65504d | |||
| ce50489b8f | |||
| b6d563a3cc | |||
| bb3ee42176 | |||
| b0251e74d3 | |||
| c8d61b939b | |||
| b832b9925c | |||
| 21b9930d36 | |||
| f81ab4e6a0 | |||
| f53a24821a | |||
| a742de8c3d | |||
| 855e6f6a0f | |||
| 6cd117b224 | |||
| dd71f6e196 | |||
| a63943c0ae | |||
| 3d78836dcd | |||
| be180eeaf4 | |||
| 8a2127d8f4 | |||
| 616815b08c | |||
| 90c35cb532 | |||
| b892a31bd9 | |||
| 699727683d | |||
| 8efd15b99a | |||
| a043a863a7 | |||
| ccdb7bf482 | |||
| c5a5e91d2f | |||
| b53a974021 | |||
| 066b38d0ec | |||
| 8b9d033d7d | |||
| befb924574 | |||
| e9fa5e8191 | |||
| fa8cb4d120 | |||
| d7daeb0518 | |||
| 9b6c798a17 | |||
| 959f4f0eb1 | |||
| 040aadd65f | |||
| b6a99e3ffe | |||
| 20d4d7e7c4 | |||
| a8a69e4570 | |||
| cea6cb0952 | |||
| fae6eb2617 | |||
| 0e3030af48 | |||
| 9a255de350 | |||
| ca1fc87240 | |||
| dff7877e06 | |||
| 32ec1a11ce | |||
| 4d8f31303a | |||
| b4da0afe8b | |||
| 34e3aa1c95 | |||
| 0ec1461200 | |||
| 3706b45822 | |||
| 2438623b7c | |||
| af69193370 | |||
| 20c169a7b8 | |||
| 87efd44e09 | |||
| e7bba55479 | |||
| 4dcdf588ee | |||
| 4065061d25 | |||
| 60ffb98742 | |||
| d70db906df | |||
| 30bb351de2 | |||
| 0022833380 | |||
| 1219d6dd8a | |||
| c5e6b63a9c | |||
| a2d0ef2c1b | |||
| 61729a772b | |||
| 5e51f91e07 | |||
| 5acd33d10a | |||
| 1a4623ceff | |||
| 8016abd95b | |||
| e58469f8e4 | |||
| 100e077a0d | |||
| 72ccef23af | |||
| 1a9ac85931 |
+4
-2
@@ -26,5 +26,7 @@ DerivedData
|
||||
*.xctimeline
|
||||
|
||||
# Carthage
|
||||
Carthage/Checkouts
|
||||
Carthage/**/OrderedDictionary*
|
||||
Carthage
|
||||
|
||||
# SPM
|
||||
.build
|
||||
|
||||
+44
-8
@@ -1,13 +1,49 @@
|
||||
# Git
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
# OS
|
||||
os: osx
|
||||
language: objective-c
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
# Xcode Project
|
||||
xcode_project: OrderedDictionary.xcodeproj
|
||||
xcode_scheme: OrderedDictionary-iOS
|
||||
osx_image: xcode7
|
||||
xcode_sdk: iphonesimulator
|
||||
|
||||
# Build Matrix
|
||||
matrix:
|
||||
include:
|
||||
# Swift 4.0 / macOS
|
||||
- osx_image: xcode9.2
|
||||
xcode_scheme: OrderedDictionary-Mac
|
||||
env:
|
||||
- XCODE_SDK=macosx
|
||||
- XCODE_ACTION="build test"
|
||||
- XCODE_DESTINATION="arch=x86_64"
|
||||
- XCODE_PLAYGROUND_TARGET="x86_64-apple-macosx10.10"
|
||||
# Swift 4.0 / iOS
|
||||
- osx_image: xcode9.2
|
||||
xcode_scheme: OrderedDictionary-iOS
|
||||
env:
|
||||
- XCODE_SDK=iphonesimulator
|
||||
- XCODE_ACTION="build-for-testing test-without-building"
|
||||
- XCODE_DESTINATION="platform=iOS Simulator,name=iPhone 6s,OS=10.1"
|
||||
# Swift 4.1 / macOS
|
||||
- osx_image: xcode9.3beta
|
||||
xcode_scheme: OrderedDictionary-Mac
|
||||
env:
|
||||
- XCODE_SDK=macosx
|
||||
- XCODE_ACTION="build test"
|
||||
- XCODE_DESTINATION="arch=x86_64"
|
||||
- XCODE_PLAYGROUND_TARGET="x86_64-apple-macosx10.10"
|
||||
# Swift 4.1 / iOS
|
||||
- osx_image: xcode9.3beta
|
||||
xcode_scheme: OrderedDictionary-iOS
|
||||
env:
|
||||
- XCODE_SDK=iphonesimulator
|
||||
- XCODE_ACTION="build-for-testing test-without-building"
|
||||
- XCODE_DESTINATION="platform=iOS Simulator,name=iPhone 6s,OS=10.1"
|
||||
|
||||
# Build Script
|
||||
script:
|
||||
- xcodebuild clean build test -project OrderedDictionary.xcodeproj -scheme OrderedDictionary-iOS -destination "platform=iOS Simulator,name=iPhone 6,OS=9.0"
|
||||
- Scripts/build.sh
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
github "Quick/Nimble" "e84623d953d811f74a2afcda4fa0c8121e7dad7d"
|
||||
@@ -1 +0,0 @@
|
||||
github "Quick/Nimble" "e84623d953d811f74a2afcda4fa0c8121e7dad7d"
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.apple.xcode.dsym.net.jeffhui.Nimble</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>dSYM</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
Binary file not shown.
-1
@@ -1 +0,0 @@
|
||||
Versions/Current/Headers
|
||||
-1
@@ -1 +0,0 @@
|
||||
Versions/Current/Modules
|
||||
-1
@@ -1 +0,0 @@
|
||||
Versions/Current/Nimble
|
||||
-1
@@ -1 +0,0 @@
|
||||
Versions/Current/Resources
|
||||
-129
@@ -1,129 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class NMBExpectation;
|
||||
@class NMBObjCBeCloseToMatcher;
|
||||
@class NMBObjCRaiseExceptionMatcher;
|
||||
@protocol NMBMatcher;
|
||||
|
||||
|
||||
#define NIMBLE_EXPORT FOUNDATION_EXPORT
|
||||
|
||||
#ifdef NIMBLE_DISABLE_SHORT_SYNTAX
|
||||
#define NIMBLE_SHORT(PROTO, ORIGINAL)
|
||||
#else
|
||||
#define NIMBLE_SHORT(PROTO, ORIGINAL) FOUNDATION_STATIC_INLINE PROTO { return (ORIGINAL); }
|
||||
#endif
|
||||
|
||||
NIMBLE_EXPORT NMBExpectation *NMB_expect(id(^actualBlock)(), NSString *file, NSUInteger line);
|
||||
NIMBLE_EXPORT NMBExpectation *NMB_expectAction(void(^actualBlock)(), NSString *file, NSUInteger line);
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_equal(id expectedValue);
|
||||
NIMBLE_SHORT(id<NMBMatcher> equal(id expectedValue),
|
||||
NMB_equal(expectedValue));
|
||||
|
||||
NIMBLE_EXPORT NMBObjCBeCloseToMatcher *NMB_beCloseTo(NSNumber *expectedValue);
|
||||
NIMBLE_SHORT(NMBObjCBeCloseToMatcher *beCloseTo(id expectedValue),
|
||||
NMB_beCloseTo(expectedValue));
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beAnInstanceOf(Class expectedClass);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beAnInstanceOf(Class expectedClass),
|
||||
NMB_beAnInstanceOf(expectedClass));
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beAKindOf(Class expectedClass);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beAKindOf(Class expectedClass),
|
||||
NMB_beAKindOf(expectedClass));
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beginWith(id itemElementOrSubstring);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beginWith(id itemElementOrSubstring),
|
||||
NMB_beginWith(itemElementOrSubstring));
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beGreaterThan(NSNumber *expectedValue);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beGreaterThan(NSNumber *expectedValue),
|
||||
NMB_beGreaterThan(expectedValue));
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beGreaterThanOrEqualTo(NSNumber *expectedValue);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beGreaterThanOrEqualTo(NSNumber *expectedValue),
|
||||
NMB_beGreaterThanOrEqualTo(expectedValue));
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beIdenticalTo(id expectedInstance);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beIdenticalTo(id expectedInstance),
|
||||
NMB_beIdenticalTo(expectedInstance));
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beLessThan(NSNumber *expectedValue);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beLessThan(NSNumber *expectedValue),
|
||||
NMB_beLessThan(expectedValue));
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beLessThanOrEqualTo(NSNumber *expectedValue);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beLessThanOrEqualTo(NSNumber *expectedValue),
|
||||
NMB_beLessThanOrEqualTo(expectedValue));
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beTruthy(void);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beTruthy(void),
|
||||
NMB_beTruthy());
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beFalsy(void);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beFalsy(void),
|
||||
NMB_beFalsy());
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beTrue(void);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beTrue(void),
|
||||
NMB_beTrue());
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beFalse(void);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beFalse(void),
|
||||
NMB_beFalse());
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beNil(void);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beNil(void),
|
||||
NMB_beNil());
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beEmpty(void);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beEmpty(void),
|
||||
NMB_beEmpty());
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_containWithNilTermination(id itemOrSubstring, ...) NS_REQUIRES_NIL_TERMINATION;
|
||||
#define NMB_contain(...) NMB_containWithNilTermination(__VA_ARGS__, nil)
|
||||
#ifndef NIMBLE_DISABLE_SHORT_SYNTAX
|
||||
#define contain(...) NMB_contain(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_endWith(id itemElementOrSubstring);
|
||||
NIMBLE_SHORT(id<NMBMatcher> endWith(id itemElementOrSubstring),
|
||||
NMB_endWith(itemElementOrSubstring));
|
||||
|
||||
NIMBLE_EXPORT NMBObjCRaiseExceptionMatcher *NMB_raiseException(void);
|
||||
NIMBLE_SHORT(NMBObjCRaiseExceptionMatcher *raiseException(void),
|
||||
NMB_raiseException());
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_match(id expectedValue);
|
||||
NIMBLE_SHORT(id<NMBMatcher> match(id expectedValue),
|
||||
NMB_match(expectedValue));
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_allPass(id matcher);
|
||||
NIMBLE_SHORT(id<NMBMatcher> allPass(id matcher),
|
||||
NMB_allPass(matcher));
|
||||
|
||||
// In order to preserve breakpoint behavior despite using macros to fill in __FILE__ and __LINE__,
|
||||
// define a builder that populates __FILE__ and __LINE__, and returns a block that takes timeout
|
||||
// and action arguments. See https://github.com/Quick/Quick/pull/185 for details.
|
||||
typedef void (^NMBWaitUntilTimeoutBlock)(NSTimeInterval timeout, void (^action)(void (^)(void)));
|
||||
typedef void (^NMBWaitUntilBlock)(void (^action)(void (^)(void)));
|
||||
|
||||
NIMBLE_EXPORT NMBWaitUntilTimeoutBlock NMB_waitUntilTimeoutBuilder(NSString *file, NSUInteger line);
|
||||
NIMBLE_EXPORT NMBWaitUntilBlock NMB_waitUntilBuilder(NSString *file, NSUInteger line);
|
||||
|
||||
NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger line);
|
||||
|
||||
#define NMB_waitUntilTimeout NMB_waitUntilTimeoutBuilder(@(__FILE__), __LINE__)
|
||||
#define NMB_waitUntil NMB_waitUntilBuilder(@(__FILE__), __LINE__)
|
||||
|
||||
#ifndef NIMBLE_DISABLE_SHORT_SYNTAX
|
||||
#define expect(...) NMB_expect(^id{ return (__VA_ARGS__); }, @(__FILE__), __LINE__)
|
||||
#define expectAction(BLOCK) NMB_expectAction((BLOCK), @(__FILE__), __LINE__)
|
||||
#define failWithMessage(msg) NMB_failWithMessage(msg, @(__FILE__), __LINE__)
|
||||
#define fail() failWithMessage(@"fail() always fails")
|
||||
|
||||
|
||||
#define waitUntilTimeout NMB_waitUntilTimeout
|
||||
#define waitUntil NMB_waitUntil
|
||||
#endif
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface NMBExceptionCapture : NSObject
|
||||
|
||||
- (id)initWithHandler:(void(^)(NSException *))handler finally:(void(^)())finally;
|
||||
- (void)tryBlock:(void(^)())unsafeBlock;
|
||||
|
||||
@end
|
||||
-364
@@ -1,364 +0,0 @@
|
||||
// Generated by Apple Swift version 2.0 (swiftlang-700.0.57.3 clang-700.0.72)
|
||||
#pragma clang diagnostic push
|
||||
|
||||
#if defined(__has_include) && __has_include(<swift/objc-prologue.h>)
|
||||
# include <swift/objc-prologue.h>
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic ignored "-Wauto-import"
|
||||
#include <objc/NSObject.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#if defined(__has_include) && __has_include(<uchar.h>)
|
||||
# include <uchar.h>
|
||||
#elif !defined(__cplusplus) || __cplusplus < 201103L
|
||||
typedef uint_least16_t char16_t;
|
||||
typedef uint_least32_t char32_t;
|
||||
#endif
|
||||
|
||||
typedef struct _NSZone NSZone;
|
||||
|
||||
#if !defined(SWIFT_PASTE)
|
||||
# define SWIFT_PASTE_HELPER(x, y) x##y
|
||||
# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y)
|
||||
#endif
|
||||
#if !defined(SWIFT_METATYPE)
|
||||
# define SWIFT_METATYPE(X) Class
|
||||
#endif
|
||||
|
||||
#if defined(__has_attribute) && __has_attribute(objc_runtime_name)
|
||||
# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X)))
|
||||
#else
|
||||
# define SWIFT_RUNTIME_NAME(X)
|
||||
#endif
|
||||
#if defined(__has_attribute) && __has_attribute(swift_name)
|
||||
# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X)))
|
||||
#else
|
||||
# define SWIFT_COMPILE_NAME(X)
|
||||
#endif
|
||||
#if !defined(SWIFT_CLASS_EXTRA)
|
||||
# define SWIFT_CLASS_EXTRA
|
||||
#endif
|
||||
#if !defined(SWIFT_PROTOCOL_EXTRA)
|
||||
# define SWIFT_PROTOCOL_EXTRA
|
||||
#endif
|
||||
#if !defined(SWIFT_ENUM_EXTRA)
|
||||
# define SWIFT_ENUM_EXTRA
|
||||
#endif
|
||||
#if !defined(SWIFT_CLASS)
|
||||
# if defined(__has_attribute) && __has_attribute(objc_subclassing_restricted)
|
||||
# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA
|
||||
# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
|
||||
# else
|
||||
# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
|
||||
# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(SWIFT_PROTOCOL)
|
||||
# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
|
||||
# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
|
||||
#endif
|
||||
|
||||
#if !defined(SWIFT_EXTENSION)
|
||||
# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__)
|
||||
#endif
|
||||
|
||||
#if !defined(OBJC_DESIGNATED_INITIALIZER)
|
||||
# if defined(__has_attribute) && __has_attribute(objc_designated_initializer)
|
||||
# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
|
||||
# else
|
||||
# define OBJC_DESIGNATED_INITIALIZER
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_ENUM)
|
||||
# define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum SWIFT_ENUM_EXTRA _name : _type
|
||||
#endif
|
||||
typedef float swift_float2 __attribute__((__ext_vector_type__(2)));
|
||||
typedef float swift_float3 __attribute__((__ext_vector_type__(3)));
|
||||
typedef float swift_float4 __attribute__((__ext_vector_type__(4)));
|
||||
typedef double swift_double2 __attribute__((__ext_vector_type__(2)));
|
||||
typedef double swift_double3 __attribute__((__ext_vector_type__(3)));
|
||||
typedef double swift_double4 __attribute__((__ext_vector_type__(4)));
|
||||
typedef int swift_int2 __attribute__((__ext_vector_type__(2)));
|
||||
typedef int swift_int3 __attribute__((__ext_vector_type__(3)));
|
||||
typedef int swift_int4 __attribute__((__ext_vector_type__(4)));
|
||||
#if defined(__has_feature) && __has_feature(modules)
|
||||
@import ObjectiveC;
|
||||
@import Foundation;
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch"
|
||||
#pragma clang diagnostic ignored "-Wduplicate-method-arg"
|
||||
|
||||
|
||||
/// Encapsulates the failure message that matchers can report to the end user.
|
||||
///
|
||||
/// This is shared state between Nimble and matchers that mutate this value.
|
||||
SWIFT_CLASS("_TtC6Nimble14FailureMessage")
|
||||
@interface FailureMessage : NSObject
|
||||
@property (nonatomic, copy) NSString * __nonnull expected;
|
||||
@property (nonatomic, copy) NSString * __nullable actualValue;
|
||||
@property (nonatomic, copy) NSString * __nonnull to;
|
||||
@property (nonatomic, copy) NSString * __nonnull postfixMessage;
|
||||
@property (nonatomic, copy) NSString * __nonnull postfixActual;
|
||||
@property (nonatomic, copy) NSString * __nullable userDescription;
|
||||
@property (nonatomic, copy) NSString * __nonnull stringValue;
|
||||
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
|
||||
- (nonnull instancetype)initWithStringValue:(NSString * __nonnull)stringValue OBJC_DESIGNATED_INITIALIZER;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/// Protocol for types that support only beEmpty()
|
||||
SWIFT_PROTOCOL("_TtP6Nimble13NMBCollection_")
|
||||
@protocol NMBCollection
|
||||
@property (nonatomic, readonly) NSInteger count;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/// Protocol for types to support beLessThan(), beLessThanOrEqualTo(), beGreaterThan(), beGreaterThanOrEqualTo(), and equal() matchers.
|
||||
///
|
||||
/// Types that conform to Swift's Comparable protocol will work implicitly too
|
||||
SWIFT_PROTOCOL("_TtP6Nimble13NMBComparable_")
|
||||
@protocol NMBComparable
|
||||
- (NSComparisonResult)NMB_compare:(id <NMBComparable> __null_unspecified)otherObject;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/// Protocol for types that support contain() matcher.
|
||||
SWIFT_PROTOCOL("_TtP6Nimble12NMBContainer_")
|
||||
@protocol NMBContainer
|
||||
- (BOOL)containsObject:(id __null_unspecified)object;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/// Protocol for types to support beCloseTo() matcher
|
||||
SWIFT_PROTOCOL("_TtP6Nimble20NMBDoubleConvertible_")
|
||||
@protocol NMBDoubleConvertible
|
||||
@property (nonatomic, readonly) double doubleValue;
|
||||
@end
|
||||
|
||||
@protocol NMBMatcher;
|
||||
|
||||
SWIFT_CLASS("_TtC6Nimble14NMBExpectation")
|
||||
@interface NMBExpectation : NSObject
|
||||
- (nonnull instancetype)initWithActualBlock:(NSObject * __null_unspecified (^ __nonnull)(void))actualBlock negative:(BOOL)negative file:(NSString * __nonnull)file line:(NSUInteger)line OBJC_DESIGNATED_INITIALIZER;
|
||||
@property (nonatomic, readonly, copy) NMBExpectation * __nonnull (^ __nonnull withTimeout)(NSTimeInterval);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull to)(id <NMBMatcher> __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull toWithDescription)(id <NMBMatcher> __nonnull, NSString * __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull toNot)(id <NMBMatcher> __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull toNotWithDescription)(id <NMBMatcher> __nonnull, NSString * __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull notTo)(id <NMBMatcher> __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull notToWithDescription)(id <NMBMatcher> __nonnull, NSString * __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull toEventually)(id <NMBMatcher> __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull toEventuallyWithDescription)(id <NMBMatcher> __nonnull, NSString * __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull toEventuallyNot)(id <NMBMatcher> __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull toEventuallyNotWithDescription)(id <NMBMatcher> __nonnull, NSString * __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull toNotEventually)(id <NMBMatcher> __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull toNotEventuallyWithDescription)(id <NMBMatcher> __nonnull, NSString * __nonnull);
|
||||
+ (void)failWithMessage:(NSString * __nonnull)message file:(NSString * __nonnull)file line:(NSUInteger)line;
|
||||
@end
|
||||
|
||||
@class SourceLocation;
|
||||
|
||||
|
||||
/// Objective-C interface to the Swift variant of Matcher.
|
||||
SWIFT_PROTOCOL("_TtP6Nimble10NMBMatcher_")
|
||||
@protocol NMBMatcher
|
||||
- (BOOL)matches:(NSObject * __null_unspecified (^ __nonnull)(void))actualBlock failureMessage:(FailureMessage * __nonnull)failureMessage location:(SourceLocation * __nonnull)location;
|
||||
- (BOOL)doesNotMatch:(NSObject * __null_unspecified (^ __nonnull)(void))actualBlock failureMessage:(FailureMessage * __nonnull)failureMessage location:(SourceLocation * __nonnull)location;
|
||||
@end
|
||||
|
||||
|
||||
SWIFT_CLASS("_TtC6Nimble23NMBObjCBeCloseToMatcher")
|
||||
@interface NMBObjCBeCloseToMatcher : NSObject <NMBMatcher>
|
||||
- (BOOL)matches:(NSObject * __null_unspecified (^ __nonnull)(void))actualExpression failureMessage:(FailureMessage * __nonnull)failureMessage location:(SourceLocation * __nonnull)location;
|
||||
- (BOOL)doesNotMatch:(NSObject * __null_unspecified (^ __nonnull)(void))actualExpression failureMessage:(FailureMessage * __nonnull)failureMessage location:(SourceLocation * __nonnull)location;
|
||||
@property (nonatomic, readonly, copy) NMBObjCBeCloseToMatcher * __nonnull (^ __nonnull within)(double);
|
||||
@end
|
||||
|
||||
|
||||
SWIFT_CLASS("_TtC6Nimble14NMBObjCMatcher")
|
||||
@interface NMBObjCMatcher : NSObject <NMBMatcher>
|
||||
- (BOOL)matches:(NSObject * __null_unspecified (^ __nonnull)(void))actualBlock failureMessage:(FailureMessage * __nonnull)failureMessage location:(SourceLocation * __nonnull)location;
|
||||
- (BOOL)doesNotMatch:(NSObject * __null_unspecified (^ __nonnull)(void))actualBlock failureMessage:(FailureMessage * __nonnull)failureMessage location:(SourceLocation * __nonnull)location;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)beEmptyMatcher;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)beIdenticalToMatcher:(NSObject * __nullable)expected;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)beginWithMatcher:(id __nonnull)expected;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)beGreaterThanOrEqualToMatcher:(id <NMBComparable> __nullable)expected;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)containMatcher:(NSArray<NSObject *> * __nonnull)expected;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)beGreaterThanMatcher:(id <NMBComparable> __nullable)expected;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)beLessThanMatcher:(id <NMBComparable> __nullable)expected;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (id <NMBMatcher> __nonnull)equalMatcher:(NSObject * __nonnull)expected;
|
||||
@end
|
||||
|
||||
@class NSString;
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (id <NMBMatcher> __nonnull)matchMatcher:(NSString * __nonnull)expected;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (id <NMBMatcher> __nonnull)beAKindOfMatcher:(Class __nonnull)expected;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)allPassMatcher:(NMBObjCMatcher * __nonnull)matcher;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (id <NMBMatcher> __nonnull)beAnInstanceOfMatcher:(Class __nonnull)expected;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)beLessThanOrEqualToMatcher:(id <NMBComparable> __nullable)expected;
|
||||
@end
|
||||
|
||||
@class NSNumber;
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCBeCloseToMatcher * __nonnull)beCloseToMatcher:(NSNumber * __nonnull)expected within:(double)within;
|
||||
@end
|
||||
|
||||
@class NMBObjCRaiseExceptionMatcher;
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCRaiseExceptionMatcher * __nonnull)raiseExceptionMatcher;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)endWithMatcher:(id __nonnull)expected;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)beNilMatcher;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)beTruthyMatcher;
|
||||
+ (NMBObjCMatcher * __nonnull)beFalsyMatcher;
|
||||
+ (NMBObjCMatcher * __nonnull)beTrueMatcher;
|
||||
+ (NMBObjCMatcher * __nonnull)beFalseMatcher;
|
||||
@end
|
||||
|
||||
@class NSDictionary;
|
||||
@class NSException;
|
||||
|
||||
SWIFT_CLASS("_TtC6Nimble28NMBObjCRaiseExceptionMatcher")
|
||||
@interface NMBObjCRaiseExceptionMatcher : NSObject <NMBMatcher>
|
||||
- (BOOL)matches:(NSObject * __null_unspecified (^ __nonnull)(void))actualBlock failureMessage:(FailureMessage * __nonnull)failureMessage location:(SourceLocation * __nonnull)location;
|
||||
- (BOOL)doesNotMatch:(NSObject * __null_unspecified (^ __nonnull)(void))actualBlock failureMessage:(FailureMessage * __nonnull)failureMessage location:(SourceLocation * __nonnull)location;
|
||||
@property (nonatomic, readonly, copy) NMBObjCRaiseExceptionMatcher * __nonnull (^ __nonnull named)(NSString * __nonnull);
|
||||
@property (nonatomic, readonly, copy) NMBObjCRaiseExceptionMatcher * __nonnull (^ __nonnull reason)(NSString * __nullable);
|
||||
@property (nonatomic, readonly, copy) NMBObjCRaiseExceptionMatcher * __nonnull (^ __nonnull userInfo)(NSDictionary * __nullable);
|
||||
@property (nonatomic, readonly, copy) NMBObjCRaiseExceptionMatcher * __nonnull (^ __nonnull satisfyingBlock)(void (^ __nullable)(NSException * __nonnull));
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/// Protocol for types that support beginWith(), endWith(), beEmpty() matchers
|
||||
SWIFT_PROTOCOL("_TtP6Nimble20NMBOrderedCollection_")
|
||||
@protocol NMBOrderedCollection <NMBCollection>
|
||||
- (NSInteger)indexOfObject:(id __null_unspecified)object;
|
||||
@end
|
||||
|
||||
|
||||
@interface NSArray (SWIFT_EXTENSION(Nimble)) <NMBContainer>
|
||||
@end
|
||||
|
||||
|
||||
@interface NSArray (SWIFT_EXTENSION(Nimble)) <NMBOrderedCollection, NMBCollection>
|
||||
@end
|
||||
|
||||
|
||||
@interface NSArray (SWIFT_EXTENSION(Nimble))
|
||||
@end
|
||||
|
||||
|
||||
@interface NSDictionary (SWIFT_EXTENSION(Nimble)) <NMBCollection>
|
||||
@end
|
||||
|
||||
|
||||
@interface NSHashTable (SWIFT_EXTENSION(Nimble)) <NMBContainer>
|
||||
@end
|
||||
|
||||
|
||||
@interface NSHashTable (SWIFT_EXTENSION(Nimble)) <NMBCollection>
|
||||
@end
|
||||
|
||||
|
||||
@interface NSNumber (SWIFT_EXTENSION(Nimble)) <NMBDoubleConvertible>
|
||||
@end
|
||||
|
||||
|
||||
@interface NSNumber (SWIFT_EXTENSION(Nimble)) <NMBComparable>
|
||||
- (NSComparisonResult)NMB_compare:(id <NMBComparable> __null_unspecified)otherObject;
|
||||
@end
|
||||
|
||||
|
||||
@interface NSSet (SWIFT_EXTENSION(Nimble)) <NMBCollection>
|
||||
@end
|
||||
|
||||
|
||||
@interface NSSet (SWIFT_EXTENSION(Nimble)) <NMBContainer>
|
||||
@end
|
||||
|
||||
|
||||
@interface NSString (SWIFT_EXTENSION(Nimble)) <NMBComparable>
|
||||
- (NSComparisonResult)NMB_compare:(id <NMBComparable> __null_unspecified)otherObject;
|
||||
@end
|
||||
|
||||
|
||||
SWIFT_CLASS("_TtC6Nimble14SourceLocation")
|
||||
@interface SourceLocation : NSObject
|
||||
@property (nonatomic, readonly, copy) NSString * __nonnull file;
|
||||
@property (nonatomic, readonly) NSUInteger line;
|
||||
@property (nonatomic, readonly, copy) NSString * __nonnull description;
|
||||
@end
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Nimble/NMBExceptionCapture.h>
|
||||
#import <Nimble/DSL.h>
|
||||
|
||||
FOUNDATION_EXPORT double NimbleVersionNumber;
|
||||
FOUNDATION_EXPORT const unsigned char NimbleVersionString[];
|
||||
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
-10
@@ -1,10 +0,0 @@
|
||||
framework module Nimble {
|
||||
umbrella header "Nimble.h"
|
||||
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
||||
|
||||
module Nimble.Swift {
|
||||
header "Nimble-Swift.h"
|
||||
}
|
||||
BIN
Binary file not shown.
-51
@@ -1,51 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string>14F27</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>Nimble</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>net.jeffhui.Nimble</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>Nimble</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTPlatformBuild</key>
|
||||
<string>7A192o</string>
|
||||
<key>DTPlatformVersion</key>
|
||||
<string>GM</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>15A244e</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>macosx10.11</string>
|
||||
<key>DTXcode</key>
|
||||
<string>0700</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>7A192o</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2014 Jeff Hui. All rights reserved.</string>
|
||||
<key>UIDeviceFamily</key>
|
||||
<array>
|
||||
<integer>1</integer>
|
||||
<integer>2</integer>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
-1
@@ -1 +0,0 @@
|
||||
A
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.apple.xcode.dsym.net.jeffhui.Nimble</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>dSYM</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
Binary file not shown.
-129
@@ -1,129 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class NMBExpectation;
|
||||
@class NMBObjCBeCloseToMatcher;
|
||||
@class NMBObjCRaiseExceptionMatcher;
|
||||
@protocol NMBMatcher;
|
||||
|
||||
|
||||
#define NIMBLE_EXPORT FOUNDATION_EXPORT
|
||||
|
||||
#ifdef NIMBLE_DISABLE_SHORT_SYNTAX
|
||||
#define NIMBLE_SHORT(PROTO, ORIGINAL)
|
||||
#else
|
||||
#define NIMBLE_SHORT(PROTO, ORIGINAL) FOUNDATION_STATIC_INLINE PROTO { return (ORIGINAL); }
|
||||
#endif
|
||||
|
||||
NIMBLE_EXPORT NMBExpectation *NMB_expect(id(^actualBlock)(), NSString *file, NSUInteger line);
|
||||
NIMBLE_EXPORT NMBExpectation *NMB_expectAction(void(^actualBlock)(), NSString *file, NSUInteger line);
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_equal(id expectedValue);
|
||||
NIMBLE_SHORT(id<NMBMatcher> equal(id expectedValue),
|
||||
NMB_equal(expectedValue));
|
||||
|
||||
NIMBLE_EXPORT NMBObjCBeCloseToMatcher *NMB_beCloseTo(NSNumber *expectedValue);
|
||||
NIMBLE_SHORT(NMBObjCBeCloseToMatcher *beCloseTo(id expectedValue),
|
||||
NMB_beCloseTo(expectedValue));
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beAnInstanceOf(Class expectedClass);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beAnInstanceOf(Class expectedClass),
|
||||
NMB_beAnInstanceOf(expectedClass));
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beAKindOf(Class expectedClass);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beAKindOf(Class expectedClass),
|
||||
NMB_beAKindOf(expectedClass));
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beginWith(id itemElementOrSubstring);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beginWith(id itemElementOrSubstring),
|
||||
NMB_beginWith(itemElementOrSubstring));
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beGreaterThan(NSNumber *expectedValue);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beGreaterThan(NSNumber *expectedValue),
|
||||
NMB_beGreaterThan(expectedValue));
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beGreaterThanOrEqualTo(NSNumber *expectedValue);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beGreaterThanOrEqualTo(NSNumber *expectedValue),
|
||||
NMB_beGreaterThanOrEqualTo(expectedValue));
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beIdenticalTo(id expectedInstance);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beIdenticalTo(id expectedInstance),
|
||||
NMB_beIdenticalTo(expectedInstance));
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beLessThan(NSNumber *expectedValue);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beLessThan(NSNumber *expectedValue),
|
||||
NMB_beLessThan(expectedValue));
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beLessThanOrEqualTo(NSNumber *expectedValue);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beLessThanOrEqualTo(NSNumber *expectedValue),
|
||||
NMB_beLessThanOrEqualTo(expectedValue));
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beTruthy(void);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beTruthy(void),
|
||||
NMB_beTruthy());
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beFalsy(void);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beFalsy(void),
|
||||
NMB_beFalsy());
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beTrue(void);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beTrue(void),
|
||||
NMB_beTrue());
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beFalse(void);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beFalse(void),
|
||||
NMB_beFalse());
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beNil(void);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beNil(void),
|
||||
NMB_beNil());
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_beEmpty(void);
|
||||
NIMBLE_SHORT(id<NMBMatcher> beEmpty(void),
|
||||
NMB_beEmpty());
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_containWithNilTermination(id itemOrSubstring, ...) NS_REQUIRES_NIL_TERMINATION;
|
||||
#define NMB_contain(...) NMB_containWithNilTermination(__VA_ARGS__, nil)
|
||||
#ifndef NIMBLE_DISABLE_SHORT_SYNTAX
|
||||
#define contain(...) NMB_contain(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_endWith(id itemElementOrSubstring);
|
||||
NIMBLE_SHORT(id<NMBMatcher> endWith(id itemElementOrSubstring),
|
||||
NMB_endWith(itemElementOrSubstring));
|
||||
|
||||
NIMBLE_EXPORT NMBObjCRaiseExceptionMatcher *NMB_raiseException(void);
|
||||
NIMBLE_SHORT(NMBObjCRaiseExceptionMatcher *raiseException(void),
|
||||
NMB_raiseException());
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_match(id expectedValue);
|
||||
NIMBLE_SHORT(id<NMBMatcher> match(id expectedValue),
|
||||
NMB_match(expectedValue));
|
||||
|
||||
NIMBLE_EXPORT id<NMBMatcher> NMB_allPass(id matcher);
|
||||
NIMBLE_SHORT(id<NMBMatcher> allPass(id matcher),
|
||||
NMB_allPass(matcher));
|
||||
|
||||
// In order to preserve breakpoint behavior despite using macros to fill in __FILE__ and __LINE__,
|
||||
// define a builder that populates __FILE__ and __LINE__, and returns a block that takes timeout
|
||||
// and action arguments. See https://github.com/Quick/Quick/pull/185 for details.
|
||||
typedef void (^NMBWaitUntilTimeoutBlock)(NSTimeInterval timeout, void (^action)(void (^)(void)));
|
||||
typedef void (^NMBWaitUntilBlock)(void (^action)(void (^)(void)));
|
||||
|
||||
NIMBLE_EXPORT NMBWaitUntilTimeoutBlock NMB_waitUntilTimeoutBuilder(NSString *file, NSUInteger line);
|
||||
NIMBLE_EXPORT NMBWaitUntilBlock NMB_waitUntilBuilder(NSString *file, NSUInteger line);
|
||||
|
||||
NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger line);
|
||||
|
||||
#define NMB_waitUntilTimeout NMB_waitUntilTimeoutBuilder(@(__FILE__), __LINE__)
|
||||
#define NMB_waitUntil NMB_waitUntilBuilder(@(__FILE__), __LINE__)
|
||||
|
||||
#ifndef NIMBLE_DISABLE_SHORT_SYNTAX
|
||||
#define expect(...) NMB_expect(^id{ return (__VA_ARGS__); }, @(__FILE__), __LINE__)
|
||||
#define expectAction(BLOCK) NMB_expectAction((BLOCK), @(__FILE__), __LINE__)
|
||||
#define failWithMessage(msg) NMB_failWithMessage(msg, @(__FILE__), __LINE__)
|
||||
#define fail() failWithMessage(@"fail() always fails")
|
||||
|
||||
|
||||
#define waitUntilTimeout NMB_waitUntilTimeout
|
||||
#define waitUntil NMB_waitUntil
|
||||
#endif
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface NMBExceptionCapture : NSObject
|
||||
|
||||
- (id)initWithHandler:(void(^)(NSException *))handler finally:(void(^)())finally;
|
||||
- (void)tryBlock:(void(^)())unsafeBlock;
|
||||
|
||||
@end
|
||||
-364
@@ -1,364 +0,0 @@
|
||||
// Generated by Apple Swift version 2.0 (swiftlang-700.0.57.3 clang-700.0.72)
|
||||
#pragma clang diagnostic push
|
||||
|
||||
#if defined(__has_include) && __has_include(<swift/objc-prologue.h>)
|
||||
# include <swift/objc-prologue.h>
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic ignored "-Wauto-import"
|
||||
#include <objc/NSObject.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#if defined(__has_include) && __has_include(<uchar.h>)
|
||||
# include <uchar.h>
|
||||
#elif !defined(__cplusplus) || __cplusplus < 201103L
|
||||
typedef uint_least16_t char16_t;
|
||||
typedef uint_least32_t char32_t;
|
||||
#endif
|
||||
|
||||
typedef struct _NSZone NSZone;
|
||||
|
||||
#if !defined(SWIFT_PASTE)
|
||||
# define SWIFT_PASTE_HELPER(x, y) x##y
|
||||
# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y)
|
||||
#endif
|
||||
#if !defined(SWIFT_METATYPE)
|
||||
# define SWIFT_METATYPE(X) Class
|
||||
#endif
|
||||
|
||||
#if defined(__has_attribute) && __has_attribute(objc_runtime_name)
|
||||
# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X)))
|
||||
#else
|
||||
# define SWIFT_RUNTIME_NAME(X)
|
||||
#endif
|
||||
#if defined(__has_attribute) && __has_attribute(swift_name)
|
||||
# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X)))
|
||||
#else
|
||||
# define SWIFT_COMPILE_NAME(X)
|
||||
#endif
|
||||
#if !defined(SWIFT_CLASS_EXTRA)
|
||||
# define SWIFT_CLASS_EXTRA
|
||||
#endif
|
||||
#if !defined(SWIFT_PROTOCOL_EXTRA)
|
||||
# define SWIFT_PROTOCOL_EXTRA
|
||||
#endif
|
||||
#if !defined(SWIFT_ENUM_EXTRA)
|
||||
# define SWIFT_ENUM_EXTRA
|
||||
#endif
|
||||
#if !defined(SWIFT_CLASS)
|
||||
# if defined(__has_attribute) && __has_attribute(objc_subclassing_restricted)
|
||||
# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA
|
||||
# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
|
||||
# else
|
||||
# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
|
||||
# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(SWIFT_PROTOCOL)
|
||||
# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
|
||||
# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
|
||||
#endif
|
||||
|
||||
#if !defined(SWIFT_EXTENSION)
|
||||
# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__)
|
||||
#endif
|
||||
|
||||
#if !defined(OBJC_DESIGNATED_INITIALIZER)
|
||||
# if defined(__has_attribute) && __has_attribute(objc_designated_initializer)
|
||||
# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
|
||||
# else
|
||||
# define OBJC_DESIGNATED_INITIALIZER
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_ENUM)
|
||||
# define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum SWIFT_ENUM_EXTRA _name : _type
|
||||
#endif
|
||||
typedef float swift_float2 __attribute__((__ext_vector_type__(2)));
|
||||
typedef float swift_float3 __attribute__((__ext_vector_type__(3)));
|
||||
typedef float swift_float4 __attribute__((__ext_vector_type__(4)));
|
||||
typedef double swift_double2 __attribute__((__ext_vector_type__(2)));
|
||||
typedef double swift_double3 __attribute__((__ext_vector_type__(3)));
|
||||
typedef double swift_double4 __attribute__((__ext_vector_type__(4)));
|
||||
typedef int swift_int2 __attribute__((__ext_vector_type__(2)));
|
||||
typedef int swift_int3 __attribute__((__ext_vector_type__(3)));
|
||||
typedef int swift_int4 __attribute__((__ext_vector_type__(4)));
|
||||
#if defined(__has_feature) && __has_feature(modules)
|
||||
@import ObjectiveC;
|
||||
@import Foundation;
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch"
|
||||
#pragma clang diagnostic ignored "-Wduplicate-method-arg"
|
||||
|
||||
|
||||
/// Encapsulates the failure message that matchers can report to the end user.
|
||||
///
|
||||
/// This is shared state between Nimble and matchers that mutate this value.
|
||||
SWIFT_CLASS("_TtC6Nimble14FailureMessage")
|
||||
@interface FailureMessage : NSObject
|
||||
@property (nonatomic, copy) NSString * __nonnull expected;
|
||||
@property (nonatomic, copy) NSString * __nullable actualValue;
|
||||
@property (nonatomic, copy) NSString * __nonnull to;
|
||||
@property (nonatomic, copy) NSString * __nonnull postfixMessage;
|
||||
@property (nonatomic, copy) NSString * __nonnull postfixActual;
|
||||
@property (nonatomic, copy) NSString * __nullable userDescription;
|
||||
@property (nonatomic, copy) NSString * __nonnull stringValue;
|
||||
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
|
||||
- (nonnull instancetype)initWithStringValue:(NSString * __nonnull)stringValue OBJC_DESIGNATED_INITIALIZER;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/// Protocol for types that support only beEmpty()
|
||||
SWIFT_PROTOCOL("_TtP6Nimble13NMBCollection_")
|
||||
@protocol NMBCollection
|
||||
@property (nonatomic, readonly) NSInteger count;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/// Protocol for types to support beLessThan(), beLessThanOrEqualTo(), beGreaterThan(), beGreaterThanOrEqualTo(), and equal() matchers.
|
||||
///
|
||||
/// Types that conform to Swift's Comparable protocol will work implicitly too
|
||||
SWIFT_PROTOCOL("_TtP6Nimble13NMBComparable_")
|
||||
@protocol NMBComparable
|
||||
- (NSComparisonResult)NMB_compare:(id <NMBComparable> __null_unspecified)otherObject;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/// Protocol for types that support contain() matcher.
|
||||
SWIFT_PROTOCOL("_TtP6Nimble12NMBContainer_")
|
||||
@protocol NMBContainer
|
||||
- (BOOL)containsObject:(id __null_unspecified)object;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/// Protocol for types to support beCloseTo() matcher
|
||||
SWIFT_PROTOCOL("_TtP6Nimble20NMBDoubleConvertible_")
|
||||
@protocol NMBDoubleConvertible
|
||||
@property (nonatomic, readonly) double doubleValue;
|
||||
@end
|
||||
|
||||
@protocol NMBMatcher;
|
||||
|
||||
SWIFT_CLASS("_TtC6Nimble14NMBExpectation")
|
||||
@interface NMBExpectation : NSObject
|
||||
- (nonnull instancetype)initWithActualBlock:(NSObject * __null_unspecified (^ __nonnull)(void))actualBlock negative:(BOOL)negative file:(NSString * __nonnull)file line:(NSUInteger)line OBJC_DESIGNATED_INITIALIZER;
|
||||
@property (nonatomic, readonly, copy) NMBExpectation * __nonnull (^ __nonnull withTimeout)(NSTimeInterval);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull to)(id <NMBMatcher> __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull toWithDescription)(id <NMBMatcher> __nonnull, NSString * __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull toNot)(id <NMBMatcher> __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull toNotWithDescription)(id <NMBMatcher> __nonnull, NSString * __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull notTo)(id <NMBMatcher> __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull notToWithDescription)(id <NMBMatcher> __nonnull, NSString * __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull toEventually)(id <NMBMatcher> __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull toEventuallyWithDescription)(id <NMBMatcher> __nonnull, NSString * __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull toEventuallyNot)(id <NMBMatcher> __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull toEventuallyNotWithDescription)(id <NMBMatcher> __nonnull, NSString * __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull toNotEventually)(id <NMBMatcher> __nonnull);
|
||||
@property (nonatomic, readonly, copy) void (^ __nonnull toNotEventuallyWithDescription)(id <NMBMatcher> __nonnull, NSString * __nonnull);
|
||||
+ (void)failWithMessage:(NSString * __nonnull)message file:(NSString * __nonnull)file line:(NSUInteger)line;
|
||||
@end
|
||||
|
||||
@class SourceLocation;
|
||||
|
||||
|
||||
/// Objective-C interface to the Swift variant of Matcher.
|
||||
SWIFT_PROTOCOL("_TtP6Nimble10NMBMatcher_")
|
||||
@protocol NMBMatcher
|
||||
- (BOOL)matches:(NSObject * __null_unspecified (^ __nonnull)(void))actualBlock failureMessage:(FailureMessage * __nonnull)failureMessage location:(SourceLocation * __nonnull)location;
|
||||
- (BOOL)doesNotMatch:(NSObject * __null_unspecified (^ __nonnull)(void))actualBlock failureMessage:(FailureMessage * __nonnull)failureMessage location:(SourceLocation * __nonnull)location;
|
||||
@end
|
||||
|
||||
|
||||
SWIFT_CLASS("_TtC6Nimble23NMBObjCBeCloseToMatcher")
|
||||
@interface NMBObjCBeCloseToMatcher : NSObject <NMBMatcher>
|
||||
- (BOOL)matches:(NSObject * __null_unspecified (^ __nonnull)(void))actualExpression failureMessage:(FailureMessage * __nonnull)failureMessage location:(SourceLocation * __nonnull)location;
|
||||
- (BOOL)doesNotMatch:(NSObject * __null_unspecified (^ __nonnull)(void))actualExpression failureMessage:(FailureMessage * __nonnull)failureMessage location:(SourceLocation * __nonnull)location;
|
||||
@property (nonatomic, readonly, copy) NMBObjCBeCloseToMatcher * __nonnull (^ __nonnull within)(double);
|
||||
@end
|
||||
|
||||
|
||||
SWIFT_CLASS("_TtC6Nimble14NMBObjCMatcher")
|
||||
@interface NMBObjCMatcher : NSObject <NMBMatcher>
|
||||
- (BOOL)matches:(NSObject * __null_unspecified (^ __nonnull)(void))actualBlock failureMessage:(FailureMessage * __nonnull)failureMessage location:(SourceLocation * __nonnull)location;
|
||||
- (BOOL)doesNotMatch:(NSObject * __null_unspecified (^ __nonnull)(void))actualBlock failureMessage:(FailureMessage * __nonnull)failureMessage location:(SourceLocation * __nonnull)location;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)beEmptyMatcher;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)beIdenticalToMatcher:(NSObject * __nullable)expected;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)beginWithMatcher:(id __nonnull)expected;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)beGreaterThanOrEqualToMatcher:(id <NMBComparable> __nullable)expected;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)containMatcher:(NSArray<NSObject *> * __nonnull)expected;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)beGreaterThanMatcher:(id <NMBComparable> __nullable)expected;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)beLessThanMatcher:(id <NMBComparable> __nullable)expected;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (id <NMBMatcher> __nonnull)equalMatcher:(NSObject * __nonnull)expected;
|
||||
@end
|
||||
|
||||
@class NSString;
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (id <NMBMatcher> __nonnull)matchMatcher:(NSString * __nonnull)expected;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (id <NMBMatcher> __nonnull)beAKindOfMatcher:(Class __nonnull)expected;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)allPassMatcher:(NMBObjCMatcher * __nonnull)matcher;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (id <NMBMatcher> __nonnull)beAnInstanceOfMatcher:(Class __nonnull)expected;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)beLessThanOrEqualToMatcher:(id <NMBComparable> __nullable)expected;
|
||||
@end
|
||||
|
||||
@class NSNumber;
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCBeCloseToMatcher * __nonnull)beCloseToMatcher:(NSNumber * __nonnull)expected within:(double)within;
|
||||
@end
|
||||
|
||||
@class NMBObjCRaiseExceptionMatcher;
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCRaiseExceptionMatcher * __nonnull)raiseExceptionMatcher;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)endWithMatcher:(id __nonnull)expected;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)beNilMatcher;
|
||||
@end
|
||||
|
||||
|
||||
@interface NMBObjCMatcher (SWIFT_EXTENSION(Nimble))
|
||||
+ (NMBObjCMatcher * __nonnull)beTruthyMatcher;
|
||||
+ (NMBObjCMatcher * __nonnull)beFalsyMatcher;
|
||||
+ (NMBObjCMatcher * __nonnull)beTrueMatcher;
|
||||
+ (NMBObjCMatcher * __nonnull)beFalseMatcher;
|
||||
@end
|
||||
|
||||
@class NSDictionary;
|
||||
@class NSException;
|
||||
|
||||
SWIFT_CLASS("_TtC6Nimble28NMBObjCRaiseExceptionMatcher")
|
||||
@interface NMBObjCRaiseExceptionMatcher : NSObject <NMBMatcher>
|
||||
- (BOOL)matches:(NSObject * __null_unspecified (^ __nonnull)(void))actualBlock failureMessage:(FailureMessage * __nonnull)failureMessage location:(SourceLocation * __nonnull)location;
|
||||
- (BOOL)doesNotMatch:(NSObject * __null_unspecified (^ __nonnull)(void))actualBlock failureMessage:(FailureMessage * __nonnull)failureMessage location:(SourceLocation * __nonnull)location;
|
||||
@property (nonatomic, readonly, copy) NMBObjCRaiseExceptionMatcher * __nonnull (^ __nonnull named)(NSString * __nonnull);
|
||||
@property (nonatomic, readonly, copy) NMBObjCRaiseExceptionMatcher * __nonnull (^ __nonnull reason)(NSString * __nullable);
|
||||
@property (nonatomic, readonly, copy) NMBObjCRaiseExceptionMatcher * __nonnull (^ __nonnull userInfo)(NSDictionary * __nullable);
|
||||
@property (nonatomic, readonly, copy) NMBObjCRaiseExceptionMatcher * __nonnull (^ __nonnull satisfyingBlock)(void (^ __nullable)(NSException * __nonnull));
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/// Protocol for types that support beginWith(), endWith(), beEmpty() matchers
|
||||
SWIFT_PROTOCOL("_TtP6Nimble20NMBOrderedCollection_")
|
||||
@protocol NMBOrderedCollection <NMBCollection>
|
||||
- (NSInteger)indexOfObject:(id __null_unspecified)object;
|
||||
@end
|
||||
|
||||
|
||||
@interface NSArray (SWIFT_EXTENSION(Nimble)) <NMBContainer>
|
||||
@end
|
||||
|
||||
|
||||
@interface NSArray (SWIFT_EXTENSION(Nimble)) <NMBOrderedCollection, NMBCollection>
|
||||
@end
|
||||
|
||||
|
||||
@interface NSArray (SWIFT_EXTENSION(Nimble))
|
||||
@end
|
||||
|
||||
|
||||
@interface NSDictionary (SWIFT_EXTENSION(Nimble)) <NMBCollection>
|
||||
@end
|
||||
|
||||
|
||||
@interface NSHashTable (SWIFT_EXTENSION(Nimble)) <NMBContainer>
|
||||
@end
|
||||
|
||||
|
||||
@interface NSHashTable (SWIFT_EXTENSION(Nimble)) <NMBCollection>
|
||||
@end
|
||||
|
||||
|
||||
@interface NSNumber (SWIFT_EXTENSION(Nimble)) <NMBDoubleConvertible>
|
||||
@end
|
||||
|
||||
|
||||
@interface NSNumber (SWIFT_EXTENSION(Nimble)) <NMBComparable>
|
||||
- (NSComparisonResult)NMB_compare:(id <NMBComparable> __null_unspecified)otherObject;
|
||||
@end
|
||||
|
||||
|
||||
@interface NSSet (SWIFT_EXTENSION(Nimble)) <NMBCollection>
|
||||
@end
|
||||
|
||||
|
||||
@interface NSSet (SWIFT_EXTENSION(Nimble)) <NMBContainer>
|
||||
@end
|
||||
|
||||
|
||||
@interface NSString (SWIFT_EXTENSION(Nimble)) <NMBComparable>
|
||||
- (NSComparisonResult)NMB_compare:(id <NMBComparable> __null_unspecified)otherObject;
|
||||
@end
|
||||
|
||||
|
||||
SWIFT_CLASS("_TtC6Nimble14SourceLocation")
|
||||
@interface SourceLocation : NSObject
|
||||
@property (nonatomic, readonly, copy) NSString * __nonnull file;
|
||||
@property (nonatomic, readonly) NSUInteger line;
|
||||
@property (nonatomic, readonly, copy) NSString * __nonnull description;
|
||||
@end
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Nimble/NMBExceptionCapture.h>
|
||||
#import <Nimble/DSL.h>
|
||||
|
||||
FOUNDATION_EXPORT double NimbleVersionNumber;
|
||||
FOUNDATION_EXPORT const unsigned char NimbleVersionString[];
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
-10
@@ -1,10 +0,0 @@
|
||||
framework module Nimble {
|
||||
umbrella header "Nimble.h"
|
||||
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
||||
|
||||
module Nimble.Swift {
|
||||
header "Nimble-Swift.h"
|
||||
}
|
||||
BIN
Binary file not shown.
-183
@@ -1,183 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>files</key>
|
||||
<dict>
|
||||
<key>Headers/DSL.h</key>
|
||||
<data>
|
||||
auYzCIxlY2jTkyI1BlljW3KUTJY=
|
||||
</data>
|
||||
<key>Headers/NMBExceptionCapture.h</key>
|
||||
<data>
|
||||
ncXv+PqMUjLHOJpiFz6BKmTAq5o=
|
||||
</data>
|
||||
<key>Headers/Nimble-Swift.h</key>
|
||||
<data>
|
||||
ix7zUf4GFfA4sevTnSKvAsAN3xM=
|
||||
</data>
|
||||
<key>Headers/Nimble.h</key>
|
||||
<data>
|
||||
HXkPd6XbqY7QmdFCpOCNIHhI4v0=
|
||||
</data>
|
||||
<key>Info.plist</key>
|
||||
<data>
|
||||
m9rBh3svN6G89okFeorwD5OH+2g=
|
||||
</data>
|
||||
<key>Modules/Nimble.swiftmodule/arm.swiftdoc</key>
|
||||
<data>
|
||||
lSaVfyH8XbRz0WDbmqKJxc5QtbY=
|
||||
</data>
|
||||
<key>Modules/Nimble.swiftmodule/arm.swiftmodule</key>
|
||||
<data>
|
||||
NseDOVaErTA347+6KjeL5eI3+kI=
|
||||
</data>
|
||||
<key>Modules/Nimble.swiftmodule/arm64.swiftdoc</key>
|
||||
<data>
|
||||
6W52hA33Ca+9qq8Yiql4aY8+0Rk=
|
||||
</data>
|
||||
<key>Modules/Nimble.swiftmodule/arm64.swiftmodule</key>
|
||||
<data>
|
||||
Yn3aQiLuskjb8JCg2+JAqYVrN/Y=
|
||||
</data>
|
||||
<key>Modules/module.modulemap</key>
|
||||
<data>
|
||||
HraXvk1VTxnsGdY8oSlKGNkdg60=
|
||||
</data>
|
||||
</dict>
|
||||
<key>files2</key>
|
||||
<dict>
|
||||
<key>Headers/DSL.h</key>
|
||||
<data>
|
||||
auYzCIxlY2jTkyI1BlljW3KUTJY=
|
||||
</data>
|
||||
<key>Headers/NMBExceptionCapture.h</key>
|
||||
<data>
|
||||
ncXv+PqMUjLHOJpiFz6BKmTAq5o=
|
||||
</data>
|
||||
<key>Headers/Nimble-Swift.h</key>
|
||||
<data>
|
||||
ix7zUf4GFfA4sevTnSKvAsAN3xM=
|
||||
</data>
|
||||
<key>Headers/Nimble.h</key>
|
||||
<data>
|
||||
HXkPd6XbqY7QmdFCpOCNIHhI4v0=
|
||||
</data>
|
||||
<key>Modules/Nimble.swiftmodule/arm.swiftdoc</key>
|
||||
<data>
|
||||
lSaVfyH8XbRz0WDbmqKJxc5QtbY=
|
||||
</data>
|
||||
<key>Modules/Nimble.swiftmodule/arm.swiftmodule</key>
|
||||
<data>
|
||||
NseDOVaErTA347+6KjeL5eI3+kI=
|
||||
</data>
|
||||
<key>Modules/Nimble.swiftmodule/arm64.swiftdoc</key>
|
||||
<data>
|
||||
6W52hA33Ca+9qq8Yiql4aY8+0Rk=
|
||||
</data>
|
||||
<key>Modules/Nimble.swiftmodule/arm64.swiftmodule</key>
|
||||
<data>
|
||||
Yn3aQiLuskjb8JCg2+JAqYVrN/Y=
|
||||
</data>
|
||||
<key>Modules/module.modulemap</key>
|
||||
<data>
|
||||
HraXvk1VTxnsGdY8oSlKGNkdg60=
|
||||
</data>
|
||||
</dict>
|
||||
<key>rules</key>
|
||||
<dict>
|
||||
<key>^</key>
|
||||
<true/>
|
||||
<key>^.*\.lproj/</key>
|
||||
<dict>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1000</real>
|
||||
</dict>
|
||||
<key>^.*\.lproj/locversion.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1100</real>
|
||||
</dict>
|
||||
<key>^version.plist$</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>rules2</key>
|
||||
<dict>
|
||||
<key>.*\.dSYM($|/)</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>11</real>
|
||||
</dict>
|
||||
<key>^</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^(.*/)?\.DS_Store$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>2000</real>
|
||||
</dict>
|
||||
<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
|
||||
<dict>
|
||||
<key>nested</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>10</real>
|
||||
</dict>
|
||||
<key>^.*</key>
|
||||
<true/>
|
||||
<key>^.*\.lproj/</key>
|
||||
<dict>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1000</real>
|
||||
</dict>
|
||||
<key>^.*\.lproj/locversion.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1100</real>
|
||||
</dict>
|
||||
<key>^Info\.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^PkgInfo$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^[^/]+$</key>
|
||||
<dict>
|
||||
<key>nested</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>10</real>
|
||||
</dict>
|
||||
<key>^embedded\.provisionprofile$</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^version\.plist$</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Lukas Kubanek
|
||||
Copyright (c) 2015-2019 Lukas Kubanek
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -7,260 +7,228 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
803F9CD51B92324C002F728F /* OrderedDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 803F9CD21B92324C002F728F /* OrderedDictionary.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
803F9CD81B9232EE002F728F /* OrderedDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 803F9CD71B9232EE002F728F /* OrderedDictionary.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
803F9CF41B925B1C002F728F /* OrderedDictionary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 803F9CC61B923207002F728F /* OrderedDictionary.framework */; settings = {ASSET_TAGS = (); }; };
|
||||
803F9CFD1B925B4C002F728F /* OrderedDictionaryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 803F9CFC1B925B4C002F728F /* OrderedDictionaryTests.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
803F9D001B925BBF002F728F /* Nimble.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 803F9CE91B925AE5002F728F /* Nimble.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
803F9D011B925BE9002F728F /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 803F9CE91B925AE5002F728F /* Nimble.framework */; };
|
||||
8060976B1B92F2D200DB20CF /* OrderedDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 803F9CD71B9232EE002F728F /* OrderedDictionary.swift */; };
|
||||
8060976C1B92F2D900DB20CF /* OrderedDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 803F9CD21B92324C002F728F /* OrderedDictionary.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
806097761B92F44F00DB20CF /* OrderedDictionary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 806097631B92F20400DB20CF /* OrderedDictionary.framework */; settings = {ASSET_TAGS = (); }; };
|
||||
8060977C1B92F4A000DB20CF /* OrderedDictionaryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 803F9CFC1B925B4C002F728F /* OrderedDictionaryTests.swift */; };
|
||||
806097801B92F4F000DB20CF /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8060977F1B92F4F000DB20CF /* Nimble.framework */; settings = {ASSET_TAGS = (); }; };
|
||||
806097821B92F4FC00DB20CF /* Nimble.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8060977F1B92F4F000DB20CF /* Nimble.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
8055B0421E201C5D009DC3EE /* OrderedDictionary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8055B0381E201C5D009DC3EE /* OrderedDictionary.framework */; };
|
||||
8055B0591E201DF3009DC3EE /* OrderedDictionaryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8055B0581E201DF3009DC3EE /* OrderedDictionaryTests.swift */; };
|
||||
80A203A11F3F483700622481 /* OrderedDictionary+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80A203A01F3F483700622481 /* OrderedDictionary+Codable.swift */; };
|
||||
80A203A21F3F4C1F00622481 /* OrderedDictionary+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80A203A01F3F483700622481 /* OrderedDictionary+Codable.swift */; };
|
||||
80B28EA01E201EC9007E3A77 /* OrderedDictionary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 80B28E971E201EC8007E3A77 /* OrderedDictionary.framework */; };
|
||||
80B28EB01E201F1C007E3A77 /* OrderedDictionaryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8055B0581E201DF3009DC3EE /* OrderedDictionaryTests.swift */; };
|
||||
80E8E21D1E20301E00395E49 /* OrderedDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80E8E21C1E20301E00395E49 /* OrderedDictionary.swift */; };
|
||||
80E8E21F1E20425B00395E49 /* OrderedDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80E8E21C1E20301E00395E49 /* OrderedDictionary.swift */; };
|
||||
80E8E2301E2133D100395E49 /* OrderedDictionary+Description.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80E8E22F1E2133D100395E49 /* OrderedDictionary+Description.swift */; };
|
||||
80E8E2311E2133D100395E49 /* OrderedDictionary+Description.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80E8E22F1E2133D100395E49 /* OrderedDictionary+Description.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
803F9CF51B925B1C002F728F /* PBXContainerItemProxy */ = {
|
||||
8055B0431E201C5D009DC3EE /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 803F9CBD1B923207002F728F /* Project object */;
|
||||
containerPortal = 8055B02F1E201C5D009DC3EE /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 803F9CC51B923207002F728F;
|
||||
remoteGlobalIDString = 8055B0371E201C5D009DC3EE;
|
||||
remoteInfo = OrderedDictionary;
|
||||
};
|
||||
806097771B92F44F00DB20CF /* PBXContainerItemProxy */ = {
|
||||
80B28EA11E201EC9007E3A77 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 803F9CBD1B923207002F728F /* Project object */;
|
||||
containerPortal = 8055B02F1E201C5D009DC3EE /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 806097621B92F20400DB20CF;
|
||||
remoteGlobalIDString = 80B28E961E201EC8007E3A77;
|
||||
remoteInfo = "OrderedDictionary-iOS";
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
803F9CFF1B925BA2002F728F /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
803F9D001B925BBF002F728F /* Nimble.framework in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
806097811B92F4F500DB20CF /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
806097821B92F4FC00DB20CF /* Nimble.framework in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
803F9CC61B923207002F728F /* OrderedDictionary.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OrderedDictionary.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
803F9CD21B92324C002F728F /* OrderedDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OrderedDictionary.h; sourceTree = "<group>"; };
|
||||
803F9CD41B92324C002F728F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
803F9CD71B9232EE002F728F /* OrderedDictionary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrderedDictionary.swift; sourceTree = "<group>"; };
|
||||
803F9CE91B925AE5002F728F /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nimble.framework; path = Carthage/Build/Mac/Nimble.framework; sourceTree = "<group>"; };
|
||||
803F9CEF1B925B1C002F728F /* OrderedDictionary-OSX-Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "OrderedDictionary-OSX-Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
803F9CFC1B925B4C002F728F /* OrderedDictionaryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrderedDictionaryTests.swift; sourceTree = "<group>"; };
|
||||
803F9CFE1B925B56002F728F /* Info-Tests.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Info-Tests.plist"; path = "Supporting Files/Info-Tests.plist"; sourceTree = SOURCE_ROOT; };
|
||||
806097631B92F20400DB20CF /* OrderedDictionary.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OrderedDictionary.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
806097711B92F44F00DB20CF /* OrderedDictionary-iOS-Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "OrderedDictionary-iOS-Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
8060977F1B92F4F000DB20CF /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nimble.framework; path = Carthage/Build/iOS/Nimble.framework; sourceTree = "<group>"; };
|
||||
80F94F181B926A60000A96E7 /* OrderedDictionary.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = OrderedDictionary.playground; sourceTree = "<group>"; };
|
||||
8024947E2277123600AB44C7 /* Package@swift-4.2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Package@swift-4.2.swift"; sourceTree = "<group>"; };
|
||||
8024947F2277136D00AB44C7 /* Package@swift-5.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Package@swift-5.swift"; sourceTree = "<group>"; };
|
||||
804879371E217C7700AD31A3 /* build.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = build.sh; sourceTree = "<group>"; };
|
||||
804879381E217CA100AD31A3 /* validate-playgrounds.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "validate-playgrounds.sh"; sourceTree = "<group>"; };
|
||||
8055B0381E201C5D009DC3EE /* OrderedDictionary.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OrderedDictionary.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
8055B0411E201C5D009DC3EE /* OrderedDictionary_Mac_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OrderedDictionary_Mac_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
8055B0581E201DF3009DC3EE /* OrderedDictionaryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrderedDictionaryTests.swift; sourceTree = "<group>"; };
|
||||
807AA68F1F1E587A00576474 /* OrderedDictionary+Codable.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = "OrderedDictionary+Codable.playground"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
||||
80A203A01F3F483700622481 /* OrderedDictionary+Codable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OrderedDictionary+Codable.swift"; sourceTree = "<group>"; };
|
||||
80B28E971E201EC8007E3A77 /* OrderedDictionary.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OrderedDictionary.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
80B28E9F1E201EC9007E3A77 /* OrderedDictionary_iOS_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OrderedDictionary_iOS_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
80B28EB41E201F81007E3A77 /* Info-Tests.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-Tests.plist"; sourceTree = "<group>"; };
|
||||
80B28EB51E201F81007E3A77 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
80B28EB71E2020DD007E3A77 /* OrderedDictionary.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = OrderedDictionary.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
||||
80DE329220F4CAFA0053EDA7 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = "<group>"; };
|
||||
80DE329320F4DD910053EDA7 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
||||
80DE329420F4DD910053EDA7 /* LICENSE.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = LICENSE.md; sourceTree = "<group>"; };
|
||||
80E8E21C1E20301E00395E49 /* OrderedDictionary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrderedDictionary.swift; sourceTree = "<group>"; };
|
||||
80E8E22F1E2133D100395E49 /* OrderedDictionary+Description.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "OrderedDictionary+Description.swift"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
803F9CC21B923207002F728F /* Frameworks */ = {
|
||||
8055B0341E201C5D009DC3EE /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
803F9CEC1B925B1C002F728F /* Frameworks */ = {
|
||||
8055B03E1E201C5D009DC3EE /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
803F9CF41B925B1C002F728F /* OrderedDictionary.framework in Frameworks */,
|
||||
803F9D011B925BE9002F728F /* Nimble.framework in Frameworks */,
|
||||
8055B0421E201C5D009DC3EE /* OrderedDictionary.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
8060975F1B92F20400DB20CF /* Frameworks */ = {
|
||||
80B28E931E201EC8007E3A77 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
8060976E1B92F44F00DB20CF /* Frameworks */ = {
|
||||
80B28E9C1E201EC9007E3A77 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
806097761B92F44F00DB20CF /* OrderedDictionary.framework in Frameworks */,
|
||||
806097801B92F4F000DB20CF /* Nimble.framework in Frameworks */,
|
||||
80B28EA01E201EC9007E3A77 /* OrderedDictionary.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
803F9CBC1B923207002F728F = {
|
||||
804879361E217C7700AD31A3 /* Scripts */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
803F9CD11B92324C002F728F /* Sources */,
|
||||
80F94F171B926A60000A96E7 /* Playgrounds */,
|
||||
803F9CFB1B925B4C002F728F /* Tests */,
|
||||
803F9CD31B92324C002F728F /* Supporting Files */,
|
||||
803F9CE81B9259F3002F728F /* Frameworks */,
|
||||
803F9CC71B923207002F728F /* Products */,
|
||||
804879371E217C7700AD31A3 /* build.sh */,
|
||||
804879381E217CA100AD31A3 /* validate-playgrounds.sh */,
|
||||
);
|
||||
path = Scripts;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8055B02E1E201C5D009DC3EE = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
80DE329320F4DD910053EDA7 /* README.md */,
|
||||
80DE329420F4DD910053EDA7 /* LICENSE.md */,
|
||||
80DE329220F4CAFA0053EDA7 /* Package.swift */,
|
||||
8024947E2277123600AB44C7 /* Package@swift-4.2.swift */,
|
||||
8024947F2277136D00AB44C7 /* Package@swift-5.swift */,
|
||||
8055B0521E201D24009DC3EE /* Sources */,
|
||||
80B28EB11E201F72007E3A77 /* Playgrounds */,
|
||||
8055B0571E201DF3009DC3EE /* Tests */,
|
||||
80B28EB31E201F81007E3A77 /* Supporting Files */,
|
||||
804879361E217C7700AD31A3 /* Scripts */,
|
||||
8055B0391E201C5D009DC3EE /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
803F9CC71B923207002F728F /* Products */ = {
|
||||
8055B0391E201C5D009DC3EE /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
803F9CC61B923207002F728F /* OrderedDictionary.framework */,
|
||||
803F9CEF1B925B1C002F728F /* OrderedDictionary-OSX-Tests.xctest */,
|
||||
806097631B92F20400DB20CF /* OrderedDictionary.framework */,
|
||||
806097711B92F44F00DB20CF /* OrderedDictionary-iOS-Tests.xctest */,
|
||||
8055B0381E201C5D009DC3EE /* OrderedDictionary.framework */,
|
||||
8055B0411E201C5D009DC3EE /* OrderedDictionary_Mac_Tests.xctest */,
|
||||
80B28E971E201EC8007E3A77 /* OrderedDictionary.framework */,
|
||||
80B28E9F1E201EC9007E3A77 /* OrderedDictionary_iOS_Tests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
803F9CD11B92324C002F728F /* Sources */ = {
|
||||
8055B0521E201D24009DC3EE /* Sources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
803F9CD21B92324C002F728F /* OrderedDictionary.h */,
|
||||
803F9CD71B9232EE002F728F /* OrderedDictionary.swift */,
|
||||
80E8E21C1E20301E00395E49 /* OrderedDictionary.swift */,
|
||||
80A203A01F3F483700622481 /* OrderedDictionary+Codable.swift */,
|
||||
80E8E22F1E2133D100395E49 /* OrderedDictionary+Description.swift */,
|
||||
);
|
||||
path = Sources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
803F9CD31B92324C002F728F /* Supporting Files */ = {
|
||||
8055B0571E201DF3009DC3EE /* Tests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
803F9CD41B92324C002F728F /* Info.plist */,
|
||||
803F9CFE1B925B56002F728F /* Info-Tests.plist */,
|
||||
);
|
||||
path = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
803F9CE81B9259F3002F728F /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8060977D1B92F4D900DB20CF /* OSX */,
|
||||
8060977E1B92F4DF00DB20CF /* iOS */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
803F9CFB1B925B4C002F728F /* Tests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
803F9CFC1B925B4C002F728F /* OrderedDictionaryTests.swift */,
|
||||
8055B0581E201DF3009DC3EE /* OrderedDictionaryTests.swift */,
|
||||
);
|
||||
path = Tests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8060977D1B92F4D900DB20CF /* OSX */ = {
|
||||
80B28EB11E201F72007E3A77 /* Playgrounds */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
803F9CE91B925AE5002F728F /* Nimble.framework */,
|
||||
);
|
||||
name = OSX;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8060977E1B92F4DF00DB20CF /* iOS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8060977F1B92F4F000DB20CF /* Nimble.framework */,
|
||||
);
|
||||
name = iOS;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
80F94F171B926A60000A96E7 /* Playgrounds */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
80F94F181B926A60000A96E7 /* OrderedDictionary.playground */,
|
||||
80B28EB71E2020DD007E3A77 /* OrderedDictionary.playground */,
|
||||
807AA68F1F1E587A00576474 /* OrderedDictionary+Codable.playground */,
|
||||
);
|
||||
path = Playgrounds;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
80B28EB31E201F81007E3A77 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
80B28EB51E201F81007E3A77 /* Info.plist */,
|
||||
80B28EB41E201F81007E3A77 /* Info-Tests.plist */,
|
||||
);
|
||||
path = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
803F9CC31B923207002F728F /* Headers */ = {
|
||||
8055B0351E201C5D009DC3EE /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
803F9CD51B92324C002F728F /* OrderedDictionary.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
806097601B92F20400DB20CF /* Headers */ = {
|
||||
80B28E941E201EC8007E3A77 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8060976C1B92F2D900DB20CF /* OrderedDictionary.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
803F9CC51B923207002F728F /* OrderedDictionary-OSX */ = {
|
||||
8055B0371E201C5D009DC3EE /* OrderedDictionary-Mac */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 803F9CCE1B923207002F728F /* Build configuration list for PBXNativeTarget "OrderedDictionary-OSX" */;
|
||||
buildConfigurationList = 8055B04C1E201C5D009DC3EE /* Build configuration list for PBXNativeTarget "OrderedDictionary-Mac" */;
|
||||
buildPhases = (
|
||||
803F9CC11B923207002F728F /* Sources */,
|
||||
803F9CC21B923207002F728F /* Frameworks */,
|
||||
803F9CC31B923207002F728F /* Headers */,
|
||||
803F9CC41B923207002F728F /* Resources */,
|
||||
8055B0331E201C5D009DC3EE /* Sources */,
|
||||
8055B0341E201C5D009DC3EE /* Frameworks */,
|
||||
8055B0351E201C5D009DC3EE /* Headers */,
|
||||
8055B0361E201C5D009DC3EE /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "OrderedDictionary-OSX";
|
||||
name = "OrderedDictionary-Mac";
|
||||
productName = OrderedDictionary;
|
||||
productReference = 803F9CC61B923207002F728F /* OrderedDictionary.framework */;
|
||||
productReference = 8055B0381E201C5D009DC3EE /* OrderedDictionary.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
803F9CEE1B925B1C002F728F /* OrderedDictionary-OSX-Tests */ = {
|
||||
8055B0401E201C5D009DC3EE /* OrderedDictionary-Mac-Tests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 803F9CF71B925B1C002F728F /* Build configuration list for PBXNativeTarget "OrderedDictionary-OSX-Tests" */;
|
||||
buildConfigurationList = 8055B04F1E201C5D009DC3EE /* Build configuration list for PBXNativeTarget "OrderedDictionary-Mac-Tests" */;
|
||||
buildPhases = (
|
||||
803F9CEB1B925B1C002F728F /* Sources */,
|
||||
803F9CEC1B925B1C002F728F /* Frameworks */,
|
||||
803F9CED1B925B1C002F728F /* Resources */,
|
||||
803F9CFF1B925BA2002F728F /* CopyFiles */,
|
||||
8055B03D1E201C5D009DC3EE /* Sources */,
|
||||
8055B03E1E201C5D009DC3EE /* Frameworks */,
|
||||
8055B03F1E201C5D009DC3EE /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
803F9CF61B925B1C002F728F /* PBXTargetDependency */,
|
||||
8055B0441E201C5D009DC3EE /* PBXTargetDependency */,
|
||||
);
|
||||
name = "OrderedDictionary-OSX-Tests";
|
||||
name = "OrderedDictionary-Mac-Tests";
|
||||
productName = OrderedDictionaryTests;
|
||||
productReference = 803F9CEF1B925B1C002F728F /* OrderedDictionary-OSX-Tests.xctest */;
|
||||
productReference = 8055B0411E201C5D009DC3EE /* OrderedDictionary_Mac_Tests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
806097621B92F20400DB20CF /* OrderedDictionary-iOS */ = {
|
||||
80B28E961E201EC8007E3A77 /* OrderedDictionary-iOS */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 806097681B92F20400DB20CF /* Build configuration list for PBXNativeTarget "OrderedDictionary-iOS" */;
|
||||
buildConfigurationList = 80B28EA81E201EC9007E3A77 /* Build configuration list for PBXNativeTarget "OrderedDictionary-iOS" */;
|
||||
buildPhases = (
|
||||
8060975E1B92F20400DB20CF /* Sources */,
|
||||
8060975F1B92F20400DB20CF /* Frameworks */,
|
||||
806097601B92F20400DB20CF /* Headers */,
|
||||
806097611B92F20400DB20CF /* Resources */,
|
||||
80B28E921E201EC8007E3A77 /* Sources */,
|
||||
80B28E931E201EC8007E3A77 /* Frameworks */,
|
||||
80B28E941E201EC8007E3A77 /* Headers */,
|
||||
80B28E951E201EC8007E3A77 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -268,95 +236,103 @@
|
||||
);
|
||||
name = "OrderedDictionary-iOS";
|
||||
productName = "OrderedDictionary-iOS";
|
||||
productReference = 806097631B92F20400DB20CF /* OrderedDictionary.framework */;
|
||||
productReference = 80B28E971E201EC8007E3A77 /* OrderedDictionary.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
806097701B92F44F00DB20CF /* OrderedDictionary-iOS-Tests */ = {
|
||||
80B28E9E1E201EC9007E3A77 /* OrderedDictionary-iOS-Tests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 806097791B92F44F00DB20CF /* Build configuration list for PBXNativeTarget "OrderedDictionary-iOS-Tests" */;
|
||||
buildConfigurationList = 80B28EAB1E201EC9007E3A77 /* Build configuration list for PBXNativeTarget "OrderedDictionary-iOS-Tests" */;
|
||||
buildPhases = (
|
||||
8060976D1B92F44F00DB20CF /* Sources */,
|
||||
8060976E1B92F44F00DB20CF /* Frameworks */,
|
||||
8060976F1B92F44F00DB20CF /* Resources */,
|
||||
806097811B92F4F500DB20CF /* CopyFiles */,
|
||||
80B28E9B1E201EC9007E3A77 /* Sources */,
|
||||
80B28E9C1E201EC9007E3A77 /* Frameworks */,
|
||||
80B28E9D1E201EC9007E3A77 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
806097781B92F44F00DB20CF /* PBXTargetDependency */,
|
||||
80B28EA21E201EC9007E3A77 /* PBXTargetDependency */,
|
||||
);
|
||||
name = "OrderedDictionary-iOS-Tests";
|
||||
productName = "OrderedDictionary-iOS-Tests";
|
||||
productReference = 806097711B92F44F00DB20CF /* OrderedDictionary-iOS-Tests.xctest */;
|
||||
productName = "OrderedDictionary-iOSTests";
|
||||
productReference = 80B28E9F1E201EC9007E3A77 /* OrderedDictionary_iOS_Tests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
803F9CBD1B923207002F728F /* Project object */ = {
|
||||
8055B02F1E201C5D009DC3EE /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0700;
|
||||
LastUpgradeCheck = 0700;
|
||||
LastSwiftUpdateCheck = 0820;
|
||||
LastUpgradeCheck = 1020;
|
||||
ORGANIZATIONNAME = "Lukas Kubanek";
|
||||
TargetAttributes = {
|
||||
803F9CC51B923207002F728F = {
|
||||
CreatedOnToolsVersion = 7.0;
|
||||
8055B0371E201C5D009DC3EE = {
|
||||
CreatedOnToolsVersion = 8.2.1;
|
||||
LastSwiftMigration = 1020;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
803F9CEE1B925B1C002F728F = {
|
||||
CreatedOnToolsVersion = 7.0;
|
||||
8055B0401E201C5D009DC3EE = {
|
||||
CreatedOnToolsVersion = 8.2.1;
|
||||
LastSwiftMigration = 1020;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
806097621B92F20400DB20CF = {
|
||||
CreatedOnToolsVersion = 7.0;
|
||||
80B28E961E201EC8007E3A77 = {
|
||||
CreatedOnToolsVersion = 8.2.1;
|
||||
LastSwiftMigration = 1020;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
806097701B92F44F00DB20CF = {
|
||||
CreatedOnToolsVersion = 7.0;
|
||||
80B28E9E1E201EC9007E3A77 = {
|
||||
CreatedOnToolsVersion = 8.2.1;
|
||||
LastSwiftMigration = 1020;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 803F9CC01B923207002F728F /* Build configuration list for PBXProject "OrderedDictionary" */;
|
||||
buildConfigurationList = 8055B0321E201C5D009DC3EE /* Build configuration list for PBXProject "OrderedDictionary" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 803F9CBC1B923207002F728F;
|
||||
productRefGroup = 803F9CC71B923207002F728F /* Products */;
|
||||
mainGroup = 8055B02E1E201C5D009DC3EE;
|
||||
productRefGroup = 8055B0391E201C5D009DC3EE /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
803F9CC51B923207002F728F /* OrderedDictionary-OSX */,
|
||||
803F9CEE1B925B1C002F728F /* OrderedDictionary-OSX-Tests */,
|
||||
806097621B92F20400DB20CF /* OrderedDictionary-iOS */,
|
||||
806097701B92F44F00DB20CF /* OrderedDictionary-iOS-Tests */,
|
||||
8055B0371E201C5D009DC3EE /* OrderedDictionary-Mac */,
|
||||
8055B0401E201C5D009DC3EE /* OrderedDictionary-Mac-Tests */,
|
||||
80B28E961E201EC8007E3A77 /* OrderedDictionary-iOS */,
|
||||
80B28E9E1E201EC9007E3A77 /* OrderedDictionary-iOS-Tests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
803F9CC41B923207002F728F /* Resources */ = {
|
||||
8055B0361E201C5D009DC3EE /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
803F9CED1B925B1C002F728F /* Resources */ = {
|
||||
8055B03F1E201C5D009DC3EE /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
806097611B92F20400DB20CF /* Resources */ = {
|
||||
80B28E951E201EC8007E3A77 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
8060976F1B92F44F00DB20CF /* Resources */ = {
|
||||
80B28E9D1E201EC9007E3A77 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
@@ -366,71 +342,89 @@
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
803F9CC11B923207002F728F /* Sources */ = {
|
||||
8055B0331E201C5D009DC3EE /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
803F9CD81B9232EE002F728F /* OrderedDictionary.swift in Sources */,
|
||||
80E8E2301E2133D100395E49 /* OrderedDictionary+Description.swift in Sources */,
|
||||
80E8E21D1E20301E00395E49 /* OrderedDictionary.swift in Sources */,
|
||||
80A203A11F3F483700622481 /* OrderedDictionary+Codable.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
803F9CEB1B925B1C002F728F /* Sources */ = {
|
||||
8055B03D1E201C5D009DC3EE /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
803F9CFD1B925B4C002F728F /* OrderedDictionaryTests.swift in Sources */,
|
||||
8055B0591E201DF3009DC3EE /* OrderedDictionaryTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
8060975E1B92F20400DB20CF /* Sources */ = {
|
||||
80B28E921E201EC8007E3A77 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8060976B1B92F2D200DB20CF /* OrderedDictionary.swift in Sources */,
|
||||
80E8E2311E2133D100395E49 /* OrderedDictionary+Description.swift in Sources */,
|
||||
80E8E21F1E20425B00395E49 /* OrderedDictionary.swift in Sources */,
|
||||
80A203A21F3F4C1F00622481 /* OrderedDictionary+Codable.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
8060976D1B92F44F00DB20CF /* Sources */ = {
|
||||
80B28E9B1E201EC9007E3A77 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8060977C1B92F4A000DB20CF /* OrderedDictionaryTests.swift in Sources */,
|
||||
80B28EB01E201F1C007E3A77 /* OrderedDictionaryTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
803F9CF61B925B1C002F728F /* PBXTargetDependency */ = {
|
||||
8055B0441E201C5D009DC3EE /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 803F9CC51B923207002F728F /* OrderedDictionary-OSX */;
|
||||
targetProxy = 803F9CF51B925B1C002F728F /* PBXContainerItemProxy */;
|
||||
target = 8055B0371E201C5D009DC3EE /* OrderedDictionary-Mac */;
|
||||
targetProxy = 8055B0431E201C5D009DC3EE /* PBXContainerItemProxy */;
|
||||
};
|
||||
806097781B92F44F00DB20CF /* PBXTargetDependency */ = {
|
||||
80B28EA21E201EC9007E3A77 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 806097621B92F20400DB20CF /* OrderedDictionary-iOS */;
|
||||
targetProxy = 806097771B92F44F00DB20CF /* PBXContainerItemProxy */;
|
||||
target = 80B28E961E201EC8007E3A77 /* OrderedDictionary-iOS */;
|
||||
targetProxy = 80B28EA11E201EC9007E3A77 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
803F9CCC1B923207002F728F /* Debug */ = {
|
||||
8055B04A1E201C5D009DC3EE /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
@@ -450,33 +444,51 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
803F9CCD1B923207002F728F /* Release */ = {
|
||||
8055B04B1E201C5D009DC3EE /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
@@ -490,27 +502,29 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = macosx;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
803F9CCF1B923207002F728F /* Debug */ = {
|
||||
8055B04D1E201C5D009DC3EE /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
||||
CLANG_ENABLE_CODE_COVERAGE = NO;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Carthage/Build/Mac",
|
||||
);
|
||||
FRAMEWORK_VERSION = A;
|
||||
INFOPLIST_FILE = "Supporting Files/Info.plist";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
@@ -518,23 +532,20 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lukaskubanek.OrderedDictionary;
|
||||
PRODUCT_NAME = OrderedDictionary;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
803F9CD01B923207002F728F /* Release */ = {
|
||||
8055B04E1E201C5D009DC3EE /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
||||
CLANG_ENABLE_CODE_COVERAGE = NO;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Carthage/Build/Mac",
|
||||
);
|
||||
FRAMEWORK_VERSION = A;
|
||||
INFOPLIST_FILE = "Supporting Files/Info.plist";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
@@ -545,40 +556,37 @@
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
803F9CF81B925B1C002F728F /* Debug */ = {
|
||||
8055B0501E201C5D009DC3EE /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Carthage/Build/Mac",
|
||||
);
|
||||
INFOPLIST_FILE = "Supporting Files/Info-Tests.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lukaskubanek.OrderedDictionaryTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
803F9CF91B925B1C002F728F /* Release */ = {
|
||||
8055B0511E201C5D009DC3EE /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Carthage/Build/Mac",
|
||||
);
|
||||
INFOPLIST_FILE = "Supporting Files/Info-Tests.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lukaskubanek.OrderedDictionaryTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
806097691B92F20400DB20CF /* Debug */ = {
|
||||
80B28EA91E201EC9007E3A77 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
||||
CLANG_ENABLE_CODE_COVERAGE = NO;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
@@ -594,10 +602,13 @@
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
8060976A1B92F20400DB20CF /* Release */ = {
|
||||
80B28EAA1E201EC9007E3A77 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
||||
CLANG_ENABLE_CODE_COVERAGE = NO;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
@@ -614,34 +625,26 @@
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
8060977A1B92F44F00DB20CF /* Debug */ = {
|
||||
80B28EAC1E201EC9007E3A77 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Carthage/Build/iOS",
|
||||
);
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
INFOPLIST_FILE = "Supporting Files/Info-Tests.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.lukaskubanek.OrderedDictionary-iOS-Tests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.lukaskubanek.OrderedDictionary-iOSTests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
8060977B1B92F44F00DB20CF /* Release */ = {
|
||||
80B28EAD1E201EC9007E3A77 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Carthage/Build/iOS",
|
||||
);
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
INFOPLIST_FILE = "Supporting Files/Info-Tests.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.lukaskubanek.OrderedDictionary-iOS-Tests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.lukaskubanek.OrderedDictionary-iOSTests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
@@ -650,50 +653,52 @@
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
803F9CC01B923207002F728F /* Build configuration list for PBXProject "OrderedDictionary" */ = {
|
||||
8055B0321E201C5D009DC3EE /* Build configuration list for PBXProject "OrderedDictionary" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
803F9CCC1B923207002F728F /* Debug */,
|
||||
803F9CCD1B923207002F728F /* Release */,
|
||||
8055B04A1E201C5D009DC3EE /* Debug */,
|
||||
8055B04B1E201C5D009DC3EE /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
803F9CCE1B923207002F728F /* Build configuration list for PBXNativeTarget "OrderedDictionary-OSX" */ = {
|
||||
8055B04C1E201C5D009DC3EE /* Build configuration list for PBXNativeTarget "OrderedDictionary-Mac" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
803F9CCF1B923207002F728F /* Debug */,
|
||||
803F9CD01B923207002F728F /* Release */,
|
||||
8055B04D1E201C5D009DC3EE /* Debug */,
|
||||
8055B04E1E201C5D009DC3EE /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
803F9CF71B925B1C002F728F /* Build configuration list for PBXNativeTarget "OrderedDictionary-OSX-Tests" */ = {
|
||||
8055B04F1E201C5D009DC3EE /* Build configuration list for PBXNativeTarget "OrderedDictionary-Mac-Tests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
803F9CF81B925B1C002F728F /* Debug */,
|
||||
803F9CF91B925B1C002F728F /* Release */,
|
||||
8055B0501E201C5D009DC3EE /* Debug */,
|
||||
8055B0511E201C5D009DC3EE /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
806097681B92F20400DB20CF /* Build configuration list for PBXNativeTarget "OrderedDictionary-iOS" */ = {
|
||||
80B28EA81E201EC9007E3A77 /* Build configuration list for PBXNativeTarget "OrderedDictionary-iOS" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
806097691B92F20400DB20CF /* Debug */,
|
||||
8060976A1B92F20400DB20CF /* Release */,
|
||||
80B28EA91E201EC9007E3A77 /* Debug */,
|
||||
80B28EAA1E201EC9007E3A77 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
806097791B92F44F00DB20CF /* Build configuration list for PBXNativeTarget "OrderedDictionary-iOS-Tests" */ = {
|
||||
80B28EAB1E201EC9007E3A77 /* Build configuration list for PBXNativeTarget "OrderedDictionary-iOS-Tests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
8060977A1B92F44F00DB20CF /* Debug */,
|
||||
8060977B1B92F44F00DB20CF /* Release */,
|
||||
80B28EAC1E201EC9007E3A77 /* Debug */,
|
||||
80B28EAD1E201EC9007E3A77 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 803F9CBD1B923207002F728F /* Project object */;
|
||||
rootObject = 8055B02F1E201C5D009DC3EE /* Project object */;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
+13
-14
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
LastUpgradeVersion = "1020"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -14,9 +14,9 @@
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "803F9CC51B923207002F728F"
|
||||
BlueprintIdentifier = "8055B0371E201C5D009DC3EE"
|
||||
BuildableName = "OrderedDictionary.framework"
|
||||
BlueprintName = "OrderedDictionary-OSX"
|
||||
BlueprintName = "OrderedDictionary-Mac"
|
||||
ReferencedContainer = "container:OrderedDictionary.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
@@ -26,16 +26,15 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
codeCoverageEnabled = "YES">
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "803F9CEE1B925B1C002F728F"
|
||||
BuildableName = "OrderedDictionary-OSX-Tests.xctest"
|
||||
BlueprintName = "OrderedDictionary-OSX-Tests"
|
||||
BlueprintIdentifier = "8055B0401E201C5D009DC3EE"
|
||||
BuildableName = "OrderedDictionary_Mac_Tests.xctest"
|
||||
BlueprintName = "OrderedDictionary-Mac-Tests"
|
||||
ReferencedContainer = "container:OrderedDictionary.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
@@ -43,9 +42,9 @@
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "803F9CC51B923207002F728F"
|
||||
BlueprintIdentifier = "8055B0371E201C5D009DC3EE"
|
||||
BuildableName = "OrderedDictionary.framework"
|
||||
BlueprintName = "OrderedDictionary-OSX"
|
||||
BlueprintName = "OrderedDictionary-Mac"
|
||||
ReferencedContainer = "container:OrderedDictionary.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
@@ -65,9 +64,9 @@
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "803F9CC51B923207002F728F"
|
||||
BlueprintIdentifier = "8055B0371E201C5D009DC3EE"
|
||||
BuildableName = "OrderedDictionary.framework"
|
||||
BlueprintName = "OrderedDictionary-OSX"
|
||||
BlueprintName = "OrderedDictionary-Mac"
|
||||
ReferencedContainer = "container:OrderedDictionary.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
@@ -83,9 +82,9 @@
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "803F9CC51B923207002F728F"
|
||||
BlueprintIdentifier = "8055B0371E201C5D009DC3EE"
|
||||
BuildableName = "OrderedDictionary.framework"
|
||||
BlueprintName = "OrderedDictionary-OSX"
|
||||
BlueprintName = "OrderedDictionary-Mac"
|
||||
ReferencedContainer = "container:OrderedDictionary.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
LastUpgradeVersion = "1020"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -14,7 +14,7 @@
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "806097621B92F20400DB20CF"
|
||||
BlueprintIdentifier = "80B28E961E201EC8007E3A77"
|
||||
BuildableName = "OrderedDictionary.framework"
|
||||
BlueprintName = "OrderedDictionary-iOS"
|
||||
ReferencedContainer = "container:OrderedDictionary.xcodeproj">
|
||||
@@ -26,15 +26,14 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
codeCoverageEnabled = "YES">
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "806097701B92F44F00DB20CF"
|
||||
BuildableName = "OrderedDictionary-iOS-Tests.xctest"
|
||||
BlueprintIdentifier = "80B28E9E1E201EC9007E3A77"
|
||||
BuildableName = "OrderedDictionary_iOS_Tests.xctest"
|
||||
BlueprintName = "OrderedDictionary-iOS-Tests"
|
||||
ReferencedContainer = "container:OrderedDictionary.xcodeproj">
|
||||
</BuildableReference>
|
||||
@@ -43,7 +42,7 @@
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "806097621B92F20400DB20CF"
|
||||
BlueprintIdentifier = "80B28E961E201EC8007E3A77"
|
||||
BuildableName = "OrderedDictionary.framework"
|
||||
BlueprintName = "OrderedDictionary-iOS"
|
||||
ReferencedContainer = "container:OrderedDictionary.xcodeproj">
|
||||
@@ -65,7 +64,7 @@
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "806097621B92F20400DB20CF"
|
||||
BlueprintIdentifier = "80B28E961E201EC8007E3A77"
|
||||
BuildableName = "OrderedDictionary.framework"
|
||||
BlueprintName = "OrderedDictionary-iOS"
|
||||
ReferencedContainer = "container:OrderedDictionary.xcodeproj">
|
||||
@@ -83,7 +82,7 @@
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "806097621B92F20400DB20CF"
|
||||
BlueprintIdentifier = "80B28E961E201EC8007E3A77"
|
||||
BuildableName = "OrderedDictionary.framework"
|
||||
BlueprintName = "OrderedDictionary-iOS"
|
||||
ReferencedContainer = "container:OrderedDictionary.xcodeproj">
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// swift-tools-version:4
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "OrderedDictionary",
|
||||
products: [
|
||||
.library(
|
||||
name: "OrderedDictionary",
|
||||
targets: ["OrderedDictionary"]
|
||||
)
|
||||
],
|
||||
dependencies: [],
|
||||
targets: [
|
||||
.target(
|
||||
name: "OrderedDictionary",
|
||||
dependencies: [],
|
||||
path: "Sources"
|
||||
),
|
||||
.testTarget(
|
||||
name: "OrderedDictionaryTests",
|
||||
dependencies: ["OrderedDictionary"],
|
||||
path: "Tests"
|
||||
)
|
||||
],
|
||||
swiftLanguageVersions: [4]
|
||||
)
|
||||
@@ -0,0 +1,27 @@
|
||||
// swift-tools-version:4.2
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "OrderedDictionary",
|
||||
products: [
|
||||
.library(
|
||||
name: "OrderedDictionary",
|
||||
targets: ["OrderedDictionary"]
|
||||
)
|
||||
],
|
||||
dependencies: [],
|
||||
targets: [
|
||||
.target(
|
||||
name: "OrderedDictionary",
|
||||
dependencies: [],
|
||||
path: "Sources"
|
||||
),
|
||||
.testTarget(
|
||||
name: "OrderedDictionaryTests",
|
||||
dependencies: ["OrderedDictionary"],
|
||||
path: "Tests"
|
||||
)
|
||||
],
|
||||
swiftLanguageVersions: [.v4, .v4_2]
|
||||
)
|
||||
@@ -0,0 +1,27 @@
|
||||
// swift-tools-version:5.0
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "OrderedDictionary",
|
||||
products: [
|
||||
.library(
|
||||
name: "OrderedDictionary",
|
||||
targets: ["OrderedDictionary"]
|
||||
)
|
||||
],
|
||||
dependencies: [],
|
||||
targets: [
|
||||
.target(
|
||||
name: "OrderedDictionary",
|
||||
dependencies: [],
|
||||
path: "Sources"
|
||||
),
|
||||
.testTarget(
|
||||
name: "OrderedDictionaryTests",
|
||||
dependencies: ["OrderedDictionary"],
|
||||
path: "Tests"
|
||||
)
|
||||
],
|
||||
swiftLanguageVersions: [.v5]
|
||||
)
|
||||
@@ -0,0 +1,49 @@
|
||||
import Foundation
|
||||
import OrderedDictionary
|
||||
|
||||
let orderedDictionary1: OrderedDictionary<String, Int> = [
|
||||
"A": 42,
|
||||
"B": 100,
|
||||
"C": 11
|
||||
]
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - JSON Encoding & Decoding
|
||||
// ======================================================= //
|
||||
|
||||
let jsonEncoder = JSONEncoder()
|
||||
let jsonData = try! jsonEncoder.encode(orderedDictionary1)
|
||||
let jsonString = String(data: jsonData, encoding: .utf8)
|
||||
|
||||
let jsonDecoder = JSONDecoder()
|
||||
let orderedDictionary2 = try! jsonDecoder.decode(OrderedDictionary<String, Int>.self, from: jsonData)
|
||||
|
||||
orderedDictionary1 == orderedDictionary2
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Property List Encoding & Decoding
|
||||
// ======================================================= //
|
||||
|
||||
let plistEncoder = PropertyListEncoder()
|
||||
let plistData = try! plistEncoder.encode(orderedDictionary1)
|
||||
|
||||
let plistDecoder = PropertyListDecoder()
|
||||
let orderedDictionary3 = try! plistDecoder.decode(OrderedDictionary<String, Int>.self, from: plistData)
|
||||
|
||||
orderedDictionary1 == orderedDictionary3
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Non-codable Type
|
||||
// ======================================================= //
|
||||
|
||||
struct NonCodableType {
|
||||
var string: String
|
||||
}
|
||||
|
||||
let orderedDictionary4: OrderedDictionary<String, NonCodableType> = [
|
||||
"A" : NonCodableType(string: "Foo"),
|
||||
"B" : NonCodableType(string: "Bar"),
|
||||
"C" : NonCodableType(string: "Baz")
|
||||
]
|
||||
|
||||
//try? jsonEncoder.encode(x)
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<playground version='5.0' target-platform='macos'>
|
||||
<timeline fileName='timeline.xctimeline'/>
|
||||
</playground>
|
||||
@@ -1,65 +1,134 @@
|
||||
import OrderedDictionary
|
||||
|
||||
////
|
||||
// Initialize an ordered dictionary using an array of key-value pairs
|
||||
////
|
||||
// ======================================================= //
|
||||
// Helpers
|
||||
// ======================================================= //
|
||||
|
||||
var orderedDictionary: OrderedDictionary<String, Int> = [
|
||||
("A", 1),
|
||||
("B", 2),
|
||||
("C", 3),
|
||||
("D", 4)
|
||||
]
|
||||
|
||||
print(orderedDictionary) // => [A: 1, B: 2, C: 3, D: 4]
|
||||
|
||||
////
|
||||
// Loop through the contents
|
||||
////
|
||||
|
||||
for (index, (key, value)) in orderedDictionary.enumerate() {
|
||||
print("\(index): (\(key): \(value))")
|
||||
func print(_ optional: Any?) {
|
||||
print(optional as Any)
|
||||
}
|
||||
|
||||
// => 0: (A: 1)
|
||||
// => 1: (B: 2)
|
||||
// => 2: (C: 3)
|
||||
// => 3: (D: 4)
|
||||
// ======================================================= //
|
||||
// Construction
|
||||
// ======================================================= //
|
||||
|
||||
////
|
||||
// Modify the values by setting the value for key
|
||||
////
|
||||
// Construct an ordered dictionary using a dictionary literal
|
||||
var orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3, "D": 4]
|
||||
|
||||
// Output the ordered dictionary
|
||||
print(orderedDictionary) // => [A: 1, B: 2, C: 3, D: 4]
|
||||
|
||||
// ======================================================= //
|
||||
// Enumeration
|
||||
// ======================================================= //
|
||||
|
||||
// Loop through the ordered dictionary
|
||||
for (key, value) in orderedDictionary {
|
||||
print("[\(key): \(value)]") // => [A: 1], => [B: 2], => [C: 3], => [D: 4]
|
||||
}
|
||||
|
||||
// Loop through the ordered dictionary with an additional index
|
||||
for (index, element) in orderedDictionary.enumerated() {
|
||||
print("(\(index): [\(element.key): \(element.value)])") // => (0: [A: 1]), => (1: [B: 2]), => (2: [C: 3]), => (3: [D: 4])
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// Acessing Content
|
||||
// ======================================================= //
|
||||
|
||||
// Access the value for an existing key using the subscript
|
||||
print(orderedDictionary["A"]) // => Optional(1)
|
||||
|
||||
// Access the value for a non-existent key using the subscript
|
||||
print(orderedDictionary["X"]) // => nil
|
||||
|
||||
// Access the value for a key using the method
|
||||
print(orderedDictionary.value(forKey: "A")) // => Optional(1)
|
||||
|
||||
// Access the value for a non-existent key using the method
|
||||
print(orderedDictionary.value(forKey: "X")) // => nil
|
||||
|
||||
// Access the key-value pair (element) at an existing index
|
||||
print(orderedDictionary[2]) // => ("C", 3)
|
||||
|
||||
// Access the key-value pair (element) at a non-existent index
|
||||
//print(orderedDictionary[10]) // => fatal error
|
||||
|
||||
// Get the index for an existing key
|
||||
print(orderedDictionary.index(forKey: "D")) // => Optional(3)
|
||||
|
||||
// ======================================================= //
|
||||
// Modifying Content Using Keys
|
||||
// ======================================================= //
|
||||
|
||||
// Modify the value for an existing key using the subscript
|
||||
orderedDictionary["A"] = 100
|
||||
orderedDictionary["E"] = 5
|
||||
orderedDictionary["B"] = nil
|
||||
orderedDictionary.updateValue(42, forKey: "D")
|
||||
print(orderedDictionary["A"]) // => Optional(100)
|
||||
|
||||
// Modify the value for an existing key using the method
|
||||
orderedDictionary.updateValue(42, forKey: "D")
|
||||
print(orderedDictionary["D"]) // => Optional(42)
|
||||
|
||||
// Append a new key-value pair by setting a value for an non-existent key
|
||||
orderedDictionary["E"] = 5
|
||||
print(orderedDictionary) // => [A: 100, B: 2, C: 3, D: 42, E: 5]
|
||||
|
||||
// Remove a key-value pair by setting `nil` value for an existing key
|
||||
orderedDictionary["B"] = nil
|
||||
print(orderedDictionary["B"]) // => nil
|
||||
print(orderedDictionary) // => [A: 100, C: 3, D: 42, E: 5]
|
||||
|
||||
print(orderedDictionary["A"]) // => Optional(100)
|
||||
print(orderedDictionary["B"]) // => nil
|
||||
print(orderedDictionary["C"]) // => Optional(3)
|
||||
print(orderedDictionary["D"]) // => Optional(42)
|
||||
print(orderedDictionary["E"]) // => Optional(5)
|
||||
// ======================================================= //
|
||||
// Modifying Content Using Indexes
|
||||
// ======================================================= //
|
||||
|
||||
////
|
||||
// Modify the values by setting the element for index
|
||||
////
|
||||
// Modify an element at an existing index
|
||||
let replacedElement = orderedDictionary.update(("F", 235), at: 2)
|
||||
print(orderedDictionary[2]) // => ("F", 235)
|
||||
print(orderedDictionary) // => [A: 100, C: 3, F: 235, E: 5]
|
||||
print(replacedElement) // => Optional("D", 42)
|
||||
|
||||
orderedDictionary[2] = ("F", 235)
|
||||
orderedDictionary.updateElement(("K", 12), atIndex: 1)
|
||||
orderedDictionary.removeAtIndex(0)
|
||||
// Modify an element at a non-existent index
|
||||
//orderedDictionary.update(("L", 0), at: 100) // => fatal error
|
||||
|
||||
print(orderedDictionary) // => [K: 12, F: 235, E: 5]
|
||||
// ======================================================= //
|
||||
// Sorting
|
||||
// ======================================================= //
|
||||
|
||||
print(orderedDictionary[0]) // => ("K", 12)
|
||||
print(orderedDictionary[1]) // => ("F", 235)
|
||||
print(orderedDictionary[2]) // => ("E", 5)
|
||||
// print(orderedDictionary[3]) // => fatal error
|
||||
// Sort the ordered dictionary using a closure
|
||||
orderedDictionary.sort {
|
||||
if $0.value == $1.value {
|
||||
return $0.key < $1.key
|
||||
} else {
|
||||
return $0.value < $1.value
|
||||
}
|
||||
}
|
||||
|
||||
print(orderedDictionary.indexForKey("K")) // => Optional(0)
|
||||
print(orderedDictionary.indexForKey("F")) // => Optional(1)
|
||||
print(orderedDictionary.indexForKey("E")) // => Optional(2)
|
||||
print(orderedDictionary.indexForKey("A")) // => nil
|
||||
print(orderedDictionary.indexForKey("C")) // => nil
|
||||
print(orderedDictionary) // => [C: 3, E: 5, A: 100, F: 235]
|
||||
|
||||
// ======================================================= //
|
||||
// Removing Content
|
||||
// ======================================================= //
|
||||
|
||||
// Remove value for an existing key
|
||||
let removedValue = orderedDictionary.removeValue(forKey: "F")
|
||||
print(removedValue) // => Optional(235)
|
||||
print(orderedDictionary["F"]) // => nil
|
||||
print(orderedDictionary) // => [C: 3, E: 5, A: 100]
|
||||
|
||||
// Remove value for a non-existent key
|
||||
orderedDictionary.removeValue(forKey: "X")
|
||||
print(orderedDictionary) // => [C: 3, E: 5, A: 100]
|
||||
|
||||
// Remove element at an existing index
|
||||
let removedElement = orderedDictionary.remove(at: 1)
|
||||
print(removedElement) // => Optional((E, 5))
|
||||
print(orderedDictionary) // => [C: 3, A: 100]
|
||||
|
||||
// Remove element at a non-existent index
|
||||
orderedDictionary.remove(at: 42)
|
||||
print(orderedDictionary) // => [C: 3, A: 100]
|
||||
|
||||
// Remove all elements
|
||||
orderedDictionary.removeAll()
|
||||
print(orderedDictionary) // => [:]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<playground version='5.0' target-platform='osx' requires-full-environment='true'>
|
||||
<playground version='5.0' target-platform='osx'>
|
||||
<timeline fileName='timeline.xctimeline'/>
|
||||
</playground>
|
||||
@@ -1,126 +1,64 @@
|
||||
# OrderedDictionary
|
||||
|
||||
[![][image-1]][1] [![][image-2]][2] [![][image-3]][3] ![][image-4] [![][image-5]][4] [![][image-6]][5]
|
||||
[](https://travis-ci.org/lukaskubanek/OrderedDictionary) [](https://github.com/lukaskubanek/OrderedDictionary/releases) [](https://developer.apple.com/swift/ "Swift 4")  [](https://github.com/Carthage/Carthage)
|
||||
[](https://github.com/Carthage/Carthage) [](LICENSE.md)
|
||||
|
||||
This is a lightweight implementation of an ordered dictionary data structure in Swift packed into a µframework.
|
||||
**OrderedDictionary** is a lightweight implementation of an ordered dictionary data structure in Swift.
|
||||
|
||||
`OrderedDictionary` is an immutable generic collection which combines the features of `Dictionary` and `Array`. Like `Dictionary` it stores key-value pairs and maps the keys to values. Additionally these pairs are sorted by zero-based integer index like in `Array`. The `OrderedDictionary` provides similar APIs to the collections from the Swift standard library and allows accessing the content by keys or indexes.
|
||||
The `OrderedDictionary` struct is a generic collection which combines the features of `Dictionary` and `Array` from the Swift standard library. Like `Dictionary` it stores key-value pairs with each key being unique and maps each key to an associated value. Like `Array` it stores those pairs sorted and accessible by a zero-based integer index.
|
||||
|
||||
Internally `OrderedDictionary` uses a backing store composed of an instance of `Dictionary` for storing the key-value pairs and an instance of `Array` for managing the ordered keys.
|
||||
`OrderedDictionary` provides similar APIs like collections from the Swift standard library. This includes accessing contents by keys or indices, inserting and removing elements, iterating, sorting etc.
|
||||
|
||||
Internally, `OrderedDictionary` uses a backing store composed of an instance of `Dictionary` for storing the key-value pairs and an instance of `Array` for managing the ordered keys. This means it is not the most performant implementation possible, but it gets its job done by reusing most functionality from the Swift standard library.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Swift 2.0
|
||||
- Xcode 7.0 GM
|
||||
- iOS 8.0+ / OS X 10.10+
|
||||
- Swift 4.0, 4.2, 5.0
|
||||
- Xcode 9.2+
|
||||
- iOS 8.0+ / macOS 10.10+
|
||||
|
||||
## Installation
|
||||
|
||||
The easiest way to integrate `OrderedDictionary` to your project is to use [Carthage][6]. Add following line to your `Cartfile`:
|
||||
The library is distributed as a Swift framework and can be integrated into your project in following ways:
|
||||
|
||||
```
|
||||
github "lukaskubanek/OrderedDictionary" ~> 0.3
|
||||
#### Carthage
|
||||
|
||||
If you use [Carthage](https://github.com/Carthage/Carthage) for managing your dependencies, put OrderedDictionary into your `Cartfile`:
|
||||
|
||||
```plain
|
||||
github "lukaskubanek/OrderedDictionary"
|
||||
```
|
||||
|
||||
Then drag the `OrderedDictionary.xcodeproj` or the `OrderedDictionary.framework` into your project/workspace and link against the `OrderedDictionary.framework`.
|
||||
Then, drag either the `OrderedDictionary.xcodeproj` or the `OrderedDictionary.framework` into your project/workspace and link your target against the `OrderedDictionary.framework`. Also make sure that the framework [gets copied](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application) to your application bundle.
|
||||
|
||||
Finally make sure the framework gets copied into your application bundle.
|
||||
#### Swift Package Manager
|
||||
|
||||
## Example Usage
|
||||
Another option is to use the [Swift Package Manager](https://swift.org/package-manager/). If you prefer this option, put OrderedDictionary as a dependency to your `Package.swift`:
|
||||
|
||||
```swift
|
||||
import OrderedDictionary
|
||||
|
||||
////
|
||||
// Initialize an ordered dictionary using an array of key-value pairs
|
||||
////
|
||||
|
||||
var orderedDictionary: OrderedDictionary<String, Int> = [
|
||||
("A", 1),
|
||||
("B", 2),
|
||||
("C", 3),
|
||||
("D", 4)
|
||||
]
|
||||
|
||||
print(orderedDictionary) // => [A: 1, B: 2, C: 3, D: 4]
|
||||
|
||||
////
|
||||
// Loop through the contents
|
||||
////
|
||||
|
||||
for (index, (key, value)) in orderedDictionary.enumerate() {
|
||||
print("\(index): (\(key): \(value))")
|
||||
}
|
||||
|
||||
// => 0: (A: 1)
|
||||
// => 1: (B: 2)
|
||||
// => 2: (C: 3)
|
||||
// => 3: (D: 4)
|
||||
|
||||
////
|
||||
// Modify the values by setting the value for key
|
||||
////
|
||||
|
||||
orderedDictionary["A"] = 100
|
||||
orderedDictionary["E"] = 5
|
||||
orderedDictionary["B"] = nil
|
||||
orderedDictionary.updateValue(42, forKey: "D")
|
||||
|
||||
print(orderedDictionary) // => [A: 100, C: 3, D: 42, E: 5]
|
||||
|
||||
print(orderedDictionary["A"]) // => Optional(100)
|
||||
print(orderedDictionary["B"]) // => nil
|
||||
print(orderedDictionary["C"]) // => Optional(3)
|
||||
print(orderedDictionary["D"]) // => Optional(42)
|
||||
print(orderedDictionary["E"]) // => Optional(5)
|
||||
|
||||
////
|
||||
// Modify the values by setting the element for index
|
||||
////
|
||||
|
||||
orderedDictionary[2] = ("F", 235)
|
||||
orderedDictionary.updateElement(("K", 12), atIndex: 1)
|
||||
orderedDictionary.removeAtIndex(0)
|
||||
|
||||
print(orderedDictionary) // => [K: 12, F: 235, E: 5]
|
||||
|
||||
print(orderedDictionary[0]) // => ("K", 12)
|
||||
print(orderedDictionary[1]) // => ("F", 235)
|
||||
print(orderedDictionary[2]) // => ("E", 5)
|
||||
// print(orderedDictionary[3]) // => fatal error
|
||||
|
||||
print(orderedDictionary.indexForKey("K")) // => Optional(0)
|
||||
print(orderedDictionary.indexForKey("F")) // => Optional(1)
|
||||
print(orderedDictionary.indexForKey("E")) // => Optional(2)
|
||||
print(orderedDictionary.indexForKey("A")) // => nil
|
||||
print(orderedDictionary.indexForKey("C")) // => nil
|
||||
```plain
|
||||
.package(url: "https://github.com/lukaskubanek/OrderedDictionary.git", from: "2.2.2")
|
||||
```
|
||||
|
||||
#### Git Submodules
|
||||
|
||||
Yet another option is using [Git submodules](http://git-scm.com/book/en/v2/Git-Tools-Submodules) and integrating the Xcode project `OrderedDictionary.xcodeproj` from the submodule directly to your Xcode workspace.
|
||||
|
||||
#### ⚠️ Note About CocoaPods
|
||||
|
||||
Although there is high demand for [CocoaPods](https://cocoapods.org) support, this method won't be officially supported by this library. Since I'm not using CocoaPods myself and since I think this method will be once replaced by the Swift Package Manager, I don't want to put any effort in maintaining an official podspec. If you really want to include this library via CocoaPods, there is still a way by creating a custom podspec (see the last section of [this post](https://guides.cocoapods.org/syntax/podfile.html#pod)).
|
||||
|
||||
## Usage & Docs
|
||||
|
||||
For the usage of this library please refer to [the example playground](Playgrounds/OrderedDictionary.playground/Contents.swift). For documentation please refer to [the documentation comments](Sources/OrderedDictionary.swift).
|
||||
|
||||
## Changelog
|
||||
|
||||
The changelog is managed on the [GitHub releases page](https://github.com/lukaskubanek/OrderedDictionary/releases).
|
||||
|
||||
## Author
|
||||
|
||||
Lukas Kubanek // [lukaskubanek.com][11] // [@kubanekl][12]
|
||||
Lukas Kubanek // [lukaskubanek.com](http://lukaskubanek.com) // [@kubanekl](https://twitter.com/kubanekl)
|
||||
|
||||
## License
|
||||
|
||||
`OrderedDictionary` is released under the [MIT License][13].
|
||||
|
||||
[1]: https://travis-ci.org/lukaskubanek/OrderedDictionary
|
||||
[2]: https://github.com/lukaskubanek/OrderedDictionary/releases
|
||||
[3]: https://developer.apple.com/swift/
|
||||
[4]: https://github.com/Carthage/Carthage
|
||||
[5]: LICENSE.md
|
||||
[6]: https://github.com/Carthage/Carthage/
|
||||
[7]: https://developer.apple.com/swift/
|
||||
[8]: https://github.com/lukaskubanek/OrderedDictionary/releases
|
||||
[9]: https://developer.apple.com/swift/
|
||||
[10]: https://github.com/Carthage/Carthage
|
||||
[11]: http://lukaskubanek.com
|
||||
[12]: https://twitter.com/kubanekl
|
||||
[13]: LICENSE.md
|
||||
|
||||
[image-1]: https://img.shields.io/travis/lukaskubanek/OrderedDictionary.svg?style=flat-square
|
||||
[image-2]: https://img.shields.io/github/release/lukaskubanek/OrderedDictionary.svg?style=flat-square
|
||||
[image-3]: https://img.shields.io/badge/Swift-2.0-orange.svg?style=flat-square
|
||||
[image-4]: https://img.shields.io/badge/platform-OS_X%20&_iOS-yellowgreen.svg?style=flat-square
|
||||
[image-5]: https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat-square "Carthage compatible"
|
||||
[image-6]: https://img.shields.io/badge/license-MIT-lightgrey.svg?style=flat-square "License"
|
||||
**OrderedDictionary** is provided under the [MIT License](LICENSE.md).
|
||||
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script was taken from the ReactiveSwift repository.
|
||||
# https://github.com/ReactiveCocoa/ReactiveSwift/blob/master/script/build
|
||||
|
||||
BUILD_DIRECTORY="build"
|
||||
CONFIGURATION="Release"
|
||||
|
||||
if [[ -z $TRAVIS_XCODE_PROJECT ]]; then
|
||||
echo "Error: \$TRAVIS_XCODE_PROJECT is not set."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z $TRAVIS_XCODE_SCHEME ]]; then
|
||||
echo "Error: \$TRAVIS_XCODE_SCHEME is not set."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z $XCODE_ACTION ]]; then
|
||||
echo "Error: \$XCODE_ACTION is not set."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z $XCODE_SDK ]]; then
|
||||
echo "Error: \$XCODE_SDK is not set."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z $XCODE_DESTINATION ]]; then
|
||||
echo "Error: \$XCODE_DESTINATION is not set."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -o pipefail
|
||||
xcodebuild $XCODE_ACTION \
|
||||
-project "$TRAVIS_XCODE_PROJECT" \
|
||||
-scheme "$TRAVIS_XCODE_SCHEME" \
|
||||
-sdk "$XCODE_SDK" \
|
||||
-destination "$XCODE_DESTINATION" \
|
||||
-derivedDataPath "${BUILD_DIRECTORY}" \
|
||||
-configuration $CONFIGURATION \
|
||||
ENABLE_TESTABILITY=YES \
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS=NO \
|
||||
RUN_CLANG_STATIC_ANALYZER=NO | xcpretty
|
||||
result=$?
|
||||
|
||||
if [ "$result" -ne 0 ]; then
|
||||
exit $result
|
||||
fi
|
||||
|
||||
if [[ $XCODE_SDK = "macosx" ]]; then
|
||||
echo "SDK is ${XCODE_SDK}, validating playground..."
|
||||
. Scripts/validate-playgrounds.sh
|
||||
fi
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ -z $BUILD_DIRECTORY ]]; then
|
||||
echo "Error: \$BUILD_DIRECTORY is not set."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z $XCODE_PLAYGROUND_TARGET ]]; then
|
||||
echo "Error: \$XCODE_PLAYGROUND_TARGET is not set."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PAGES_PATH=Playgrounds/OrderedDictionary.playground/Contents.swift
|
||||
|
||||
swift -v -target ${XCODE_PLAYGROUND_TARGET} \
|
||||
-D NOT_IN_PLAYGROUND \
|
||||
-F ${BUILD_DIRECTORY}/Build/Products/${CONFIGURATION} ${PAGES_PATH} > /dev/null
|
||||
|
||||
result=$?
|
||||
|
||||
rm -Rf ${BUILD_DIRECTORY}
|
||||
|
||||
exit $result
|
||||
@@ -0,0 +1,136 @@
|
||||
#if swift(>=4.1)
|
||||
|
||||
extension OrderedDictionary: Encodable where Key: Encodable, Value: Encodable {
|
||||
|
||||
/// __inheritdoc__
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
// Encode the ordered dictionary as an array of alternating key-value pairs.
|
||||
var container = encoder.unkeyedContainer()
|
||||
|
||||
for (key, value) in self {
|
||||
try container.encode(key)
|
||||
try container.encode(value)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension OrderedDictionary: Decodable where Key: Decodable, Value: Decodable {
|
||||
|
||||
/// __inheritdoc__
|
||||
public init(from decoder: Decoder) throws {
|
||||
// Decode the ordered dictionary from an array of alternating key-value pairs.
|
||||
self.init()
|
||||
|
||||
var container = try decoder.unkeyedContainer()
|
||||
|
||||
while !container.isAtEnd {
|
||||
let key = try container.decode(Key.self)
|
||||
guard !container.isAtEnd else { throw DecodingError.unkeyedContainerReachedEndBeforeValue(decoder.codingPath) }
|
||||
let value = try container.decode(Value.self)
|
||||
|
||||
self[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
extension OrderedDictionary: Encodable {
|
||||
|
||||
/// __inheritdoc__
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
// Since Swift 4.0 lacks the protocol conditional conformance support, we have to make the
|
||||
// whole OrderedDictionary type conform to Encodable and assert that the key and value
|
||||
// types conform to Encodable. Furthermore, we leverage a trick of super encoders to be
|
||||
// able to encode objects without knowing their exact types. This trick was used in the
|
||||
// standard library for encoding/decoding Dictionary before Swift 4.1.
|
||||
|
||||
_assertTypeIsEncodable(Key.self, in: type(of: self))
|
||||
_assertTypeIsEncodable(Value.self, in: type(of: self))
|
||||
|
||||
var container = encoder.unkeyedContainer()
|
||||
|
||||
for (key, value) in self {
|
||||
let keyEncoder = container.superEncoder()
|
||||
try (key as! Encodable).encode(to: keyEncoder)
|
||||
|
||||
let valueEncoder = container.superEncoder()
|
||||
try (value as! Encodable).encode(to: valueEncoder)
|
||||
}
|
||||
}
|
||||
|
||||
private func _assertTypeIsEncodable<T>(_ type: T.Type, in wrappingType: Any.Type) {
|
||||
guard T.self is Encodable.Type else {
|
||||
if T.self == Encodable.self || T.self == Codable.self {
|
||||
preconditionFailure("\(wrappingType) does not conform to Encodable because Encodable does not conform to itself. You must use a concrete type to encode or decode.")
|
||||
} else {
|
||||
preconditionFailure("\(wrappingType) does not conform to Encodable because \(T.self) does not conform to Encodable.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension OrderedDictionary: Decodable {
|
||||
|
||||
/// __inheritdoc__
|
||||
public init(from decoder: Decoder) throws {
|
||||
// Since Swift 4.0 lacks the protocol conditional conformance support, we have to make the
|
||||
// whole OrderedDictionary type conform to Decodable and assert that the key and value
|
||||
// types conform to Decodable. Furthermore, we leverage a trick of super decoders to be
|
||||
// able to decode objects without knowing their exact types. This trick was used in the
|
||||
// standard library for encoding/decoding Dictionary before Swift 4.1.
|
||||
|
||||
self.init()
|
||||
|
||||
_assertTypeIsDecodable(Key.self, in: type(of: self))
|
||||
_assertTypeIsDecodable(Value.self, in: type(of: self))
|
||||
|
||||
var container = try decoder.unkeyedContainer()
|
||||
|
||||
let keyMetaType = (Key.self as! Decodable.Type)
|
||||
let valueMetaType = (Value.self as! Decodable.Type)
|
||||
|
||||
while !container.isAtEnd {
|
||||
let keyDecoder = try container.superDecoder()
|
||||
let key = try keyMetaType.init(from: keyDecoder) as! Key
|
||||
|
||||
guard !container.isAtEnd else { throw DecodingError.unkeyedContainerReachedEndBeforeValue(decoder.codingPath) }
|
||||
|
||||
let valueDecoder = try container.superDecoder()
|
||||
let value = try valueMetaType.init(from: valueDecoder) as! Value
|
||||
|
||||
self[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
private func _assertTypeIsDecodable<T>(_ type: T.Type, in wrappingType: Any.Type) {
|
||||
guard T.self is Decodable.Type else {
|
||||
if T.self == Decodable.self || T.self == Codable.self {
|
||||
preconditionFailure("\(wrappingType) does not conform to Decodable because Decodable does not conform to itself. You must use a concrete type to encode or decode.")
|
||||
} else {
|
||||
preconditionFailure("\(wrappingType) does not conform to Decodable because \(T.self) does not conform to Decodable.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
extension DecodingError {
|
||||
|
||||
fileprivate static func unkeyedContainerReachedEndBeforeValue(
|
||||
_ codingPath: [CodingKey]
|
||||
) -> DecodingError {
|
||||
return DecodingError.dataCorrupted(
|
||||
DecodingError.Context(
|
||||
codingPath: codingPath,
|
||||
debugDescription: "Unkeyed container reached end before value in key-value pair."
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
extension OrderedDictionary: CustomStringConvertible {
|
||||
|
||||
/// A textual representation of the ordered dictionary.
|
||||
public var description: String {
|
||||
return makeDescription(debug: false)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension OrderedDictionary: CustomDebugStringConvertible {
|
||||
|
||||
/// A textual representation of the ordered dictionary, suitable for debugging.
|
||||
public var debugDescription: String {
|
||||
return makeDescription(debug: true)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension OrderedDictionary {
|
||||
|
||||
fileprivate func makeDescription(debug: Bool) -> String {
|
||||
// The implementation of the description is inspired by zwaldowski's implementation of the
|
||||
// ordered dictionary. See https://bit.ly/2RiWfJu
|
||||
|
||||
if isEmpty { return "[:]" }
|
||||
|
||||
let printFunction: (Any, inout String) -> () = {
|
||||
if debug {
|
||||
return { debugPrint($0, separator: "", terminator: "", to: &$1) }
|
||||
} else {
|
||||
return { print($0, separator: "", terminator: "", to: &$1) }
|
||||
}
|
||||
}()
|
||||
|
||||
let descriptionForItem: (Any) -> String = { item in
|
||||
var description = ""
|
||||
printFunction(item, &description)
|
||||
return description
|
||||
}
|
||||
|
||||
let bodyComponents = map { element in
|
||||
return descriptionForItem(element.key) + ": " + descriptionForItem(element.value)
|
||||
}
|
||||
|
||||
let body = bodyComponents.joined(separator: ", ")
|
||||
|
||||
return "[\(body)]"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
//
|
||||
// OrderedDictionary.h
|
||||
// OrderedDictionary
|
||||
//
|
||||
// Created by Lukas Kubanek on 29/08/15.
|
||||
// Copyright © 2015 Lukas Kubanek. All rights reserved.
|
||||
//
|
||||
|
||||
extern double OrderedDictionaryVersionNumber;
|
||||
extern const unsigned char OrderedDictionaryVersionString[];
|
||||
+617
-160
@@ -1,220 +1,677 @@
|
||||
//
|
||||
// OrderedDictionary.swift
|
||||
// OrderedDictionary
|
||||
//
|
||||
// Created by Lukas Kubanek on 29/08/15.
|
||||
// Copyright © 2015 Lukas Kubanek. All rights reserved.
|
||||
//
|
||||
/// A generic collection for storing key-value pairs in an ordered manner.
|
||||
///
|
||||
/// Same as in a dictionary all keys in the collection are unique and have an associated value.
|
||||
/// Same as in an array, all key-value pairs (elements) are kept sorted and accessible by
|
||||
/// a zero-based integer index.
|
||||
public struct OrderedDictionary<Key: Hashable, Value>: BidirectionalCollection {
|
||||
|
||||
public struct OrderedDictionary<Key: Hashable, Value>: CollectionType, ArrayLiteralConvertible, CustomStringConvertible {
|
||||
// ======================================================= //
|
||||
// MARK: - Type Aliases
|
||||
// ======================================================= //
|
||||
|
||||
/// The type of the key-value pair stored in the ordered dictionary.
|
||||
public typealias Element = (key: Key, value: Value)
|
||||
|
||||
/// The type of the index.
|
||||
public typealias Index = Int
|
||||
|
||||
/// The type of the indices collection.
|
||||
public typealias Indices = CountableRange<Int>
|
||||
|
||||
/// The type of the contiguous subrange of the ordered dictionary's elements.
|
||||
///
|
||||
/// - SeeAlso: OrderedDictionarySlice
|
||||
public typealias SubSequence = OrderedDictionarySlice<Key, Value>
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Initialization
|
||||
// ======================================================= //
|
||||
|
||||
public init() {
|
||||
self.orderedKeys = []
|
||||
self.keysToValues = [:]
|
||||
/// Creates an empty ordered dictionary.
|
||||
public init() {}
|
||||
|
||||
/// Creates an ordered dictionary from a sequence of values keyed by a key which gets extracted
|
||||
/// from the value in the provided closure.
|
||||
///
|
||||
/// - Parameter values: The sequence of values.
|
||||
/// - Parameter getKey: The closure which provides a key for the given value from the values
|
||||
/// sequence.
|
||||
public init<Values: Sequence>(
|
||||
values: Values,
|
||||
keyedBy getKey: (Value) -> Key
|
||||
) where Values.Element == Value {
|
||||
self.init(values.map { (getKey($0), $0) })
|
||||
}
|
||||
|
||||
public init(elements: [Element]) {
|
||||
self.init()
|
||||
/// Creates an ordered dictionary from a sequence of values keyed by a key loaded from the value
|
||||
/// at the given key path.
|
||||
///
|
||||
/// - Parameter values: The sequence of values.
|
||||
/// - Parameter keyPath: The key path for the value to locate its key at.
|
||||
public init(values: [Value], keyedBy keyPath: KeyPath<Value, Key>) {
|
||||
self.init(values.map { ($0[keyPath: keyPath], $0) })
|
||||
}
|
||||
|
||||
/// Creates an ordered dictionary from a regular unsorted dictionary by sorting it using the
|
||||
/// the given sort function.
|
||||
///
|
||||
/// - Parameter unsorted: The unsorted dictionary.
|
||||
/// - Parameter areInIncreasingOrder: The sort function which compares the key-value pairs.
|
||||
public init(
|
||||
unsorted: Dictionary<Key, Value>,
|
||||
areInIncreasingOrder: (Element, Element) throws -> Bool
|
||||
) rethrows {
|
||||
let elements = try unsorted
|
||||
.map { (key: $0.key, value: $0.value) }
|
||||
.sorted(by: areInIncreasingOrder)
|
||||
|
||||
for element in elements {
|
||||
self[element.0] = element.1
|
||||
self.init(elements)
|
||||
}
|
||||
|
||||
/// Creates an ordered dictionary from a sequence of key-value pairs.
|
||||
///
|
||||
/// - Parameter elements: The key-value pairs that will make up the new ordered dictionary.
|
||||
/// Each key in `elements` must be unique.
|
||||
public init<S: Sequence>(_ elements: S) where S.Element == Element {
|
||||
for (key, value) in elements {
|
||||
precondition(!containsKey(key), "Elements sequence contains duplicate keys")
|
||||
self[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
public init(arrayLiteral elements: Element...) {
|
||||
self.init(elements: elements)
|
||||
// ======================================================= //
|
||||
// MARK: - Ordered Keys & Values
|
||||
// ======================================================= //
|
||||
|
||||
/// A collection containing just the keys of the ordered dictionary in the correct order.
|
||||
public var orderedKeys: OrderedDictionaryKeys<Key, Value> {
|
||||
return self.lazy.map { $0.key }
|
||||
}
|
||||
|
||||
// MARK: - Type Aliases
|
||||
/// A collection containing just the values of the ordered dictionary in the correct order.
|
||||
public var orderedValues: OrderedDictionaryValues<Key, Value> {
|
||||
return self.lazy.map { $0.value }
|
||||
}
|
||||
|
||||
public typealias Element = (Key, Value)
|
||||
public typealias Index = Int
|
||||
// ======================================================= //
|
||||
// MARK: - Dictionary
|
||||
// ======================================================= //
|
||||
|
||||
// MARK: - Managing Content Using Keys
|
||||
/// Converts itself to a common unsorted dictionary.
|
||||
public var unorderedDictionary: Dictionary<Key, Value> {
|
||||
return _keysToValues
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Indices
|
||||
// ======================================================= //
|
||||
|
||||
/// The indices that are valid for subscripting the ordered dictionary.
|
||||
public var indices: Indices {
|
||||
return _orderedKeys.indices
|
||||
}
|
||||
|
||||
/// The position of the first key-value pair in a non-empty ordered dictionary.
|
||||
public var startIndex: Index {
|
||||
return _orderedKeys.startIndex
|
||||
}
|
||||
|
||||
/// The position which is one greater than the position of the last valid key-value pair in the
|
||||
/// ordered dictionary.
|
||||
public var endIndex: Index {
|
||||
return _orderedKeys.endIndex
|
||||
}
|
||||
|
||||
/// Returns the position immediately after the given index.
|
||||
public func index(after i: Index) -> Index {
|
||||
return _orderedKeys.index(after: i)
|
||||
}
|
||||
|
||||
/// Returns the position immediately before the given index.
|
||||
public func index(before i: Index) -> Index {
|
||||
return _orderedKeys.index(before: i)
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Slices
|
||||
// ======================================================= //
|
||||
|
||||
/// Accesses a contiguous subrange of the ordered dictionary.
|
||||
///
|
||||
/// - Parameter bounds: A range of the ordered dictionary's indices. The bounds of the range
|
||||
/// must be valid indices of the ordered dictionary.
|
||||
/// - Returns: The slice view at the ordered dictionary in the specified subrange.
|
||||
public subscript(bounds: Range<Index>) -> SubSequence {
|
||||
return OrderedDictionarySlice(base: self, bounds: bounds)
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Key-based Access
|
||||
// ======================================================= //
|
||||
|
||||
/// Accesses the value associated with the given key for reading and writing.
|
||||
///
|
||||
/// This key-based subscript returns the value for the given key if the key is found in the
|
||||
/// ordered dictionary, or `nil` if the key is not found.
|
||||
///
|
||||
/// When you assign a value for a key and that key already exists, the ordered dictionary
|
||||
/// overwrites the existing value and preservers the index of the key-value pair. If the ordered
|
||||
/// dictionary does not contain the key, a new key-value pair is appended to the end of the
|
||||
/// ordered dictionary.
|
||||
///
|
||||
/// If you assign `nil` as the value for the given key, the ordered dictionary removes that key
|
||||
/// and its associated value if it exists.
|
||||
///
|
||||
/// - Parameter key: The key to find in the ordered dictionary.
|
||||
/// - Returns: The value associated with `key` if `key` is in the ordered dictionary; otherwise,
|
||||
/// `nil`.
|
||||
public subscript(key: Key) -> Value? {
|
||||
get {
|
||||
return keysToValues[key]
|
||||
return value(forKey: key)
|
||||
}
|
||||
set(newValue) {
|
||||
if let newValue = newValue {
|
||||
updateValue(newValue, forKey: key)
|
||||
} else {
|
||||
removeValueForKey(key)
|
||||
removeValue(forKey: key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func containsKey(key: Key) -> Bool {
|
||||
return orderedKeys.contains(key)
|
||||
/// Returns a Boolean value indicating whether the ordered dictionary contains the given key.
|
||||
///
|
||||
/// - Parameter key: The key to be looked up.
|
||||
/// - Returns: `true` if the ordered dictionary contains the given key; otherwise, `false`.
|
||||
public func containsKey(_ key: Key) -> Bool {
|
||||
return _keysToValues[key] != nil
|
||||
}
|
||||
|
||||
public mutating func updateValue(value: Value, forKey key: Key) -> Value? {
|
||||
if orderedKeys.contains(key) {
|
||||
guard let currentValue = keysToValues[key] else {
|
||||
fatalError("Inconsistency error occured in OrderedDictionary")
|
||||
}
|
||||
/// Returns the value associated with the given key if the key is found in the ordered
|
||||
/// dictionary, or `nil` if the key is not found.
|
||||
///
|
||||
/// - Parameter key: The key to find in the ordered dictionary.
|
||||
/// - Returns: The value associated with `key` if `key` is in the ordered dictionary; otherwise,
|
||||
/// `nil`.
|
||||
public func value(forKey key: Key) -> Value? {
|
||||
return _keysToValues[key]
|
||||
}
|
||||
|
||||
/// Updates the value stored in the ordered dictionary for the given key, or appends a new
|
||||
/// key-value pair if the key does not exist.
|
||||
///
|
||||
/// - Parameter value: The new value to add to the ordered dictionary.
|
||||
/// - Parameter key: The key to associate with `value`. If `key` already exists in the ordered
|
||||
/// dictionary, `value` replaces the existing associated value. If `key` is not already a key
|
||||
/// of the ordered dictionary, the `(key, value)` pair is appended at the end of the ordered
|
||||
/// dictionary.
|
||||
@discardableResult
|
||||
public mutating func updateValue(_ value: Value, forKey key: Key) -> Value? {
|
||||
if containsKey(key) {
|
||||
let currentValue = _unsafeValue(forKey: key)
|
||||
|
||||
keysToValues[key] = value
|
||||
_keysToValues[key] = value
|
||||
|
||||
return currentValue
|
||||
} else {
|
||||
orderedKeys.append(key)
|
||||
keysToValues[key] = value
|
||||
_orderedKeys.append(key)
|
||||
_keysToValues[key] = value
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public mutating func removeValueForKey(key: Key) -> Value? {
|
||||
if let index = orderedKeys.indexOf(key) {
|
||||
guard let currentValue = keysToValues[key] else {
|
||||
fatalError("Inconsistency error occured in OrderedDictionary")
|
||||
}
|
||||
|
||||
orderedKeys.removeAtIndex(index)
|
||||
keysToValues[key] = nil
|
||||
|
||||
return currentValue
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public mutating func removeAll(keepCapacity keepCapacity: Bool = true) {
|
||||
orderedKeys.removeAll(keepCapacity: keepCapacity)
|
||||
keysToValues.removeAll(keepCapacity: keepCapacity)
|
||||
}
|
||||
|
||||
// MARK: - Managing Content Using Indexes
|
||||
|
||||
public subscript(index: Index) -> Element {
|
||||
get {
|
||||
guard let element = elementAtIndex(index) else {
|
||||
fatalError("OrderedDictionary index out of range")
|
||||
}
|
||||
|
||||
return element
|
||||
}
|
||||
set(newValue) {
|
||||
updateElement(newValue, atIndex: index)
|
||||
}
|
||||
}
|
||||
|
||||
public func indexForKey(key: Key) -> Index? {
|
||||
return orderedKeys.indexOf(key)
|
||||
}
|
||||
|
||||
public func elementAtIndex(index: Index) -> Element? {
|
||||
guard orderedKeys.indices.contains(index) else { return nil }
|
||||
/// Removes the given key and its associated value from the ordered dictionary.
|
||||
///
|
||||
/// If the key is found in the ordered dictionary, this method returns the key's associated
|
||||
/// value. On removal, the indices of the ordered dictionary are invalidated. If the key is
|
||||
/// not found in the ordered dictionary, this method returns `nil`.
|
||||
///
|
||||
/// - Parameter key: The key to remove along with its associated value.
|
||||
/// - Returns: The value that was removed, or `nil` if the key was not present in the
|
||||
/// ordered dictionary.
|
||||
///
|
||||
/// - SeeAlso: remove(at:)
|
||||
@discardableResult
|
||||
public mutating func removeValue(forKey key: Key) -> Value? {
|
||||
guard let index = index(forKey: key) else { return nil }
|
||||
|
||||
let key = orderedKeys[index]
|
||||
let currentValue = self[index].value
|
||||
|
||||
guard let value = self.keysToValues[key] else {
|
||||
fatalError("Inconsistency error occured in OrderedDictionary")
|
||||
}
|
||||
|
||||
return (key, value)
|
||||
}
|
||||
|
||||
public mutating func insertElement(newElement: Element, atIndex index: Index) -> Value? {
|
||||
guard index >= 0 else {
|
||||
fatalError("Negative OrderedDictionary index is out of range")
|
||||
}
|
||||
|
||||
guard index <= count else {
|
||||
fatalError("OrderedDictionary index out of range")
|
||||
}
|
||||
|
||||
let (key, value) = (newElement.0, newElement.1)
|
||||
|
||||
let adjustedIndex: Int
|
||||
let currentValue: Value?
|
||||
|
||||
if let currentIndex = orderedKeys.indexOf(key) {
|
||||
currentValue = keysToValues[key]
|
||||
adjustedIndex = (currentIndex < index - 1) ? index - 1 : index
|
||||
|
||||
orderedKeys.removeAtIndex(currentIndex)
|
||||
keysToValues[key] = nil
|
||||
} else {
|
||||
currentValue = nil
|
||||
adjustedIndex = index
|
||||
}
|
||||
|
||||
orderedKeys.insert(key, atIndex: adjustedIndex)
|
||||
keysToValues[key] = value
|
||||
_orderedKeys.remove(at: index)
|
||||
_keysToValues[key] = nil
|
||||
|
||||
return currentValue
|
||||
}
|
||||
|
||||
public mutating func updateElement(element: Element, atIndex index: Index) -> Element? {
|
||||
guard let currentElement = elementAtIndex(index) else {
|
||||
fatalError("OrderedDictionary index out of range")
|
||||
}
|
||||
|
||||
let (newKey, newValue) = (element.0, element.1)
|
||||
|
||||
orderedKeys[index] = newKey
|
||||
keysToValues[newKey] = newValue
|
||||
|
||||
return currentElement
|
||||
/// Removes all key-value pairs from the ordered dictionary and invalidates all indices.
|
||||
///
|
||||
/// - Parameter keepCapacity: Whether the ordered dictionary should keep its underlying storage.
|
||||
/// If you pass `true`, the operation preserves the storage capacity that the collection has,
|
||||
/// otherwise the underlying storage is released. The default is `false`.
|
||||
public mutating func removeAll(keepingCapacity keepCapacity: Bool = false) {
|
||||
_orderedKeys.removeAll(keepingCapacity: keepCapacity)
|
||||
_keysToValues.removeAll(keepingCapacity: keepCapacity)
|
||||
}
|
||||
|
||||
public mutating func removeAtIndex(index: Index) -> Element? {
|
||||
if let element = elementAtIndex(index) {
|
||||
orderedKeys.removeAtIndex(index)
|
||||
keysToValues.removeValueForKey(element.0)
|
||||
|
||||
return element
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
private func _unsafeValue(forKey key: Key) -> Value {
|
||||
let value = _keysToValues[key]
|
||||
precondition(value != nil, "Inconsistency error occurred in OrderedDictionary")
|
||||
return value!
|
||||
}
|
||||
|
||||
// MARK: - Description
|
||||
// ======================================================= //
|
||||
// MARK: - Index-based Access
|
||||
// ======================================================= //
|
||||
|
||||
public var description: String {
|
||||
let content = map({ "\($0.0): \($0.1)" }).joinWithSeparator(", ")
|
||||
return "[\(content)]"
|
||||
/// Accesses the key-value pair at the specified position.
|
||||
///
|
||||
/// The specified position has to be a valid index of the ordered dictionary. The index-base
|
||||
/// subscript returns the key-value pair corresponding to the index.
|
||||
///
|
||||
/// - Parameter position: The position of the key-value pair to access. `position` must be
|
||||
/// a valid index of the ordered dictionary and not equal to `endIndex`.
|
||||
/// - Returns: A tuple containing the key-value pair corresponding to `position`.
|
||||
///
|
||||
/// - SeeAlso: update(:at:)
|
||||
public subscript(position: Index) -> Element {
|
||||
precondition(indices.contains(position), "OrderedDictionary index is out of range")
|
||||
|
||||
let key = _orderedKeys[position]
|
||||
let value = _unsafeValue(forKey: key)
|
||||
|
||||
return (key, value)
|
||||
}
|
||||
|
||||
// MARK: - Backing Store
|
||||
/// Returns the index for the given key.
|
||||
///
|
||||
/// - Parameter key: The key to find in the ordered dictionary.
|
||||
/// - Returns: The index for `key` and its associated value if `key` is in the ordered
|
||||
/// dictionary; otherwise, `nil`.
|
||||
public func index(forKey key: Key) -> Index? {
|
||||
return _orderedKeys.index(of: key)
|
||||
}
|
||||
|
||||
private var orderedKeys: [Key]
|
||||
private var keysToValues: [Key: Value]
|
||||
/// Returns the key-value pair at the specified index, or `nil` if there is no key-value pair
|
||||
/// at that index.
|
||||
///
|
||||
/// - Parameter index: The index of the key-value pair to be looked up. `index` does not have to
|
||||
/// be a valid index.
|
||||
/// - Returns: A tuple containing the key-value pair corresponding to `index` if the index is
|
||||
/// valid; otherwise, `nil`.
|
||||
public func elementAt(_ index: Index) -> Element? {
|
||||
return indices.contains(index) ? self[index] : nil
|
||||
}
|
||||
|
||||
// MARK: - SequenceType & Indexable Conformance
|
||||
/// Checks whether the given key-value pair can be inserted into to ordered dictionary by
|
||||
/// validating the presence of the key.
|
||||
///
|
||||
/// - Parameter newElement: The key-value pair to be inserted into the ordered dictionary.
|
||||
/// - Returns: `true` if the key-value pair can be safely inserted; otherwise, `false`.
|
||||
///
|
||||
/// - SeeAlso: canInsert(key:)
|
||||
/// - SeeAlso: canInsert(at:)
|
||||
@available(*, deprecated, message: "Use canInsert(key:) with the element's key instead")
|
||||
public func canInsert(_ newElement: Element) -> Bool {
|
||||
return canInsert(key: newElement.key)
|
||||
}
|
||||
|
||||
public func generate() -> AnyGenerator<Element> {
|
||||
var nextIndex = 0
|
||||
let lastIndex = self.count
|
||||
|
||||
return anyGenerator {
|
||||
guard nextIndex < lastIndex else { return nil }
|
||||
|
||||
let nextKey = self.orderedKeys[nextIndex]
|
||||
|
||||
guard let nextValue = self.keysToValues[nextKey] else {
|
||||
fatalError("Inconsistency error occured in OrderedDictionary")
|
||||
}
|
||||
|
||||
let element = (nextKey, nextValue)
|
||||
|
||||
nextIndex++
|
||||
|
||||
return element
|
||||
}
|
||||
/// Checks whether a key-value pair with the given key can be inserted into the ordered
|
||||
/// dictionary by validating its presence.
|
||||
///
|
||||
/// - Parameter key: The key to be inserted into the ordered dictionary.
|
||||
/// - Returns: `true` if the key can safely be inserted; ortherwise, `false`.
|
||||
///
|
||||
/// - SeeAlso: canInsert(at:)
|
||||
public func canInsert(key: Key) -> Bool {
|
||||
return !containsKey(key)
|
||||
}
|
||||
|
||||
public var startIndex: Index { return orderedKeys.startIndex }
|
||||
/// Checks whether a new key-value pair can be inserted into the ordered dictionary at the
|
||||
/// given index.
|
||||
///
|
||||
/// - Parameter index: The index the new key-value pair should be inserted at.
|
||||
/// - Returns: `true` if a new key-value pair can be inserted at the specified index; otherwise,
|
||||
/// `false`.
|
||||
///
|
||||
/// - SeeAlso: canInsert(key:)
|
||||
public func canInsert(at index: Index) -> Bool {
|
||||
return index >= startIndex && index <= endIndex
|
||||
}
|
||||
|
||||
public var endIndex: Index { return orderedKeys.endIndex }
|
||||
/// Inserts a new key-value pair at the specified position.
|
||||
///
|
||||
/// If the key of the inserted pair already exists in the ordered dictionary, a runtime error
|
||||
/// is triggered. Use `canInsert(_:)` for performing a check first, so that this method can
|
||||
/// be executed safely.
|
||||
///
|
||||
/// - Parameter newElement: The new key-value pair to insert into the ordered dictionary. The
|
||||
/// key contained in the pair must not be already present in the ordered dictionary.
|
||||
/// - Parameter index: The position at which to insert the new key-value pair. `index` must be
|
||||
/// a valid index of the ordered dictionary or equal to `endIndex` property.
|
||||
///
|
||||
/// - SeeAlso: canInsert(key:)
|
||||
/// - SeeAlso: canInsert(at:)
|
||||
/// - SeeAlso: update(:at:)
|
||||
public mutating func insert(_ newElement: Element, at index: Index) {
|
||||
precondition(canInsert(key: newElement.key), "Cannot insert duplicate key in OrderedDictionary")
|
||||
precondition(canInsert(at: index), "Cannot insert at invalid index in OrderedDictionary")
|
||||
|
||||
let (key, value) = newElement
|
||||
|
||||
_orderedKeys.insert(key, at: index)
|
||||
_keysToValues[key] = value
|
||||
}
|
||||
|
||||
/// Checks whether the key-value pair at the given index can be updated with the given key-value
|
||||
/// pair. This is not the case if the key of the updated element is already present in the
|
||||
/// ordered dictionary and located at another index than the updated one.
|
||||
///
|
||||
/// Although this is a checking method, a valid index has to be provided.
|
||||
///
|
||||
/// - Parameter newElement: The key-value pair to be set at the specified position.
|
||||
/// - Parameter index: The position at which to set the key-value pair. `index` must be a valid
|
||||
/// index of the ordered dictionary.
|
||||
public func canUpdate(_ newElement: Element, at index: Index) -> Bool {
|
||||
var keyPresentAtIndex = false
|
||||
return _canUpdate(newElement, at: index, keyPresentAtIndex: &keyPresentAtIndex)
|
||||
}
|
||||
|
||||
/// Updates the key-value pair located at the specified position.
|
||||
///
|
||||
/// If the key of the updated pair already exists in the ordered dictionary *and* is located at
|
||||
/// a different position than the specified one, a runtime error is triggered. Use
|
||||
/// `canUpdate(_:at:)` for performing a check first, so that this method can be executed safely.
|
||||
///
|
||||
/// - Parameter newElement: The key-value pair to be set at the specified position.
|
||||
/// - Parameter index: The position at which to set the key-value pair. `index` must be a valid
|
||||
/// index of the ordered dictionary.
|
||||
///
|
||||
/// - SeeAlso: canUpdate(_:at:)
|
||||
/// - SeeAlso: insert(:at:)
|
||||
@discardableResult
|
||||
public mutating func update(_ newElement: Element, at index: Index) -> Element? {
|
||||
// Store the flag indicating whether the key of the inserted element
|
||||
// is present at the updated index
|
||||
var keyPresentAtIndex = false
|
||||
|
||||
precondition(
|
||||
_canUpdate(newElement, at: index, keyPresentAtIndex: &keyPresentAtIndex),
|
||||
"OrderedDictionary update duplicates key"
|
||||
)
|
||||
|
||||
// Decompose the element
|
||||
let (key, value) = newElement
|
||||
|
||||
// Load the current element at the index
|
||||
let replacedElement = self[index]
|
||||
|
||||
// If its key differs, remove its associated value
|
||||
if (!keyPresentAtIndex) {
|
||||
_keysToValues.removeValue(forKey: replacedElement.key)
|
||||
}
|
||||
|
||||
// Store the new position of the key and the new value associated with the key
|
||||
_orderedKeys[index] = key
|
||||
_keysToValues[key] = value
|
||||
|
||||
return replacedElement
|
||||
}
|
||||
|
||||
/// Removes and returns the key-value pair at the specified position if there is any key-value
|
||||
/// pair, or `nil` if there is none.
|
||||
///
|
||||
/// - Parameter index: The position of the key-value pair to remove.
|
||||
/// - Returns: The element at the specified index, or `nil` if the position is not taken.
|
||||
///
|
||||
/// - SeeAlso: removeValue(forKey:)
|
||||
@discardableResult
|
||||
public mutating func remove(at index: Index) -> Element? {
|
||||
guard let element = elementAt(index) else { return nil }
|
||||
|
||||
_orderedKeys.remove(at: index)
|
||||
_keysToValues.removeValue(forKey: element.key)
|
||||
|
||||
return element
|
||||
}
|
||||
|
||||
private func _canUpdate(
|
||||
_ newElement: Element,
|
||||
at index: Index,
|
||||
keyPresentAtIndex: inout Bool
|
||||
) -> Bool {
|
||||
precondition(indices.contains(index), "OrderedDictionary index is out of range")
|
||||
|
||||
let currentIndexOfKey = self.index(forKey: newElement.key)
|
||||
|
||||
let keyNotPresent = currentIndexOfKey == nil
|
||||
keyPresentAtIndex = currentIndexOfKey == index
|
||||
|
||||
return keyNotPresent || keyPresentAtIndex
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Removing First & Last Elements
|
||||
// ======================================================= //
|
||||
|
||||
/// Removes and returns the first key-value pair of the ordered dictionary if it is not empty.
|
||||
public mutating func popFirst() -> Element? {
|
||||
guard !isEmpty else { return nil }
|
||||
return remove(at: startIndex)
|
||||
}
|
||||
|
||||
/// Removes and returns the last key-value pair of the ordered dictionary if it is not empty.
|
||||
public mutating func popLast() -> Element? {
|
||||
guard !isEmpty else { return nil }
|
||||
return remove(at: index(before: endIndex))
|
||||
}
|
||||
|
||||
/// Removes and returns the first key-value pair of the ordered dictionary.
|
||||
public mutating func removeFirst() -> Element {
|
||||
precondition(!isEmpty, "Cannot remove key-value pairs from empty OrderedDictionary")
|
||||
return remove(at: startIndex)!
|
||||
}
|
||||
|
||||
/// Removes and returns the last key-value pair of the ordered dictionary.
|
||||
public mutating func removeLast() -> Element {
|
||||
precondition(!isEmpty, "Cannot remove key-value pairs from empty OrderedDictionary")
|
||||
return remove(at: index(before: endIndex))!
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Moving Elements
|
||||
// ======================================================= //
|
||||
|
||||
/// Moves an existing key-value pair specified by the given key to the new index by removing it
|
||||
/// from its original index first and inserting it at the new index. If the movement is
|
||||
/// actually performed, the previous index of the key-value pair is returned. Otherwise, `nil`
|
||||
/// is returned.
|
||||
///
|
||||
/// - Parameter key: The key specifying the key-value pair to move.
|
||||
/// - Parameter newIndex: The new index the key-value pair should be moved to.
|
||||
/// - Returns: The previous index of the key-value pair if it was sucessfully moved.
|
||||
@discardableResult
|
||||
public mutating func moveElement(forKey key: Key, to newIndex: Index) -> Index? {
|
||||
// Load the previous index and return nil if the index is not found.
|
||||
guard let previousIndex = index(forKey: key) else { return nil }
|
||||
|
||||
// If the previous and new indices match, threat it as if the movement was already
|
||||
// performed.
|
||||
guard previousIndex != newIndex else { return previousIndex }
|
||||
|
||||
// Remove the value for the key at its original index.
|
||||
let value = removeValue(forKey: key)!
|
||||
|
||||
// Validate the new index.
|
||||
precondition(canInsert(at: newIndex), "Cannot move to invalid index in OrderedDictionary")
|
||||
|
||||
// Insert the element at the new index.
|
||||
insert((key: key, value: value), at: newIndex)
|
||||
|
||||
return previousIndex
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Sorting Elements
|
||||
// ======================================================= //
|
||||
|
||||
/// Sorts the ordered dictionary in place, using the given predicate as the comparison between
|
||||
/// elements.
|
||||
///
|
||||
/// The predicate must be a *strict weak ordering* over the elements.
|
||||
///
|
||||
/// - Parameter areInIncreasingOrder: A predicate that returns `true` if its first argument
|
||||
/// should be ordered before its second argument; otherwise, `false`.
|
||||
///
|
||||
/// - SeeAlso: MutableCollection.sort(by:), sorted(by:)
|
||||
public mutating func sort(
|
||||
by areInIncreasingOrder: (Element, Element) throws -> Bool
|
||||
) rethrows {
|
||||
_orderedKeys = try _sortedElements(by: areInIncreasingOrder).map { $0.key }
|
||||
}
|
||||
|
||||
/// Returns a new ordered dictionary, sorted using the given predicate as the comparison between
|
||||
/// elements.
|
||||
///
|
||||
/// The predicate must be a *strict weak ordering* over the elements.
|
||||
///
|
||||
/// - Parameter areInIncreasingOrder: A predicate that returns `true` if its first argument
|
||||
/// should be ordered before its second argument; otherwise, `false`.
|
||||
/// - Returns: A new ordered dictionary sorted according to the predicate.
|
||||
///
|
||||
/// - SeeAlso: MutableCollection.sorted(by:), sort(by:)
|
||||
/// - MutatingVariant: sort
|
||||
public func sorted(
|
||||
by areInIncreasingOrder: (Element, Element) throws -> Bool
|
||||
) rethrows -> OrderedDictionary<Key, Value> {
|
||||
return OrderedDictionary(try _sortedElements(by: areInIncreasingOrder))
|
||||
}
|
||||
|
||||
private func _sortedElements(
|
||||
by areInIncreasingOrder: (Element, Element) throws -> Bool
|
||||
) rethrows -> [Element] {
|
||||
return try sorted(by: areInIncreasingOrder)
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Internal Storage
|
||||
// ======================================================= //
|
||||
|
||||
/// The backing storage for the ordered keys.
|
||||
fileprivate var _orderedKeys = [Key]()
|
||||
|
||||
/// The backing storage for the mapping of keys to values.
|
||||
fileprivate var _keysToValues = [Key: Value]()
|
||||
|
||||
}
|
||||
|
||||
public func == <Key: Equatable, Value: Equatable>(lhs: OrderedDictionary<Key, Value>, rhs: OrderedDictionary<Key, Value>) -> Bool {
|
||||
return lhs.orderedKeys == rhs.orderedKeys && lhs.keysToValues == rhs.keysToValues
|
||||
// ======================================================= //
|
||||
// MARK: - Subtypes
|
||||
// ======================================================= //
|
||||
|
||||
#if swift(>=4.1)
|
||||
|
||||
/// A view into an ordered dictionary whose indices are a subrange of the indices of the ordered
|
||||
/// dictionary.
|
||||
public typealias OrderedDictionarySlice<Key: Hashable, Value> = Slice<OrderedDictionary<Key, Value>>
|
||||
|
||||
/// A collection containing the keys of the ordered dictionary.
|
||||
///
|
||||
/// Under the hood this is a lazily evaluated bidirectional collection deriving the keys from
|
||||
/// the base ordered dictionary on-the-fly.
|
||||
public typealias OrderedDictionaryKeys<Key: Hashable, Value> = LazyMapCollection<OrderedDictionary<Key, Value>, Key>
|
||||
|
||||
/// A collection containing the values of the ordered dictionary.
|
||||
///
|
||||
/// Under the hood this is a lazily evaluated bidirectional collection deriving the values from
|
||||
/// the base ordered dictionary on-the-fly.
|
||||
public typealias OrderedDictionaryValues<Key: Hashable, Value> = LazyMapCollection<OrderedDictionary<Key, Value>, Value>
|
||||
|
||||
#else
|
||||
|
||||
/// A view into an ordered dictionary whose indices are a subrange of the indices of the ordered
|
||||
/// dictionary.
|
||||
public typealias OrderedDictionarySlice<Key: Hashable, Value> = BidirectionalSlice<OrderedDictionary<Key, Value>>
|
||||
|
||||
/// A collection containing the keys of the ordered dictionary.
|
||||
///
|
||||
/// Under the hood this is a lazily evaluated bidirectional collection deriving the keys from
|
||||
/// the base ordered dictionary on-the-fly.
|
||||
public typealias OrderedDictionaryKeys<Key: Hashable, Value> = LazyMapBidirectionalCollection<OrderedDictionary<Key, Value>, Key>
|
||||
|
||||
/// A collection containing the values of the ordered dictionary.
|
||||
///
|
||||
/// Under the hood this is a lazily evaluated bidirectional collection deriving the values from
|
||||
/// the base ordered dictionary on-the-fly.
|
||||
public typealias OrderedDictionaryValues<Key: Hashable, Value> = LazyMapBidirectionalCollection<OrderedDictionary<Key, Value>, Value>
|
||||
|
||||
#endif
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Literals
|
||||
// ======================================================= //
|
||||
|
||||
extension OrderedDictionary: ExpressibleByArrayLiteral {
|
||||
|
||||
/// Creates an ordered dictionary initialized from an array literal containing a list of
|
||||
/// key-value pairs.
|
||||
public init(arrayLiteral elements: Element...) {
|
||||
self.init(elements)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension OrderedDictionary: ExpressibleByDictionaryLiteral {
|
||||
|
||||
/// Creates an ordered dictionary initialized from a dictionary literal.
|
||||
public init(dictionaryLiteral elements: (Key, Value)...) {
|
||||
self.init(elements.map { element in
|
||||
let (key, value) = element
|
||||
return (key: key, value: value)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Equatable Conformance
|
||||
// ======================================================= //
|
||||
|
||||
#if swift(>=4.1)
|
||||
|
||||
extension OrderedDictionary: Equatable where Value: Equatable {}
|
||||
|
||||
#endif
|
||||
|
||||
extension OrderedDictionary where Value: Equatable {
|
||||
|
||||
/// Returns a Boolean value that indicates whether the two given ordered dictionaries with
|
||||
/// equatable values are equal.
|
||||
public static func == (lhs: OrderedDictionary, rhs: OrderedDictionary) -> Bool {
|
||||
return lhs._orderedKeys == rhs._orderedKeys
|
||||
&& lhs._keysToValues == rhs._keysToValues
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Dictionary Extension
|
||||
// ======================================================= //
|
||||
|
||||
extension Dictionary {
|
||||
|
||||
/// Returns an ordered dictionary containing the key-value pairs from the dictionary, sorted
|
||||
/// using the given sort function.
|
||||
///
|
||||
/// - Parameter areInIncreasingOrder: The sort function which compares the key-value pairs.
|
||||
/// - Returns: The ordered dictionary.
|
||||
/// - SeeAlso: OrderedDictionary.init(unsorted:areInIncreasingOrder:)
|
||||
public func sorted(
|
||||
by areInIncreasingOrder: (Element, Element) throws -> Bool
|
||||
) rethrows -> OrderedDictionary<Key, Value> {
|
||||
return try OrderedDictionary(
|
||||
unsorted: self,
|
||||
areInIncreasingOrder: areInIncreasingOrder
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.1</string>
|
||||
<string>2.2.2</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2015 Lukas Kubanek. All rights reserved.</string>
|
||||
<string>Copyright © 2015-2019 Lukas Kubanek. All rights reserved.</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
|
||||
+571
-179
@@ -1,238 +1,630 @@
|
||||
//
|
||||
// OrderedDictionaryTests.swift
|
||||
// OrderedDictionaryTests
|
||||
//
|
||||
// Created by Lukas Kubanek on 29/08/15.
|
||||
// Copyright © 2015 Lukas Kubanek. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
import Nimble
|
||||
import OrderedDictionary
|
||||
import Foundation
|
||||
import XCTest
|
||||
|
||||
#if !swift(>=4.1)
|
||||
|
||||
/// This is a shim for testing the equality in Swift <4.1.
|
||||
public func XCTAssertEqual<K, V: Equatable>(
|
||||
_ expression1: OrderedDictionary<K, V>,
|
||||
_ expression2: OrderedDictionary<K, V>,
|
||||
_ message: @autoclosure () -> String = "",
|
||||
file: StaticString = #file,
|
||||
line: UInt = #line
|
||||
) {
|
||||
return XCTAssertTrue(
|
||||
expression1 == expression2,
|
||||
message,
|
||||
file: file,
|
||||
line: line
|
||||
)
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
struct TestValue: Equatable {
|
||||
var string: String
|
||||
static func == (lhs: TestValue, rhs: TestValue) -> Bool {
|
||||
return lhs.string == rhs.string
|
||||
}
|
||||
}
|
||||
|
||||
class OrderedDictionaryTests: XCTestCase {
|
||||
|
||||
var orderedDictionary: OrderedDictionary<String, Int>!
|
||||
// ======================================================= //
|
||||
// MARK: - Initialization
|
||||
// ======================================================= //
|
||||
|
||||
override func setUp() {
|
||||
orderedDictionary = [
|
||||
("A", 1),
|
||||
("B", 2),
|
||||
("C", 3)
|
||||
]
|
||||
}
|
||||
|
||||
// MARK: - Content
|
||||
|
||||
func testInitializedContent() {
|
||||
expect(self.orderedDictionary.count) == 3
|
||||
|
||||
expect(self.orderedDictionary["A"]) == 1
|
||||
expect(self.orderedDictionary.indexForKey("A")) == 0
|
||||
expect(self.orderedDictionary.containsKey("A")) == true
|
||||
|
||||
expect(self.orderedDictionary["B"]) == 2
|
||||
expect(self.orderedDictionary.indexForKey("B")) == 1
|
||||
expect(self.orderedDictionary.containsKey("B")) == true
|
||||
|
||||
expect(self.orderedDictionary["C"]) == 3
|
||||
expect(self.orderedDictionary.indexForKey("C")) == 2
|
||||
expect(self.orderedDictionary.containsKey("C")) == true
|
||||
}
|
||||
|
||||
func testInitializationUsingPairs() {
|
||||
let elements = [
|
||||
func testInitializationUsingArrayLiteral() {
|
||||
let actual: OrderedDictionary<String, Int> = [
|
||||
("A", 1),
|
||||
("B", 2),
|
||||
("C", 3)
|
||||
]
|
||||
|
||||
expect(OrderedDictionary(elements: elements) == self.orderedDictionary).to(beTrue())
|
||||
let expected = OrderedDictionary<String, Int>([
|
||||
(key: "A", value: 1),
|
||||
(key: "B", value: 2),
|
||||
(key: "C", value: 3)
|
||||
])
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
func testElementsGenerator() {
|
||||
for entry in self.orderedDictionary.enumerate() {
|
||||
expect(self.orderedDictionary[entry.index].0) == entry.element.0
|
||||
expect(self.orderedDictionary[entry.index].1) == entry.element.1
|
||||
func testInitializationUsingDictionaryLiteral() {
|
||||
let actual: OrderedDictionary<String, Int> = [
|
||||
"A": 1,
|
||||
"B": 2,
|
||||
"C": 3
|
||||
]
|
||||
|
||||
let expected = OrderedDictionary<String, Int>([
|
||||
(key: "A", value: 1),
|
||||
(key: "B", value: 2),
|
||||
(key: "C", value: 3)
|
||||
])
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
func testInitializationUsingValuesAndKeyProviderClosure() {
|
||||
let actual = OrderedDictionary(
|
||||
values: [1, 2, 3],
|
||||
keyedBy: { "\($0)" }
|
||||
)
|
||||
|
||||
let expected = OrderedDictionary<String, Int>([
|
||||
(key: "1", value: 1),
|
||||
(key: "2", value: 2),
|
||||
(key: "3", value: 3)
|
||||
])
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
func testInitializationUsingValuesAnyKeyPath() {
|
||||
let actual = OrderedDictionary(
|
||||
values: [
|
||||
TestValue(string: "A"),
|
||||
TestValue(string: "B"),
|
||||
TestValue(string: "C")
|
||||
],
|
||||
keyedBy: \.string
|
||||
)
|
||||
|
||||
let expected = OrderedDictionary<String, TestValue>([
|
||||
(key: "A", value: TestValue(string: "A")),
|
||||
(key: "B", value: TestValue(string: "B")),
|
||||
(key: "C", value: TestValue(string: "C"))
|
||||
])
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
func testInitializationUsingUnsortedDictionaryAndSortFunction() {
|
||||
let actual = OrderedDictionary(
|
||||
unsorted: [
|
||||
2: "foo",
|
||||
1: "bar",
|
||||
4: "baz",
|
||||
5: "bat",
|
||||
3: "bam"
|
||||
],
|
||||
areInIncreasingOrder: { $0.key < $1.key }
|
||||
)
|
||||
|
||||
let expected = OrderedDictionary([
|
||||
(key: 1, value: "bar"),
|
||||
(key: 2, value: "foo"),
|
||||
(key: 3, value: "bam"),
|
||||
(key: 4, value: "baz"),
|
||||
(key: 5, value: "bat")
|
||||
])
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
func testCreationFromDictionary() {
|
||||
let actual = [
|
||||
2: "foo",
|
||||
1: "bar",
|
||||
4: "baz",
|
||||
5: "bat",
|
||||
3: "bam"
|
||||
].sorted(by: { $0.key < $1.key })
|
||||
|
||||
let expected = OrderedDictionary([
|
||||
(key: 1, value: "bar"),
|
||||
(key: 2, value: "foo"),
|
||||
(key: 3, value: "bam"),
|
||||
(key: 4, value: "baz"),
|
||||
(key: 5, value: "bat")
|
||||
])
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Content Access
|
||||
// ======================================================= //
|
||||
|
||||
func testAccessingContent() {
|
||||
let orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3]
|
||||
|
||||
XCTAssertEqual(orderedDictionary.count, 3)
|
||||
|
||||
XCTAssertEqual(orderedDictionary["A"], 1)
|
||||
XCTAssertEqual(orderedDictionary.value(forKey: "A"), 1)
|
||||
XCTAssertEqual(orderedDictionary.index(forKey: "A"), 0)
|
||||
XCTAssertTrue(orderedDictionary.containsKey("A"))
|
||||
XCTAssertTrue(orderedDictionary[0] == ("A", 1))
|
||||
|
||||
XCTAssertEqual(orderedDictionary["B"], 2)
|
||||
XCTAssertEqual(orderedDictionary.value(forKey: "B"), 2)
|
||||
XCTAssertEqual(orderedDictionary.index(forKey: "B"), 1)
|
||||
XCTAssertTrue(orderedDictionary.containsKey("B"))
|
||||
XCTAssertTrue(orderedDictionary[1] == ("B", 2))
|
||||
|
||||
XCTAssertEqual(orderedDictionary["C"], 3)
|
||||
XCTAssertEqual(orderedDictionary.value(forKey: "C"), 3)
|
||||
XCTAssertEqual(orderedDictionary.index(forKey: "C"), 2)
|
||||
XCTAssertTrue(orderedDictionary.containsKey("C"))
|
||||
XCTAssertTrue(orderedDictionary[2] == ("C", 3))
|
||||
}
|
||||
|
||||
func testCreatingIterator() {
|
||||
let orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3]
|
||||
var iterator = orderedDictionary.makeIterator()
|
||||
|
||||
let indexes = [0, 1, 2]
|
||||
var indexesIterator = indexes.makeIterator()
|
||||
|
||||
while let (actualKey, actualValue) = iterator.next() {
|
||||
let index = indexesIterator.next()
|
||||
let (expectedKey, expectedValue) = orderedDictionary[index!]
|
||||
|
||||
XCTAssertEqual(actualKey, expectedKey)
|
||||
XCTAssertEqual(actualValue, expectedValue)
|
||||
}
|
||||
|
||||
XCTAssertNil(iterator.next())
|
||||
XCTAssertNil(indexesIterator.next())
|
||||
}
|
||||
|
||||
func testAccessingOrderedKeys() {
|
||||
let orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3]
|
||||
let actual = Array(orderedDictionary.orderedKeys)
|
||||
|
||||
let expected = ["A", "B", "C"]
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
func testAccessingOrderedValues() {
|
||||
let orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3]
|
||||
let actual = Array(orderedDictionary.orderedValues)
|
||||
|
||||
let expected = [1, 2, 3]
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
func testAccessingUnsortedDictionary() {
|
||||
let orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3]
|
||||
let actual = orderedDictionary.unorderedDictionary
|
||||
|
||||
let expected = ["A": 1, "B": 2, "C": 3]
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Key-based Modifications
|
||||
// ======================================================= //
|
||||
|
||||
func testKeyBasedSubscript() {
|
||||
self.orderedDictionary["A"] = 5
|
||||
self.orderedDictionary["D"] = 10
|
||||
self.orderedDictionary["B"] = nil
|
||||
func testKeyBasedModifications() {
|
||||
var orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3]
|
||||
|
||||
expect(self.orderedDictionary.count) == 3
|
||||
orderedDictionary["A"] = 5
|
||||
orderedDictionary["D"] = 10
|
||||
orderedDictionary["B"] = nil
|
||||
|
||||
expect(self.orderedDictionary["A"]) == 5
|
||||
expect(self.orderedDictionary.indexForKey("A")) == 0
|
||||
expect(self.orderedDictionary.containsKey("A")) == true
|
||||
XCTAssertEqual(orderedDictionary.count, 3)
|
||||
|
||||
expect(self.orderedDictionary["B"]).to(beNil())
|
||||
expect(self.orderedDictionary.indexForKey("B")).to(beNil())
|
||||
expect(self.orderedDictionary.containsKey("B")) == false
|
||||
XCTAssertEqual(orderedDictionary["A"], 5)
|
||||
XCTAssertEqual(orderedDictionary.index(forKey: "A"), 0)
|
||||
XCTAssertTrue(orderedDictionary.containsKey("A"))
|
||||
|
||||
expect(self.orderedDictionary["C"]) == 3
|
||||
expect(self.orderedDictionary.indexForKey("C")) == 1
|
||||
expect(self.orderedDictionary.containsKey("C")) == true
|
||||
XCTAssertNil(orderedDictionary["B"])
|
||||
XCTAssertNil(orderedDictionary.index(forKey: "B"))
|
||||
XCTAssertFalse(orderedDictionary.containsKey("B"))
|
||||
|
||||
expect(self.orderedDictionary["D"]) == 10
|
||||
expect(self.orderedDictionary.indexForKey("D")) == 2
|
||||
expect(self.orderedDictionary.containsKey("D")) == true
|
||||
XCTAssertEqual(orderedDictionary["C"], 3)
|
||||
XCTAssertEqual(orderedDictionary.index(forKey: "C"), 1)
|
||||
XCTAssertTrue(orderedDictionary.containsKey("C"))
|
||||
|
||||
XCTAssertEqual(orderedDictionary["D"], 10)
|
||||
XCTAssertEqual(orderedDictionary.index(forKey: "D"), 2)
|
||||
XCTAssertTrue(orderedDictionary.containsKey("D"))
|
||||
}
|
||||
|
||||
// MARK: - Index-based Modifications
|
||||
// ======================================================= //
|
||||
// MARK: - Index-based Insertions
|
||||
// ======================================================= //
|
||||
|
||||
func testIndexBasedSubscriptForRetrievingValues() {
|
||||
let elementAtIndex0 = self.orderedDictionary[0]
|
||||
expect(elementAtIndex0.0) == "A"
|
||||
expect(elementAtIndex0.1) == 1
|
||||
func testIndexBasedInsertionsWithUniqueKeys() {
|
||||
var orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3]
|
||||
orderedDictionary.insert((key: "T", value: 15), at: 0)
|
||||
orderedDictionary.insert((key: "U", value: 16), at: 2)
|
||||
orderedDictionary.insert((key: "V", value: 17), at: 5)
|
||||
orderedDictionary.insert((key: "W", value: 18), at: 2)
|
||||
let actual = orderedDictionary
|
||||
|
||||
let elementAtIndex1 = self.orderedDictionary[1]
|
||||
expect(elementAtIndex1.0) == "B"
|
||||
expect(elementAtIndex1.1) == 2
|
||||
let expected: OrderedDictionary<String, Int> = ["T": 15, "A": 1, "W": 18, "U": 16, "B": 2, "C": 3, "V": 17]
|
||||
|
||||
let elementAtIndex2 = self.orderedDictionary[2]
|
||||
expect(elementAtIndex2.0) == "C"
|
||||
expect(elementAtIndex2.1) == 3
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
func testIndexBasedSubscriptForSettingValues() {
|
||||
self.orderedDictionary[0] = ("F", 10)
|
||||
self.orderedDictionary[1] = ("B", 5)
|
||||
func testIndexBasedInsertionWithDuplicateKey() {
|
||||
let orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3]
|
||||
let invalidKey = "A"
|
||||
|
||||
let elementAtIndex0 = self.orderedDictionary[0]
|
||||
expect(elementAtIndex0.0) == "F"
|
||||
expect(elementAtIndex0.1) == 10
|
||||
XCTAssertFalse(orderedDictionary.canInsert(key: invalidKey))
|
||||
}
|
||||
|
||||
func testIndexBasedInsertionWithNegativeIndex() {
|
||||
let orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3]
|
||||
let invalidIndex = -1
|
||||
|
||||
let elementAtIndex1 = self.orderedDictionary[1]
|
||||
expect(elementAtIndex1.0) == "B"
|
||||
expect(elementAtIndex1.1) == 5
|
||||
XCTAssertFalse(orderedDictionary.canInsert(at: invalidIndex))
|
||||
}
|
||||
|
||||
func testIndexBasedInsertionWithIndexOutOfBounds() {
|
||||
let orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3]
|
||||
let invalidIndex = 4
|
||||
|
||||
let elementAtIndex2 = self.orderedDictionary[2]
|
||||
expect(elementAtIndex2.0) == "C"
|
||||
expect(elementAtIndex2.1) == 3
|
||||
XCTAssertFalse(orderedDictionary.canInsert(at: invalidIndex))
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Index-based Updates
|
||||
// ======================================================= //
|
||||
|
||||
func testIndexBasedUpdateMethodWithNewUniqueKey() {
|
||||
var orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3]
|
||||
let previousElement = orderedDictionary.update((key: "D", value: 4), at: 1)
|
||||
|
||||
XCTAssertEqual(orderedDictionary.count, 3)
|
||||
XCTAssertTrue(previousElement! == ("B", 2))
|
||||
|
||||
let actual = orderedDictionary
|
||||
let expected: OrderedDictionary<String, Int> = ["A": 1, "D": 4, "C": 3]
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
func testIndexBasedUpdateMethodByReplacingSameKey() {
|
||||
var orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3]
|
||||
let previousElement = orderedDictionary.update((key: "B", value: 42), at: 1)
|
||||
|
||||
XCTAssertEqual(orderedDictionary.count, 3)
|
||||
XCTAssertTrue(previousElement! == ("B", 2))
|
||||
|
||||
let actual = orderedDictionary
|
||||
let expected: OrderedDictionary<String, Int> = ["A": 1, "B": 42, "C": 3]
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
func testIndexBasedUpdateMethodByDuplicatingKey() {
|
||||
let orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3]
|
||||
|
||||
let element = (key: "A", value: 42)
|
||||
|
||||
XCTAssertTrue(orderedDictionary.canUpdate(element, at: 0))
|
||||
XCTAssertFalse(orderedDictionary.canUpdate(element, at: 1))
|
||||
XCTAssertFalse(orderedDictionary.canUpdate(element, at: 2))
|
||||
}
|
||||
|
||||
func testRetrievingElementAtNonExistentIndex() {
|
||||
expect(self.orderedDictionary.elementAtIndex(10)).to(beNil())
|
||||
let orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3]
|
||||
XCTAssertNil(orderedDictionary.elementAt(42))
|
||||
}
|
||||
|
||||
func testIndexBasedInsertionsOfElementsWithDistinctKeys() {
|
||||
self.orderedDictionary.insertElement(("T", 15), atIndex: 0)
|
||||
self.orderedDictionary.insertElement(("U", 16), atIndex: 2)
|
||||
self.orderedDictionary.insertElement(("V", 17), atIndex: 5)
|
||||
self.orderedDictionary.insertElement(("W", 18), atIndex: 2)
|
||||
|
||||
let expectedOrderedDictionary: OrderedDictionary<String, Int> = [
|
||||
("T", 15),
|
||||
("A", 1),
|
||||
("W", 18),
|
||||
("U", 16),
|
||||
("B", 2),
|
||||
("C", 3),
|
||||
("V", 17)
|
||||
]
|
||||
|
||||
expect(self.orderedDictionary == expectedOrderedDictionary).to(beTrue())
|
||||
}
|
||||
|
||||
func testIndexBasedInsertionOfElementWithSameKeyBeforeItsCurrentIndex() {
|
||||
let previousValue = self.orderedDictionary.insertElement(("B", 5), atIndex: 0)
|
||||
|
||||
let expectedOrderedDictionary: OrderedDictionary<String, Int> = [
|
||||
("B", 5),
|
||||
("A", 1),
|
||||
("C", 3)
|
||||
]
|
||||
|
||||
expect(self.orderedDictionary.count) == 3
|
||||
expect(self.orderedDictionary == expectedOrderedDictionary).to(beTrue())
|
||||
expect(previousValue) == 2
|
||||
}
|
||||
|
||||
func testIndexBasedInsertionOfElementWithSameKeyAtItsCurrentIndex() {
|
||||
let previousValue = self.orderedDictionary.insertElement(("B", 5), atIndex: 1)
|
||||
|
||||
let expectedOrderedDictionary: OrderedDictionary<String, Int> = [
|
||||
("A", 1),
|
||||
("B", 5),
|
||||
("C", 3)
|
||||
]
|
||||
|
||||
expect(self.orderedDictionary.count) == 3
|
||||
expect(self.orderedDictionary == expectedOrderedDictionary).to(beTrue())
|
||||
expect(previousValue) == 2
|
||||
}
|
||||
|
||||
func testIndexBasedInsertionOfElementWithSameKeyAfterItsCurrentIndex() {
|
||||
let previousValue = self.orderedDictionary.insertElement(("B", 5), atIndex: 3)
|
||||
|
||||
let expectedOrderedDictionary: OrderedDictionary<String, Int> = [
|
||||
("A", 1),
|
||||
("C", 3),
|
||||
("B", 5)
|
||||
]
|
||||
|
||||
expect(self.orderedDictionary.count) == 3
|
||||
expect(self.orderedDictionary == expectedOrderedDictionary).to(beTrue())
|
||||
expect(previousValue) == 2
|
||||
}
|
||||
|
||||
// MARK: - Removal
|
||||
// ======================================================= //
|
||||
// MARK: - Content Removal
|
||||
// ======================================================= //
|
||||
|
||||
func testRemoveAll() {
|
||||
self.orderedDictionary.removeAll()
|
||||
var orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3]
|
||||
|
||||
expect(self.orderedDictionary.count) == 0
|
||||
orderedDictionary.removeAll()
|
||||
|
||||
XCTAssertEqual(orderedDictionary.count, 0)
|
||||
}
|
||||
|
||||
func testRemovalForKey() {
|
||||
let removedValue1 = self.orderedDictionary.removeValueForKey("A")
|
||||
let removedValue2 = self.orderedDictionary.removeValueForKey("K")
|
||||
func testKeyBasedRemoval() {
|
||||
var orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3]
|
||||
|
||||
expect(removedValue1) == 1
|
||||
expect(removedValue2).to(beNil())
|
||||
let removedValue1 = orderedDictionary.removeValue(forKey: "A")
|
||||
let removedValue2 = orderedDictionary.removeValue(forKey: "K")
|
||||
|
||||
expect(self.orderedDictionary.count) == 2
|
||||
XCTAssertEqual(removedValue1, 1)
|
||||
XCTAssertNil(removedValue2)
|
||||
|
||||
expect(self.orderedDictionary["A"]).to(beNil())
|
||||
expect(self.orderedDictionary.indexForKey("A")).to(beNil())
|
||||
XCTAssertEqual(orderedDictionary.count, 2)
|
||||
|
||||
expect(self.orderedDictionary["B"]) == 2
|
||||
expect(self.orderedDictionary.indexForKey("B")) == 0
|
||||
XCTAssertNil(orderedDictionary["A"])
|
||||
XCTAssertNil(orderedDictionary.index(forKey: "A"))
|
||||
|
||||
expect(self.orderedDictionary["C"]) == 3
|
||||
expect(self.orderedDictionary.indexForKey("C")) == 1
|
||||
XCTAssertEqual(orderedDictionary["B"], 2)
|
||||
XCTAssertEqual(orderedDictionary.index(forKey: "B"), 0)
|
||||
|
||||
XCTAssertEqual(orderedDictionary["C"], 3)
|
||||
XCTAssertEqual(orderedDictionary.index(forKey: "C"), 1)
|
||||
}
|
||||
|
||||
func testIndexBasedRemoval() {
|
||||
var orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3, "D": 4]
|
||||
|
||||
let (actualKey1, actualValue1) = orderedDictionary.remove(at: 0)!
|
||||
let (expectedKey1, expectedValue1) = ("A", 1)
|
||||
|
||||
XCTAssertEqual(actualKey1, expectedKey1)
|
||||
XCTAssertEqual(actualValue1, expectedValue1)
|
||||
|
||||
let (actualKey2, actualValue2) = orderedDictionary.remove(at: 2)!
|
||||
let (expectedKey2, expectedValue2) = ("D", 4)
|
||||
|
||||
XCTAssertEqual(actualKey2, expectedKey2)
|
||||
XCTAssertEqual(actualValue2, expectedValue2)
|
||||
|
||||
let nonExistentElement = orderedDictionary.remove(at: 42)
|
||||
|
||||
XCTAssertNil(nonExistentElement)
|
||||
|
||||
let actual = orderedDictionary
|
||||
let expected: OrderedDictionary<String, Int> = ["B": 2, "C": 3]
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
func testPopFirstEmpty() {
|
||||
var orderedDictionary: OrderedDictionary<String, Int> = []
|
||||
let first = orderedDictionary.popFirst()
|
||||
|
||||
XCTAssertNil(first)
|
||||
}
|
||||
|
||||
func testPopFirstNonEmpty() {
|
||||
var orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3, "D": 4]
|
||||
|
||||
let (actualKey, actualValue) = orderedDictionary.popFirst()!
|
||||
let (expectedKey, expectedValue) = ("A", 1)
|
||||
|
||||
XCTAssertEqual(actualKey, expectedKey)
|
||||
XCTAssertEqual(actualValue, expectedValue)
|
||||
|
||||
let actual = orderedDictionary
|
||||
let expected: OrderedDictionary<String, Int> = ["B": 2, "C": 3, "D": 4]
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
func testRemovalAtIndex() {
|
||||
let removedElement1 = self.orderedDictionary.removeAtIndex(1)
|
||||
let removedElement2 = self.orderedDictionary.removeAtIndex(0)
|
||||
let removedElement3 = self.orderedDictionary.removeAtIndex(5)
|
||||
func testPopLastEmpty() {
|
||||
var orderedDictionary: OrderedDictionary<String, Int> = []
|
||||
let last = orderedDictionary.popLast()
|
||||
|
||||
expect(removedElement1?.0) == "B"
|
||||
expect(removedElement1?.1) == 2
|
||||
|
||||
expect(removedElement2?.0) == "A"
|
||||
expect(removedElement2?.1) == 1
|
||||
|
||||
expect(removedElement3).to(beNil())
|
||||
|
||||
expect(self.orderedDictionary.count) == 1
|
||||
|
||||
let elementAtIndex0 = self.orderedDictionary[0]
|
||||
expect(elementAtIndex0.0) == "C"
|
||||
expect(elementAtIndex0.1) == 3
|
||||
XCTAssertNil(last)
|
||||
}
|
||||
|
||||
func testPopLastNonEmpty() {
|
||||
var orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3, "D": 4]
|
||||
|
||||
let (actualKey, actualValue) = orderedDictionary.popLast()!
|
||||
let (expectedKey, expectedValue) = ("D", 4)
|
||||
|
||||
XCTAssertEqual(actualKey, expectedKey)
|
||||
XCTAssertEqual(actualValue, expectedValue)
|
||||
|
||||
let actual = orderedDictionary
|
||||
let expected: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3]
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
func testRemoveFirstNonEmpty() {
|
||||
var orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3, "D": 4]
|
||||
|
||||
let (actualKey, actualValue) = orderedDictionary.removeFirst()
|
||||
let (expectedKey, expectedValue) = ("A", 1)
|
||||
|
||||
XCTAssertEqual(actualKey, expectedKey)
|
||||
XCTAssertEqual(actualValue, expectedValue)
|
||||
|
||||
let actual = orderedDictionary
|
||||
let expected: OrderedDictionary<String, Int> = ["B": 2, "C": 3, "D": 4]
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
func testRemoveLastNonEmpty() {
|
||||
var orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3, "D": 4]
|
||||
|
||||
let (actualKey, actualValue) = orderedDictionary.removeLast()
|
||||
let (expectedKey, expectedValue) = ("D", 4)
|
||||
|
||||
XCTAssertEqual(actualKey, expectedKey)
|
||||
XCTAssertEqual(actualValue, expectedValue)
|
||||
|
||||
let actual = orderedDictionary
|
||||
let expected: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3]
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Moving Elements
|
||||
// ======================================================= //
|
||||
|
||||
func testMovingElements() {
|
||||
var orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3, "D": 4]
|
||||
|
||||
XCTAssertEqual(orderedDictionary.moveElement(forKey: "A", to: 2), 0) // B, C, A, D
|
||||
XCTAssertEqual(orderedDictionary.moveElement(forKey: "D", to: 3), 3) // B, C, A, D
|
||||
XCTAssertEqual(orderedDictionary.moveElement(forKey: "C", to: 0), 1) // C, B, A, D
|
||||
XCTAssertEqual(orderedDictionary.moveElement(forKey: "B", to: 3), 1) // C, A, D, B
|
||||
XCTAssertEqual(orderedDictionary.moveElement(forKey: "E", to: 0), nil)
|
||||
|
||||
let actual = orderedDictionary
|
||||
let expected: OrderedDictionary<String, Int> = ["C": 3, "A": 1, "D": 4, "B": 2]
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Sorting Elements
|
||||
// ======================================================= //
|
||||
|
||||
func testSortingWithMutation() {
|
||||
var orderedDictionary: OrderedDictionary<String, Int> = ["E": 4, "G": 3, "A": 3, "D": 1, "B": 4]
|
||||
orderedDictionary.sort { element1, element2 in
|
||||
if element1.value != element2.value { return element1.value < element2.value }
|
||||
return element1.key < element2.key
|
||||
}
|
||||
let actual = orderedDictionary
|
||||
|
||||
let expected: OrderedDictionary<String, Int> = ["D": 1, "A": 3, "G": 3, "B": 4, "E": 4]
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
func testSortingWithoutMutation() {
|
||||
let orderedDictionary: OrderedDictionary<String, Int> = ["E": 4, "G": 3, "A": 3, "D": 1, "B": 4]
|
||||
let actual: OrderedDictionary<String, Int> = orderedDictionary.sorted { element1, element2 in
|
||||
if element1.value != element2.value { return element1.value < element2.value }
|
||||
return element1.key < element2.key
|
||||
}
|
||||
|
||||
let expected: OrderedDictionary<String, Int> = ["D": 1, "A": 3, "G": 3, "B": 4, "E": 4]
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Slices
|
||||
// ======================================================= //
|
||||
|
||||
func testSliceAccess() {
|
||||
let orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3, "D": 4]
|
||||
let slice = orderedDictionary[2..<4]
|
||||
|
||||
XCTAssertEqual(slice.count, 2)
|
||||
XCTAssertEqual(slice.startIndex, 2)
|
||||
XCTAssertEqual(slice.endIndex, 4)
|
||||
XCTAssertEqual(Array(slice.indices), [2, 3])
|
||||
XCTAssert(slice[2] == (key: "C", value: 3))
|
||||
XCTAssert(slice[3] == (key: "D", value: 4))
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Codable
|
||||
// ======================================================= //
|
||||
|
||||
func testEncodingAndDecodingViaJSON() {
|
||||
let orderedDictionary: OrderedDictionary<String, Int> = [
|
||||
"A": 42,
|
||||
"B": 100,
|
||||
"C": 11
|
||||
]
|
||||
|
||||
let jsonEncoder = JSONEncoder()
|
||||
let data = try! jsonEncoder.encode(orderedDictionary)
|
||||
let actualString = String(data: data, encoding: .utf8)
|
||||
|
||||
let expectedString = "[\"A\",42,\"B\",100,\"C\",11]"
|
||||
|
||||
XCTAssertEqual(actualString, expectedString)
|
||||
|
||||
let jsonDecoder = JSONDecoder()
|
||||
let actual = try! jsonDecoder.decode(OrderedDictionary<String, Int>.self, from: data)
|
||||
|
||||
let expected = orderedDictionary
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
func testEncodingAndDecodingViaPropertyList() {
|
||||
let orderedDictionary: OrderedDictionary<String, Int> = [
|
||||
"A": 42,
|
||||
"B": 100,
|
||||
"C": 11
|
||||
]
|
||||
|
||||
let plistEncoder = PropertyListEncoder()
|
||||
let data = try! plistEncoder.encode(orderedDictionary)
|
||||
|
||||
let plistDecoder = PropertyListDecoder()
|
||||
let actual = try! plistDecoder.decode(OrderedDictionary<String, Int>.self, from: data)
|
||||
|
||||
let expected = orderedDictionary
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Description
|
||||
// ======================================================= //
|
||||
|
||||
struct DescribedValue: CustomStringConvertible, CustomDebugStringConvertible {
|
||||
init(_ value: Int) { self.value = value }
|
||||
let value: Int
|
||||
var description: String { return "\(value)" }
|
||||
var debugDescription: String { return "debug(\(value))" }
|
||||
}
|
||||
|
||||
func testEmptyDescription() {
|
||||
let orderedDictionary = OrderedDictionary<String, DescribedValue>()
|
||||
let actual = orderedDictionary.description
|
||||
|
||||
let expected = "[:]"
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
func testDescription() {
|
||||
expect(self.orderedDictionary.description) == "[A: 1, B: 2, C: 3]"
|
||||
let orderedDictionary: OrderedDictionary<String, DescribedValue> = [
|
||||
"A": DescribedValue(1),
|
||||
"B": DescribedValue(2),
|
||||
"C": DescribedValue(3)
|
||||
]
|
||||
let actual = orderedDictionary.description
|
||||
|
||||
let expected = "[A: 1, B: 2, C: 3]"
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
func testEmptyDebugDescription() {
|
||||
let orderedDictionary = OrderedDictionary<String, DescribedValue>()
|
||||
let actual = orderedDictionary.debugDescription
|
||||
|
||||
let expected = "[:]"
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
func testDebugDescription() {
|
||||
let orderedDictionary: OrderedDictionary<String, DescribedValue> = [
|
||||
"A": DescribedValue(1),
|
||||
"B": DescribedValue(2),
|
||||
"C": DescribedValue(3)
|
||||
]
|
||||
let actual = orderedDictionary.debugDescription
|
||||
|
||||
let expected = "[\"A\": debug(1), \"B\": debug(2), \"C\": debug(3)]"
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user