Skip to content

Commit

Permalink
refactoring test: in separate files
Browse files Browse the repository at this point in the history
  • Loading branch information
kosyloa committed Apr 17, 2024
1 parent 4a8eec5 commit 5ac9722
Show file tree
Hide file tree
Showing 11 changed files with 287 additions and 247 deletions.
5 changes: 5 additions & 0 deletions DXFeedFramework.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
642DC9432AAA299800974F5C /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 646979712A3B5AF60003A9BA /* Colors.xcassets */; };
642DC9442AAA29EA00974F5C /* IpfCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 642DC9402AAA290300974F5C /* IpfCell.swift */; };
6433B12D2BCE7ADD004EFED7 /* DXFeed+LastEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6433B12C2BCE7ADD004EFED7 /* DXFeed+LastEvents.swift */; };
6433B1322BCFC01F004EFED7 /* DXLastEventsSubscribedTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6433B1312BCFC01F004EFED7 /* DXLastEventsSubscribedTest.swift */; };
64437A8F2A9DEE6F005929B2 /* InstrumentProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64437A8E2A9DEE6F005929B2 /* InstrumentProfile.swift */; };
64437A922A9DF1DE005929B2 /* NativeInstrumentProfileReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64437A912A9DF1DE005929B2 /* NativeInstrumentProfileReader.swift */; };
6447A5DB2A8E559000739CCF /* ILastingEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6447A5DA2A8E559000739CCF /* ILastingEvent.swift */; };
Expand Down Expand Up @@ -665,6 +666,7 @@
642DC9402AAA290300974F5C /* IpfCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IpfCell.swift; sourceTree = "<group>"; };
6433B12C2BCE7ADD004EFED7 /* DXFeed+LastEvents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DXFeed+LastEvents.swift"; sourceTree = "<group>"; };
6433B1302BCE87D4004EFED7 /* RequestProfile.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = RequestProfile.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
6433B1312BCFC01F004EFED7 /* DXLastEventsSubscribedTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DXLastEventsSubscribedTest.swift; sourceTree = "<group>"; };
6435EE3C2B1F1E9200E8496C /* PrintQuoteEvents.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = PrintQuoteEvents.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
64437A8E2A9DEE6F005929B2 /* InstrumentProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstrumentProfile.swift; sourceTree = "<group>"; };
64437A912A9DF1DE005929B2 /* NativeInstrumentProfileReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeInstrumentProfileReader.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1641,6 +1643,7 @@
641C64B32B347C430023CFAD /* DXObservableSubscriptionTest.swift */,
6423E4682B457000006B208D /* DXTimeSeriesSubscriptionTest.swift */,
646064E92B4D8973009201E2 /* DXLastEventTest.swift */,
6433B1312BCFC01F004EFED7 /* DXLastEventsSubscribedTest.swift */,
64EAA1A12B7A38F8005087BC /* DXPromiseTest.swift */,
64DF09342BC924AB009F1486 /* DXAsyncLastTest.swift */,
64EAA1A52B838ED3005087BC /* DXSnapshotProcessorTest.swift */,
Expand Down Expand Up @@ -2176,6 +2179,7 @@
/* Begin PBXShellScriptBuildPhase section */
64656F632A1BB22E006A0B19 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
Expand Down Expand Up @@ -2591,6 +2595,7 @@
649813C42ADD5CB2003CE3B3 /* TestEndpoointStateListener.swift in Sources */,
641C64B42B347C430023CFAD /* DXObservableSubscriptionTest.swift in Sources */,
64ACBCEC2A29FE2300032C53 /* XCTestCase+Utils.swift in Sources */,
6433B1322BCFC01F004EFED7 /* DXLastEventsSubscribedTest.swift in Sources */,
6423E4692B457000006B208D /* DXTimeSeriesSubscriptionTest.swift in Sources */,
64ECD67F2A9CF4CB00B36935 /* IPFTests.swift in Sources */,
64ACBCD52A2789EF00032C53 /* TestListener.swift in Sources */,
Expand Down
4 changes: 3 additions & 1 deletion DXFeedFramework/Api/Osub/TimeSeriesSubscriptionSymbol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ public class TimeSeriesSubscriptionSymbol: GenericIndexedEventSubscriptionSymbol

