Add unit test code for DB1
This commit is contained in:
44
KissMe/Sources/Test/KissTestCase.swift
Normal file
44
KissMe/Sources/Test/KissTestCase.swift
Normal file
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// KissTestCase.swift
|
||||
// KissMe
|
||||
//
|
||||
// Created by ened-book-m1 on 11/8/24.
|
||||
//
|
||||
|
||||
public protocol KissTestCase {
|
||||
// Method called before each test
|
||||
func setUp()
|
||||
|
||||
// Method called after each test
|
||||
func tearDown()
|
||||
|
||||
// Method to run all tests
|
||||
func runTests()
|
||||
}
|
||||
|
||||
extension KissTestCase {
|
||||
public func setUp() {}
|
||||
public func tearDown() {}
|
||||
|
||||
public func runTests() {
|
||||
let mirror = Mirror(reflecting: self)
|
||||
for child in mirror.children {
|
||||
if let name = child.label, name.hasPrefix("test"),
|
||||
let test = child.value as? () -> Void {
|
||||
setUp()
|
||||
print("\(name) begin")
|
||||
test()
|
||||
print("\(name) end")
|
||||
tearDown()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func assertEqual<T: Equatable>(_ a: T, _ b: T, message: String = "") {
|
||||
if a != b {
|
||||
print("Assertion failed: \(a) is not equal to \(b). \(message)")
|
||||
} else {
|
||||
//print("Test passed.")
|
||||
}
|
||||
}
|
||||
@@ -10,47 +10,6 @@ import KissMe
|
||||
import KissMeme
|
||||
|
||||
|
||||
extension KissConsole {
|
||||
}
|
||||
|
||||
func test_build_min_db() {
|
||||
// guard let enumerator = FileManager.subPathFiles("data") else {
|
||||
// return
|
||||
// }
|
||||
|
||||
//let db = try KissDB(directory: url)
|
||||
|
||||
//test_check_name_parsed()
|
||||
//test_date_time()
|
||||
//build_min_db_from_candle_csv()
|
||||
test_select_min_db()
|
||||
}
|
||||
|
||||
private func test_field_type() {
|
||||
let v1: Int64 = 0
|
||||
let v2: Int64 = 1
|
||||
let v3: Int64 = 65536
|
||||
let v4: Int64 = -2
|
||||
|
||||
print("\(v1.fieldType)")
|
||||
print("\(v2.fieldType)")
|
||||
print("\(v3.fieldType)")
|
||||
print("\(v4.fieldType)")
|
||||
print("done")
|
||||
}
|
||||
|
||||
private func test_date_time() {
|
||||
let kissDate = Date.date(yyyyMMdd: "20200101", HHmmss: "000000")
|
||||
let timestamp = UInt64(kissDate!.timeIntervalSince1970)
|
||||
print("timestamp: \(timestamp)")
|
||||
print("kissDate: \(kissDate!.timeIntervalSince2020)")
|
||||
print("today: \(UInt32(Date().timeIntervalSince2020))")
|
||||
|
||||
let value: UInt64 = 1234567890
|
||||
let d = Data(value: value)
|
||||
print(d.hexString)
|
||||
}
|
||||
|
||||
enum CandleDataFieldType: UInt8 {
|
||||
case uint8 = 1 // 8 bits unsigned integer
|
||||
case uint16 = 2 // 16 bits unsigned integer
|
||||
@@ -60,6 +19,20 @@ enum CandleDataFieldType: UInt8 {
|
||||
case float = 11 // 4 byte float point
|
||||
}
|
||||
|
||||
extension CandleDataFieldType: CustomStringConvertible {
|
||||
var description: String {
|
||||
switch self {
|
||||
case .uint8: return "uint8"
|
||||
case .uint16: return "uint16"
|
||||
case .uint32: return "uint32"
|
||||
case .uint64: return "uint64"
|
||||
case .double: return "double"
|
||||
case .float: return "float"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extension Int64 {
|
||||
var fieldType: CandleDataFieldType {
|
||||
let unsignedValue = UInt64(bitPattern: self)
|
||||
@@ -89,6 +62,7 @@ extension Int64 {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extension Domestic.Candle: @retroactive Equatable {
|
||||
public static func == (lhs: Domestic.Candle, rhs: Domestic.Candle) -> Bool {
|
||||
return
|
||||
@@ -103,6 +77,7 @@ extension Domestic.Candle: @retroactive Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct CandleData {
|
||||
let key: Data
|
||||
let data: Data
|
||||
@@ -165,7 +140,7 @@ struct CandleData {
|
||||
data.append(contentsOf: typeFields)
|
||||
data.append(valuesData)
|
||||
self.data = data
|
||||
print("data: \(data.count)")
|
||||
//print("data: \(data.count)")
|
||||
}
|
||||
|
||||
var candle: Domestic.Candle {
|
||||
@@ -177,19 +152,36 @@ struct CandleData {
|
||||
let typeFields = [UInt8](data[0 ..< 6])
|
||||
var values = [stockBusinessDate, stockConclusionTime]
|
||||
|
||||
print("candle data: \(data.count)")
|
||||
//print("candle data: \(data.count)")
|
||||
|
||||
var start = 6
|
||||
for field in typeFields {
|
||||
let value: String
|
||||
|
||||
switch CandleDataFieldType(rawValue: field)! {
|
||||
case .uint8: value = String(data.subdata(in: start ..< start+1).value_UInt8); start += 1
|
||||
case .uint16: value = String(data.subdata(in: start ..< start+2).value_UInt16); start += 2
|
||||
case .uint32: value = String(data.subdata(in: start ..< start+4).value_UInt32); start += 4
|
||||
case .uint64: value = String(data.subdata(in: start ..< start+8).value_UInt64); start += 8
|
||||
case .float: value = String(data.subdata(in: start ..< start+4).value_Float); start += 4
|
||||
case .double: value = String(data.subdata(in: start ..< start+8).value_Double); start += 8
|
||||
case .uint8:
|
||||
value = String(data.subdata(in: start ..< start+1).value_UInt8)
|
||||
start += 1
|
||||
|
||||
case .uint16:
|
||||
value = String(data.subdata(in: start ..< start+2).value_UInt16)
|
||||
start += 2
|
||||
|
||||
case .uint32:
|
||||
value = String(data.subdata(in: start ..< start+4).value_UInt32)
|
||||
start += 4
|
||||
|
||||
case .uint64:
|
||||
value = String(data.subdata(in: start ..< start+8).value_UInt64)
|
||||
start += 8
|
||||
|
||||
case .float:
|
||||
value = String(data.subdata(in: start ..< start+4).value_Float)
|
||||
start += 4
|
||||
|
||||
case .double:
|
||||
value = String(data.subdata(in: start ..< start+8).value_Double)
|
||||
start += 8
|
||||
}
|
||||
values.append(value)
|
||||
}
|
||||
@@ -197,117 +189,8 @@ struct CandleData {
|
||||
}
|
||||
}
|
||||
|
||||
private func build_min_db(_ productNo: String, _ candle_csvs: [URL]) {
|
||||
let dataPath = URL.currentDirectory().appending(path: "data")
|
||||
|
||||
for csvUrl in candle_csvs {
|
||||
let candleMinName = CandleMinuteFileName()
|
||||
if let (_, yyyyMMdd) = candleMinName.matchedUrl(csvUrl.path), let year = Int(yyyyMMdd.prefix(4)) {
|
||||
let yearDbPath = dataPath.appending(path: "\(productNo)/min/candle-\(year).db1")
|
||||
//try? FileManager.default.removeItem(at: directory)
|
||||
try? FileManager.default.createDirectory(at: yearDbPath, withIntermediateDirectories: true)
|
||||
|
||||
do {
|
||||
let candles = try [Domestic.Candle].readCsv(fromFile: csvUrl)
|
||||
|
||||
let db = try KissDB(directory: yearDbPath)
|
||||
try db.begin()
|
||||
|
||||
for candle in candles {
|
||||
let candleData = try CandleData(candle: candle)
|
||||
let item = KissDB.DataItem(key: candleData.key, value: candleData.data)
|
||||
try db.insert(item: item)
|
||||
|
||||
if candleData.candle != candle {
|
||||
assertionFailure("invalid candle data")
|
||||
}
|
||||
}
|
||||
|
||||
try db.commit()
|
||||
} catch {
|
||||
print("\(error)")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func build_min_db_from_candle_csv() {
|
||||
guard let enumerator = FileManager.subPathFiles("data") else {
|
||||
return
|
||||
}
|
||||
|
||||
var lastProductNo: String?
|
||||
|
||||
let candleMinName = CandleMinuteFileName()
|
||||
var allCandles = [String: [URL]]()
|
||||
for case let fileUrl as URL in enumerator {
|
||||
guard let (productNo, yyyyMMdd) = candleMinName.matchedUrl(fileUrl.path) else {
|
||||
continue
|
||||
}
|
||||
|
||||
// Select only one product no
|
||||
if lastProductNo == nil {
|
||||
lastProductNo = productNo
|
||||
}
|
||||
else {
|
||||
if lastProductNo! != productNo {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if allCandles.keys.contains(productNo) {
|
||||
allCandles[productNo]!.append(fileUrl)
|
||||
}
|
||||
else {
|
||||
allCandles[productNo] = [fileUrl]
|
||||
}
|
||||
print("product: \(productNo) \(yyyyMMdd)")
|
||||
}
|
||||
print("total \(allCandles.count)")
|
||||
|
||||
if let productCandles = allCandles.first {
|
||||
build_min_db(productCandles.key, productCandles.value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func test_select_min_db() {
|
||||
let yearDbPath = URL(filePath: "/Users/ened/Kiss/KissMe/bin/data/047040/min/candle-2023.db1")
|
||||
do {
|
||||
let startTime = KissDB.appTime
|
||||
|
||||
let db = try KissDB(directory: yearDbPath)
|
||||
try db.begin()
|
||||
|
||||
try db.select(into: { (dataItem: KissDB.DataItem) -> Bool in
|
||||
//let candleData = CandleData(key: dataItem.key, data: dataItem.value)
|
||||
//print("\(candleData.candleDate) : \(candleData.candle.accumulatedTradingAmount)")
|
||||
return true
|
||||
})
|
||||
|
||||
try db.rollback()
|
||||
|
||||
let endTime = KissDB.appTime
|
||||
print("DB count: \(db.count) insertAll elapsed: \(endTime - startTime)")
|
||||
} catch {
|
||||
print("\(error)")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func test_check_name_parsed() {
|
||||
let candleMinName = CandleMinuteFileName()
|
||||
let url = "/Users/ened/Kiss/KissMe/bin/data/000020/min/candle-20230705.csv"
|
||||
guard let (productNo, yyyyMMdd) = candleMinName.matchedUrl(url) else {
|
||||
return
|
||||
}
|
||||
print(productNo, yyyyMMdd)
|
||||
}
|
||||
|
||||
|
||||
class CandleMinuteFileName {
|
||||
|
||||
let regex: NSRegularExpression
|
||||
|
||||
init() {
|
||||
@@ -333,3 +216,66 @@ class CandleMinuteFileName {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extension KissConsole {
|
||||
|
||||
func collectCandleMinuteFiles() -> [String: [URL]] {
|
||||
guard let enumerator = FileManager.subPathFiles("data") else {
|
||||
return [:]
|
||||
}
|
||||
|
||||
let candleMinName = CandleMinuteFileName()
|
||||
var allCandles = [String: [URL]]()
|
||||
for case let fileUrl as URL in enumerator {
|
||||
guard let (productNo, _) = candleMinName.matchedUrl(fileUrl.path) else {
|
||||
continue
|
||||
}
|
||||
|
||||
if allCandles.keys.contains(productNo) {
|
||||
allCandles[productNo]!.append(fileUrl)
|
||||
}
|
||||
else {
|
||||
allCandles[productNo] = [fileUrl]
|
||||
}
|
||||
}
|
||||
return allCandles
|
||||
}
|
||||
|
||||
func buildCandleMinuteDB(productNo: String, csvFiles: [URL], removeOldDB: Bool = false) {
|
||||
let dataPath = URL.currentDirectory().appending(path: "data")
|
||||
|
||||
for csvFile in csvFiles {
|
||||
let candleMinName = CandleMinuteFileName()
|
||||
if let (_, yyyyMMdd) = candleMinName.matchedUrl(csvFile.path), let year = Int(yyyyMMdd.prefix(4)) {
|
||||
let yearDbPath = dataPath.appending(path: "\(productNo)/min/candle-\(year).db1")
|
||||
if removeOldDB {
|
||||
try? FileManager.default.removeItem(at: yearDbPath)
|
||||
}
|
||||
try? FileManager.default.createDirectory(at: yearDbPath, withIntermediateDirectories: true)
|
||||
|
||||
do {
|
||||
let candles = try [Domestic.Candle].readCsv(fromFile: csvFile)
|
||||
|
||||
let db = try KissDB(directory: yearDbPath)
|
||||
try db.begin()
|
||||
|
||||
for candle in candles {
|
||||
let candleData = try CandleData(candle: candle)
|
||||
let item = KissDB.DataItem(key: candleData.key, value: candleData.data)
|
||||
try db.insertData(item: item)
|
||||
|
||||
if candleData.candle != candle {
|
||||
assertionFailure("invalid candle data")
|
||||
}
|
||||
}
|
||||
|
||||
try db.commit()
|
||||
} catch {
|
||||
print("\(error)")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
129
KissMeConsole/Sources/Tests/DB1_CandleData_Tests.swift
Normal file
129
KissMeConsole/Sources/Tests/DB1_CandleData_Tests.swift
Normal file
@@ -0,0 +1,129 @@
|
||||
//
|
||||
// DB1_CandleData_Tests.swift
|
||||
// KissMeConsole
|
||||
//
|
||||
// Created by ened-book-m1 on 11/8/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import KissMe
|
||||
import KissMeme
|
||||
|
||||
struct DB1_CandleData_Tests: KissTestCase {
|
||||
|
||||
let test_1_FieldType = {
|
||||
let v1: Int64 = 0
|
||||
let v2: Int64 = 1
|
||||
let v3: Int64 = 65536
|
||||
let v4: Int64 = -2
|
||||
|
||||
assertEqual(v1.fieldType, .uint8)
|
||||
assertEqual(v2.fieldType, .uint8)
|
||||
assertEqual(v3.fieldType, .uint32)
|
||||
assertEqual(v4.fieldType, .uint64)
|
||||
}
|
||||
|
||||
let test_2_DateTimeSince2020 = {
|
||||
let kissDate = Date.date(yyyyMMdd: "20200101", HHmmss: "000000")
|
||||
let timestamp = UInt64(kissDate!.timeIntervalSince1970)
|
||||
|
||||
assertEqual(kissDate!.timeIntervalSince2020, 0)
|
||||
|
||||
let today = Date()
|
||||
let todayTimestampSince2020 = UInt64(today.timeIntervalSince2020)
|
||||
let diffTimeStamp = UInt64(today.timeIntervalSince1970) - timestamp
|
||||
assertEqual(todayTimestampSince2020, diffTimeStamp)
|
||||
}
|
||||
|
||||
let test_3_ParseCandleCsvFileName = {
|
||||
let candleMinName = CandleMinuteFileName()
|
||||
let url = "/Users/ened/Kiss/KissMe/bin/data/000020/min/candle-20230705.csv"
|
||||
guard let (productNo, yyyyMMdd) = candleMinName.matchedUrl(url) else {
|
||||
return
|
||||
}
|
||||
assertEqual(productNo, "000020")
|
||||
assertEqual(yyyyMMdd, "20230705")
|
||||
}
|
||||
|
||||
let test_4_BuildSamsungDB = {
|
||||
let productNo = Self.samsungProductNo
|
||||
let year = Self.year
|
||||
let month = Self.month
|
||||
let csvFiles = Self.collectCsv(productNo: productNo, yyyy: year, MM: month)
|
||||
let dataPath = URL.currentDirectory().appending(path: "data")
|
||||
|
||||
for csvFile in csvFiles {
|
||||
let candleMinName = CandleMinuteFileName()
|
||||
if let (_, yyyyMMdd) = candleMinName.matchedUrl(csvFile.path), let year = Int(yyyyMMdd.prefix(4)) {
|
||||
let yearDbPath = dataPath.appending(path: "\(productNo)/min/candle-\(year).db1")
|
||||
}
|
||||
|
||||
let yearDbPath = dataPath.appending(path: "\(productNo)/min/candle-\(year).db1")
|
||||
try? FileManager.default.removeItem(at: yearDbPath)
|
||||
try? FileManager.default.createDirectory(at: yearDbPath, withIntermediateDirectories: true)
|
||||
|
||||
do {
|
||||
let candles = try [Domestic.Candle].readCsv(fromFile: csvFile)
|
||||
|
||||
let db = try KissDB(directory: yearDbPath)
|
||||
try db.begin()
|
||||
|
||||
for candle in candles {
|
||||
let candleData = try CandleData(candle: candle)
|
||||
let item = KissDB.DataItem(key: candleData.key, value: candleData.data)
|
||||
try db.insertData(item: item)
|
||||
|
||||
assertEqual(candleData.candle, candle)
|
||||
}
|
||||
|
||||
try db.commit()
|
||||
} catch {
|
||||
print("\(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let test_5_CountSamsungDB: () -> Void = {
|
||||
let productNo = Self.samsungProductNo
|
||||
let year = Self.year
|
||||
let yyyyMM = String(year) + Self.month
|
||||
let dataPath = URL.currentDirectory().appending(path: "data")
|
||||
|
||||
let yearDbPath = dataPath.appending(path: "\(productNo)/min/candle-\(year).db1")
|
||||
do {
|
||||
let db = try KissDB(directory: yearDbPath)
|
||||
try db.begin()
|
||||
|
||||
try db.selectData(into: { (dataItem: KissDB.DataItem) -> Bool in
|
||||
let candleData = CandleData(key: dataItem.key, data: dataItem.value)
|
||||
assertEqual(String(candleData.candleDate.prefix(6)), yyyyMM)
|
||||
return true
|
||||
})
|
||||
|
||||
try db.rollback()
|
||||
} catch {
|
||||
print("\(error)")
|
||||
}
|
||||
}
|
||||
|
||||
static let samsungProductNo = "005930"
|
||||
static let year = "2023"
|
||||
static let month = "06"
|
||||
|
||||
static func collectCsv(productNo: String, yyyy: String, MM: String) -> [URL] {
|
||||
guard let enumerator = FileManager.subPathFiles("data/\(productNo)") else {
|
||||
return []
|
||||
}
|
||||
let candleMinName = CandleMinuteFileName()
|
||||
var csvFiles = [URL]()
|
||||
for case let fileUrl as URL in enumerator {
|
||||
guard let (fileProductNo, yyyyMMdd) = candleMinName.matchedUrl(fileUrl.path) else {
|
||||
continue
|
||||
}
|
||||
if fileProductNo == productNo, yyyyMMdd.prefix(4) == yyyy, yyyyMMdd.dropFirst(4).prefix(2) == MM {
|
||||
csvFiles.append(fileUrl)
|
||||
}
|
||||
}
|
||||
return csvFiles
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
KissConsole().run()
|
||||
//KissConsole().run()
|
||||
|
||||
import KissMe
|
||||
|
||||
@@ -17,4 +17,10 @@ import KissMe
|
||||
//test_websocket_dump_data()
|
||||
|
||||
//test_auction()
|
||||
//test_build_min_db()
|
||||
|
||||
func runTests() {
|
||||
let tests = DB1_CandleData_Tests()
|
||||
tests.runTests()
|
||||
}
|
||||
|
||||
runTests()
|
||||
|
||||
Submodule libraries/KissMeme updated: 7769eb3e89...db14c42c4d
@@ -36,6 +36,7 @@
|
||||
341F5F112A1685E700962D48 /* ShopRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5F102A1685E700962D48 /* ShopRequest.swift */; };
|
||||
341F5F142A16CD7A00962D48 /* DomesticShopProduct.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5F132A16CD7A00962D48 /* DomesticShopProduct.swift */; };
|
||||
3435A7F72A35D82000D604F1 /* DomesticShortSelling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3435A7F62A35D82000D604F1 /* DomesticShortSelling.swift */; };
|
||||
346C25DA2CDE1D97003EF8D7 /* KissTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346C25D92CDE1D91003EF8D7 /* KissTestCase.swift */; };
|
||||
34942F562CCA9AD200F85B79 /* DomesticStock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34942F552CCA9AD200F85B79 /* DomesticStock.swift */; };
|
||||
34942F5A2CCA9B2700F85B79 /* DomesticFutures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34942F592CCA9B2700F85B79 /* DomesticFutures.swift */; };
|
||||
349B05172C25B7C600378D55 /* OverseasStockResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349B05162C25B7C600378D55 /* OverseasStockResult.swift */; };
|
||||
@@ -183,6 +184,7 @@
|
||||
341F5F102A1685E700962D48 /* ShopRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShopRequest.swift; sourceTree = "<group>"; };
|
||||
341F5F132A16CD7A00962D48 /* DomesticShopProduct.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticShopProduct.swift; sourceTree = "<group>"; };
|
||||
3435A7F62A35D82000D604F1 /* DomesticShortSelling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticShortSelling.swift; sourceTree = "<group>"; };
|
||||
346C25D92CDE1D91003EF8D7 /* KissTestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KissTestCase.swift; sourceTree = "<group>"; };
|
||||
34942F552CCA9AD200F85B79 /* DomesticStock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticStock.swift; sourceTree = "<group>"; };
|
||||
34942F592CCA9B2700F85B79 /* DomesticFutures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticFutures.swift; sourceTree = "<group>"; };
|
||||
349B05162C25B7C600378D55 /* OverseasStockResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverseasStockResult.swift; sourceTree = "<group>"; };
|
||||
@@ -329,6 +331,7 @@
|
||||
341F5EAD2A0A80EC00962D48 /* KissMe */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
346C25D82CDE1D7A003EF8D7 /* Test */,
|
||||
34F1900D2A426C1C0068C697 /* Context */,
|
||||
34F1900A2A41981A0068C697 /* Index */,
|
||||
341F5EF32A0F88AC00962D48 /* Common */,
|
||||
@@ -416,6 +419,14 @@
|
||||
path = Shop;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
346C25D82CDE1D7A003EF8D7 /* Test */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
346C25D92CDE1D91003EF8D7 /* KissTestCase.swift */,
|
||||
);
|
||||
path = Test;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
34942F582CCA9B1000F85B79 /* Futures */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -827,6 +838,7 @@
|
||||
files = (
|
||||
341F5EFB2A10909D00962D48 /* LoginResult.swift in Sources */,
|
||||
34BC447D2A86635A0052D8EB /* Domestic.ContractPriceWebSocket.swift in Sources */,
|
||||
346C25DA2CDE1D97003EF8D7 /* KissTestCase.swift in Sources */,
|
||||
34C1BA882A5D9A4A00423D64 /* DomesticDartDisclosureInterests.swift in Sources */,
|
||||
340A4DC42A4E4345005A1FBA /* ArrayDecodable.swift in Sources */,
|
||||
34C1BA532A5A683D00423D64 /* DomesticDartBusinessReport.swift in Sources */,
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
341F5F092A1463A100962D48 /* KissConsole.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5F082A1463A100962D48 /* KissConsole.swift */; };
|
||||
3435A7F22A35A8A900D604F1 /* KissConsole+Investor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3435A7F12A35A8A900D604F1 /* KissConsole+Investor.swift */; };
|
||||
3435A7F42A35B4D000D604F1 /* KissConsole+Price.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3435A7F32A35B4D000D604F1 /* KissConsole+Price.swift */; };
|
||||
346C25DD2CDE5652003EF8D7 /* DB1_CandleData_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346C25DC2CDE5652003EF8D7 /* DB1_CandleData_Tests.swift */; };
|
||||
348168492A2F92AC00A50BD3 /* KissContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 348168482A2F92AC00A50BD3 /* KissContext.swift */; };
|
||||
349327F72A20E3E300097063 /* Foundation+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349327F62A20E3E300097063 /* Foundation+Extensions.swift */; };
|
||||
349843212A242AC900E85B08 /* KissConsole+CSV.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349843202A242AC900E85B08 /* KissConsole+CSV.swift */; };
|
||||
@@ -59,6 +60,7 @@
|
||||
341F5F082A1463A100962D48 /* KissConsole.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KissConsole.swift; sourceTree = "<group>"; };
|
||||
3435A7F12A35A8A900D604F1 /* KissConsole+Investor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KissConsole+Investor.swift"; sourceTree = "<group>"; };
|
||||
3435A7F32A35B4D000D604F1 /* KissConsole+Price.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KissConsole+Price.swift"; sourceTree = "<group>"; };
|
||||
346C25DC2CDE5652003EF8D7 /* DB1_CandleData_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DB1_CandleData_Tests.swift; sourceTree = "<group>"; };
|
||||
348168482A2F92AC00A50BD3 /* KissContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KissContext.swift; sourceTree = "<group>"; };
|
||||
349327F62A20E3E300097063 /* Foundation+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Foundation+Extensions.swift"; sourceTree = "<group>"; };
|
||||
3498431E2A24287600E85B08 /* KissMeConsoleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KissMeConsoleTests.swift; sourceTree = "<group>"; };
|
||||
@@ -106,6 +108,7 @@
|
||||
341F5ED22A0A8B9000962D48 /* KissMeConsole */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
346C25DB2CDE2A7F003EF8D7 /* Tests */,
|
||||
341F5ED32A0A8B9000962D48 /* main.swift */,
|
||||
341F5F042A13B82F00962D48 /* test.swift */,
|
||||
34DA3EA32A9A176B00BB3439 /* test_websocket.swift */,
|
||||
@@ -134,6 +137,14 @@
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
346C25DB2CDE2A7F003EF8D7 /* Tests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
346C25DC2CDE5652003EF8D7 /* DB1_CandleData_Tests.swift */,
|
||||
);
|
||||
path = Tests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3498431D2A24284600E85B08 /* KissMeConsoleTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -211,6 +222,7 @@
|
||||
349843212A242AC900E85B08 /* KissConsole+CSV.swift in Sources */,
|
||||
348168492A2F92AC00A50BD3 /* KissContext.swift in Sources */,
|
||||
34DB3C452AA6071D00B6763E /* KissConsole+WebSocket.swift in Sources */,
|
||||
346C25DD2CDE5652003EF8D7 /* DB1_CandleData_Tests.swift in Sources */,
|
||||
3435A7F42A35B4D000D604F1 /* KissConsole+Price.swift in Sources */,
|
||||
34DA3EA42A9A176B00BB3439 /* test_websocket.swift in Sources */,
|
||||
34F190132A4441F00068C697 /* KissConsole+Test.swift in Sources */,
|
||||
|
||||
Reference in New Issue
Block a user