/// Custom symbol has to return string representation.
public override var stringValue: String {
return "\(symbol.description){fromTime=\((try? DXTimeFormat.defaultTimeFormat?.withMillis?.format(value: fromTime)) ?? "")}"
return """
\(symbol.description){fromTime=\((try? DXTimeFormat.defaultTimeFormat?.withMillis?.format(value: fromTime)) ?? "")}
"""
}
}

Expand Down
185 changes: 95 additions & 90 deletions DXFeedFramework/Native/Feed/NativeFeed.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,96 +101,6 @@ class NativeFeed {
return event?.lastingEvent
}

func getLastEventIfSubscribed(type: IEventType.Type, symbol: Symbol) throws -> ILastingEvent? {
let thread = currentThread()
let converted = SymbolMapper.newNative(symbol)
defer {
if let converted = converted {
SymbolMapper.clearNative(symbol: converted)
}
}
do {
let result = try ErrorCheck.nativeCall(thread,
dxfg_DXFeed_getLastEventIfSubscribed(thread,
feed,
type.type.nativeCode(),
converted))
return try mapper.fromNative(native: result)?.lastingEvent
} catch GraalException.nullException {
return nil
}
}

func getIndexedEventsIfSubscribed(type: IEventType.Type,
symbol: Symbol,
source: IndexedEventSource) throws -> [IIndexedEvent]? {
let thread = currentThread()
let converted = SymbolMapper.newNative(symbol)
defer {
if let converted = converted {
SymbolMapper.clearNative(symbol: converted)
}
}
do {
let result = try ErrorCheck.nativeCall(thread,
dxfg_DXFeed_getIndexedEventsIfSubscribed(thread,
feed,
type.type.nativeCode(),
converted,
source.name.toCStringRef()))
if result.pointee.size == 0 {
return nil
} else {
let events: [IIndexedEvent] =
(0..<Int(result.pointee.size)).compactMap { index in
guard let nativeElement = result.pointee.elements[index] else { return nil }
let event = try? mapper.fromNative(native: nativeElement)
return event?.indexedEvent
}
return events

}
} catch GraalException.nullException {
return nil
}
}

func getTimeSeriesIfSubscribed(type: IEventType.Type,
symbol: Symbol,
fromTime: Long,
toTime: Long) throws -> [ITimeSeriesEvent]? {
let thread = currentThread()
let converted = SymbolMapper.newNative(symbol)
defer {
if let converted = converted {
SymbolMapper.clearNative(symbol: converted)
}
}
do {
let result = try ErrorCheck.nativeCall(thread,
dxfg_DXFeed_getTimeSeriesIfSubscribed(thread,
feed,
type.type.nativeCode(),
converted,
fromTime,
toTime))
if result.pointee.size == 0 {
return nil
} else {
let events: [ITimeSeriesEvent] =
(0..<Int(result.pointee.size)).compactMap { index in
guard let nativeElement = result.pointee.elements[index] else { return nil }
let event = try? mapper.fromNative(native: nativeElement)
return event?.timeSeriesEvent
}
return events

}
} catch GraalException.nullException {
return nil
}
}

func getLastEvents(types: [MarketEvent]) throws -> [ILastingEvent] {
let listPointer = UnsafeMutablePointer<dxfg_event_type_list>.allocate(capacity: 1)
listPointer.pointee.size = Int32(types.count)
Expand Down Expand Up @@ -316,7 +226,9 @@ class NativeFeed {
toTime))
return NativePromise(promise: &native.pointee.base)
}
}

extension NativeFeed {
func attach(subscription: NativeSubscription) throws {
let thread = currentThread()
try ErrorCheck.nativeCall(thread,
Expand All @@ -333,3 +245,96 @@ class NativeFeed {
subscription.subscription))
}
}

extension NativeFeed {
func getLastEventIfSubscribed(type: IEventType.Type, symbol: Symbol) throws -> ILastingEvent? {
let thread = currentThread()
let converted = SymbolMapper.newNative(symbol)
defer {
if let converted = converted {
SymbolMapper.clearNative(symbol: converted)
}
}
do {
let result = try ErrorCheck.nativeCall(thread,
dxfg_DXFeed_getLastEventIfSubscribed(thread,
feed,
type.type.nativeCode(),
converted))
return try mapper.fromNative(native: result)?.lastingEvent
} catch GraalException.nullException {
return nil
}
}

func getIndexedEventsIfSubscribed(type: IEventType.Type,
symbol: Symbol,
source: IndexedEventSource) throws -> [IIndexedEvent]? {
let thread = currentThread()
let converted = SymbolMapper.newNative(symbol)
defer {
if let converted = converted {
SymbolMapper.clearNative(symbol: converted)
}
}
do {
let result = try ErrorCheck.nativeCall(thread,
dxfg_DXFeed_getIndexedEventsIfSubscribed(thread,
feed,
type.type.nativeCode(),
converted,
source.name.toCStringRef()))
if result.pointee.size == 0 {
return nil
} else {
let events: [IIndexedEvent] =
(0..<Int(result.pointee.size)).compactMap { index in
guard let nativeElement = result.pointee.elements[index] else { return nil }
let event = try? mapper.fromNative(native: nativeElement)
return event?.indexedEvent
}
return events

}
} catch GraalException.nullException {
return nil
}
}

func getTimeSeriesIfSubscribed(type: IEventType.Type,
symbol: Symbol,
fromTime: Long,
toTime: Long) throws -> [ITimeSeriesEvent]? {
let thread = currentThread()
let converted = SymbolMapper.newNative(symbol)
defer {
if let converted = converted {
SymbolMapper.clearNative(symbol: converted)
}
}
do {
let result = try ErrorCheck.nativeCall(thread,
dxfg_DXFeed_getTimeSeriesIfSubscribed(thread,
feed,
type.type.nativeCode(),
converted,
fromTime,
toTime))
if result.pointee.size == 0 {
return nil
} else {
let events: [ITimeSeriesEvent] =
(0..<Int(result.pointee.size)).compactMap { index in
guard let nativeElement = result.pointee.elements[index] else { return nil }
let event = try? mapper.fromNative(native: nativeElement)
return event?.timeSeriesEvent
}
return events

}
} catch GraalException.nullException {
return nil
}
}

}
4 changes: 3 additions & 1 deletion DXFeedFrameworkTests/CandleTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,9 @@ final class CandleTests: XCTestCase {

XCTAssertEqual("EUR/USD{=2h,price=bid,source=bank}",
CandleSymbol.valueOf("EUR/USD{source=bank}",
[CandlePrice.bid, CandlePeriod.valueOf(value: 2, type: CandleType.hour)]).toString())
[CandlePrice.bid,
CandlePeriod.valueOf(value: 2, type: CandleType.hour)]
).toString())
XCTAssertEqual("IBM{=15m,aa=zz,price=bid}",
CandleSymbol.valueOf("IBM{aa=zz,price=b}",
[CandlePeriod.valueOf(value: 15, type: CandleType.minute)]).toString())
Expand Down
92 changes: 48 additions & 44 deletions DXFeedFrameworkTests/DXAttachTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,59 +11,63 @@ import XCTest
final class DXAttachTest: XCTestCase {
let detachedSymbol = "TEST1"
let attachedSymbol = "TEST2"
var endpoint: DXEndpoint!
var feed: DXFeed!
var publisher: DXPublisher!

override func setUpWithError() throws {
endpoint = try DXEndpoint.create()
feed = endpoint.getFeed()
publisher = endpoint.getPublisher()
}

func testAttachDetach() throws {
let endpoint = try DXEndpoint.create()
do {
if let feed = endpoint.getFeed(), let publisher = endpoint.getPublisher() {
let subcription = try feed.createSubscription([TimeAndSale.self])
let expectation1 = expectation(description: "Events received")
let expectation2 = expectation(description: "Events received")
let listener = AnonymousClass { anonymCl in
anonymCl.callback = { events in
events.forEach { event in
switch event.eventSymbol {
case self.detachedSymbol:
XCTFail("Received detached symbol \(event.toString())")
case self.attachedSymbol:
if event.timeAndSale.askPrice == 100 {
expectation1.fulfill()
} else if event.timeAndSale.askPrice == 200 {
expectation2.fulfill()
}
default:
XCTFail("Unexpected symbol \(event.toString())")
let subcription = try feed.createSubscription([TimeAndSale.self])
let expectation1 = expectation(description: "Events received")
let expectation2 = expectation(description: "Events received")
let listener = AnonymousClass { anonymCl in
anonymCl.callback = { events in
events.forEach { event in
switch event.eventSymbol {
case self.detachedSymbol:
XCTFail("Received detached symbol \(event.toString())")
case self.attachedSymbol:
if event.timeAndSale.askPrice == 100 {
expectation1.fulfill()
} else if event.timeAndSale.askPrice == 200 {
expectation2.fulfill()
}
default:
XCTFail("Unexpected symbol \(event.toString())")
}
}
return anonymCl
}
try subcription.add(listener: listener)
try subcription.addSymbols(detachedSymbol)
try feed.detach(subscription: subcription)
try publisher.publish(events: [TimeAndSale(detachedSymbol)])
try feed.attach(subscription: subcription)
try feed.attach(subscription: subcription)
try subcription.addSymbols(attachedSymbol)
return anonymCl
}
try subcription.add(listener: listener)
try subcription.addSymbols(detachedSymbol)
try feed.detach(subscription: subcription)
try publisher.publish(events: [TimeAndSale(detachedSymbol)])
try feed.attach(subscription: subcription)
try feed.attach(subscription: subcription)
try subcription.addSymbols(attachedSymbol)

try publisher.publish(events: [TimeAndSale(attachedSymbol).also(block: { tns in
tns.askPrice = 100
})])
wait(for: [expectation1], timeout: 1)
try subcription.detach(feed: feed)
try publisher.publish(events: [TimeAndSale(detachedSymbol)])
try subcription.attach(feed: feed)
try publisher.publish(events: [TimeAndSale(attachedSymbol).also(block: { tns in
tns.askPrice = 200
})])
wait(for: [expectation2], timeout: 1)
let symbols = try subcription.getSymbols().map { symbol in
symbol.stringValue
}
XCTAssert(Set(symbols) == Set([attachedSymbol, detachedSymbol]))
} else {
XCTAssert(false, "Subscription returned null")
try publisher.publish(events: [TimeAndSale(attachedSymbol).also(block: { tns in
tns.askPrice = 100
})])
wait(for: [expectation1], timeout: 1)
try subcription.detach(feed: feed)
try publisher.publish(events: [TimeAndSale(detachedSymbol)])
try subcription.attach(feed: feed)
try publisher.publish(events: [TimeAndSale(attachedSymbol).also(block: { tns in
tns.askPrice = 200
})])
wait(for: [expectation2], timeout: 1)
let symbols = try subcription.getSymbols().map { symbol in
symbol.stringValue
}
XCTAssert(Set(symbols) == Set([attachedSymbol, detachedSymbol]))
} catch {
XCTAssert(false, "Error during attach/detach \(error)")
}
Expand Down
Loading

0 comments on commit 5ac9722

Please sign in to comment.