Skip to content

Commit

Permalink
add github action workflow to run tests
Browse files Browse the repository at this point in the history
add section to readme for running tests
add toc to readme
use dedicated xcode build action
fix compile error by renaming function in FMAPI.swift file

split tests into dedicated test cases

skip filter tests during CI

add trigger for pushes to develop
  • Loading branch information
GrayedFox committed Sep 28, 2021
1 parent 58dc248 commit ff85e6c
Show file tree
Hide file tree
Showing 8 changed files with 352 additions and 155 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/pull-request-tasks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Swift Integration Tests

on:
pull_request:
branches:
push:
branches:
- master
- develop

jobs:
test:
name: Tests
runs-on: macos-latest
strategy:
matrix:
destination: ['platform=iOS Simulator,OS=14.4,name=iPhone 12 Pro Max']

steps:
- name: Checkout Code
uses: actions/checkout@v2

- name: Build and Test
uses: sersoft-gmbh/xcodebuild-action@v1
with:
project: FantasmoSDK.xcodeproj
scheme: FantasmoSDKTests
destination: ${{ matrix.destination }}
action: test
skip-testing: 'FantasmoSDKTests/SDKFilterTests/testBlurFilter'
16 changes: 12 additions & 4 deletions FantasmoSDK.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
A0D0C57426BAB96100F35448 /* FMLocationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A02EA34426B9154D00525308 /* FMLocationDelegate.swift */; };
A0D0C57526BAB96500F35448 /* FMZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 946838AA25921BF3005B1145 /* FMZone.swift */; };
A0D0C57726BD086E00F35448 /* MotionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0D0C57626BD086E00F35448 /* MotionManager.swift */; };
A0D5E88A26BA97DA00CE5B1C /* FantasmoSDKTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0D5E88926BA97DA00CE5B1C /* FantasmoSDKTests.swift */; };
A0D5E88A26BA97DA00CE5B1C /* SDKLocationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0D5E88926BA97DA00CE5B1C /* SDKLocationTests.swift */; };
A0D5E88C26BA97DA00CE5B1C /* FantasmoSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9468388B25921BAF005B1145 /* FantasmoSDK.framework */; };
A0D5E89226BA98E900CE5B1C /* CLLocation+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A02EA34A26BA7D8700525308 /* CLLocation+Extension.swift */; };
A0D5E89326BA98ED00CE5B1C /* Array+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A02EA34826B9253900525308 /* Array+Extension.swift */; };
Expand Down Expand Up @@ -92,6 +92,8 @@
A3CB77372636BDB8009625BB /* FMOrientation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3CB77362636BDB8009625BB /* FMOrientation.swift */; };
A3CB773F263710D2009625BB /* simd_float4x4+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3CB773E263710D2009625BB /* simd_float4x4+Extension.swift */; };
A3CB774226372A9B009625BB /* simd_quatf+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3CB774126372A9B009625BB /* simd_quatf+Extension.swift */; };
FFA8586D2701D5D20069EB5D /* SDKFilterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA8586B2701D5D20069EB5D /* SDKFilterTests.swift */; };
FFA8586E2701D5D20069EB5D /* SDKGeometricTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA8586C2701D5D20069EB5D /* SDKGeometricTests.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -145,7 +147,7 @@
A02EA34A26BA7D8700525308 /* CLLocation+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CLLocation+Extension.swift"; sourceTree = "<group>"; };
A0D0C57626BD086E00F35448 /* MotionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MotionManager.swift; sourceTree = "<group>"; };
A0D5E88726BA97DA00CE5B1C /* FantasmoSDKTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FantasmoSDKTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
A0D5E88926BA97DA00CE5B1C /* FantasmoSDKTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FantasmoSDKTests.swift; sourceTree = "<group>"; };
A0D5E88926BA97DA00CE5B1C /* SDKLocationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SDKLocationTests.swift; sourceTree = "<group>"; };
A0D5E88B26BA97DA00CE5B1C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
A30EBE08269F32B200E572FA /* AccumulatedARKitInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccumulatedARKitInfo.swift; sourceTree = "<group>"; };
A30EBE0B269F578E00E572FA /* TotalDeviceTranslationAccumulator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TotalDeviceTranslationAccumulator.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -176,6 +178,8 @@
A3CB773E263710D2009625BB /* simd_float4x4+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "simd_float4x4+Extension.swift"; sourceTree = "<group>"; };
A3CB774126372A9B009625BB /* simd_quatf+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "simd_quatf+Extension.swift"; sourceTree = "<group>"; };
A3EEC0852664EFC6008BCCF2 /* FMFrameFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FMFrameFilter.swift; sourceTree = "<group>"; };
FFA8586B2701D5D20069EB5D /* SDKFilterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SDKFilterTests.swift; sourceTree = "<group>"; };
FFA8586C2701D5D20069EB5D /* SDKGeometricTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SDKGeometricTests.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -330,7 +334,9 @@
A0D5E88826BA97DA00CE5B1C /* FantasmoSDKTests */ = {
isa = PBXGroup;
children = (
A0D5E88926BA97DA00CE5B1C /* FantasmoSDKTests.swift */,
FFA8586B2701D5D20069EB5D /* SDKFilterTests.swift */,
FFA8586C2701D5D20069EB5D /* SDKGeometricTests.swift */,
A0D5E88926BA97DA00CE5B1C /* SDKLocationTests.swift */,
A0D5E88B26BA97DA00CE5B1C /* Info.plist */,
4064380B26E7B1B100B38B45 /* UIImage+Extension.swift */,
);
Expand Down Expand Up @@ -599,18 +605,20 @@
A0D5E89326BA98ED00CE5B1C /* Array+Extension.swift in Sources */,
A0D5E89526BAA54300CE5B1C /* FMError.swift in Sources */,
A0D0C57426BAB96100F35448 /* FMLocationDelegate.swift in Sources */,
A0D5E88A26BA97DA00CE5B1C /* FantasmoSDKTests.swift in Sources */,
A0D5E88A26BA97DA00CE5B1C /* SDKLocationTests.swift in Sources */,
A0D5E89626BAA56100CE5B1C /* ErrorResponse.swift in Sources */,
4064380926E7ABA600B38B45 /* FMBlurFilter.swift in Sources */,
406437FF26E787A300B38B45 /* FMCamera.swift in Sources */,
4064380C26E7B1B100B38B45 /* UIImage+Extension.swift in Sources */,
4064380726E7A76A00B38B45 /* Angle.swift in Sources */,
A0D5E89226BA98E900CE5B1C /* CLLocation+Extension.swift in Sources */,
FFA8586D2701D5D20069EB5D /* SDKFilterTests.swift in Sources */,
4064380326E79C7A00B38B45 /* MockCamera.swift in Sources */,
406437FC26E7864300B38B45 /* FMFrame.swift in Sources */,
A0D5E89426BAA51F00CE5B1C /* FMLog.swift in Sources */,
A0D0C57326BAB95A00F35448 /* LocationFuser.swift in Sources */,
A0D0C57526BAB96500F35448 /* FMZone.swift in Sources */,
FFA8586E2701D5D20069EB5D /* SDKGeometricTests.swift in Sources */,
4064380126E79C0D00B38B45 /* MockFrame.swift in Sources */,
406437F826E7718700B38B45 /* FMMovementFilter.swift in Sources */,
4064380626E7A70E00B38B45 /* FMCameraPitchFilter.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A0D5E88626BA97DA00CE5B1C"
BuildableName = "FantasmoSDKTests.xctest"
BlueprintName = "FantasmoSDKTests"
ReferencedContainer = "container:FantasmoSDK.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
4 changes: 2 additions & 2 deletions FantasmoSDK/Classes/Network/FMApi.swift
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ class FMApi {
"total": events.total,
]

let imageResolution = imageResolution(from: frame, request: request)
let imageResolution = getImageResolution(from: frame, request: request)

var params = [
"intrinsics" : intrinsics.toJson(),
Expand Down Expand Up @@ -298,7 +298,7 @@ class FMApi {
/// - frame: Frame to return the resolution from
/// - request: Localization request struct
/// - Returns: Resolution as CGSize
private func imageResolution(from frame: ARFrame, request: FMLocalizationRequest) -> FMFrameResolution {
private func getImageResolution(from frame: ARFrame, request: FMLocalizationRequest) -> FMFrameResolution {
// mock if simulation
guard !request.isSimulation else {
let imageSize = MockData.imageResolution(request)
Expand Down
103 changes: 103 additions & 0 deletions FantasmoSDKTests/SDKFilterTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
//
// SDKFilterTests.swift
// FantasmoSDKTests
//
// Created by lucas kuzma on 8/4/21.
// Modified by che fisher on 27/9/21

import XCTest
import CoreLocation
import ARKit

class SDKFilterTests: XCTestCase {

override class func setUp() {
// Put setup code here that is run once (equal to mocha "before" hook)
}

override func setUpWithError() throws {
// Put setup code here is run before each test (equal to mocha "beforeEach" hook)
}

override func tearDownWithError() throws {
// Put teardown code that is run after each test case (equal to mocha "afterEach" hook)
}

override class func tearDown() {
// Put teardown code that is run once (equal to mocha "after" hook)
}

// note: this test will not fail and not throw an error code if the pixelBuffer assignment fails
func testMovementFilter() {
let filter = FMMovementFilter()
var transform = simd_float4x4(1)
var pixelBuffer: CVPixelBuffer? = nil
CVPixelBufferCreate(kCFAllocatorDefault, 64, 64, kCVPixelFormatType_OneComponent8, nil, &pixelBuffer)
if let pixelBuffer = pixelBuffer {
var frame = MockFrame(fmCamera: MockCamera(transform: transform), capturedImage: pixelBuffer)
XCTAssertEqual(filter.accepts(frame), .rejected(reason: .movingTooLittle))
transform = simd_float4x4(1.1)
frame = MockFrame(fmCamera: MockCamera(transform: transform), capturedImage: pixelBuffer)
XCTAssertEqual(filter.accepts(frame), .accepted)
transform = simd_float4x4(1.099)
XCTAssertEqual(filter.accepts(frame), .rejected(reason: .movingTooLittle))
} else {
print ("Couldn't allocate mock pixel buffer")
}
}

// note: this test will not fail and not throw an error code if the nonnilBuffer assignment fails
func testCameraPitchFilter() {
let filter = FMCameraPitchFilter()
var pixelBuffer: CVPixelBuffer? = nil
CVPixelBufferCreate(kCFAllocatorDefault, 64, 64, kCVPixelFormatType_OneComponent8, nil, &pixelBuffer)
var pitch : Float = deg2rad(-90)
if let nonnilBuffer = pixelBuffer {
var frame = MockFrame(fmCamera: MockCamera(pitch: pitch), capturedImage: nonnilBuffer)
XCTAssertEqual(filter.accepts(frame), .rejected(reason: .pitchTooLow))
pitch = deg2rad(-65)
frame = MockFrame(fmCamera: MockCamera(pitch: pitch), capturedImage: nonnilBuffer)
XCTAssertEqual(filter.accepts(frame), .accepted)
pitch = deg2rad(0)
frame = MockFrame(fmCamera: MockCamera(pitch: pitch), capturedImage: nonnilBuffer)
XCTAssertEqual(filter.accepts(frame), .accepted)
pitch = deg2rad(30)
frame = MockFrame(fmCamera: MockCamera(pitch: pitch), capturedImage: nonnilBuffer)
XCTAssertEqual(filter.accepts(frame), .accepted)
pitch = deg2rad(60)
frame = MockFrame(fmCamera: MockCamera(pitch: pitch), capturedImage: nonnilBuffer)
XCTAssertEqual(filter.accepts(frame), .rejected(reason: .pitchTooHigh))
} else {
print ("Couldn't allocate mock pixel buffer")
}
}

func testBlurFilter() {
let filter = FMBlurFilter()
let dayScan = UIImage(named: "dayScan", in: Bundle(for: type(of: self)), compatibleWith: nil)
let dayScanFrame = MockFrame(capturedImage: dayScan!.pixelBuffer()!)
let nightScan = UIImage(named: "nightScan", in: Bundle(for: type(of: self)), compatibleWith: nil)
let nightScanFrame = MockFrame(capturedImage: nightScan!.pixelBuffer()!)

// nighttime passes twice because of no throughput
XCTAssertEqual(filter.accepts(nightScanFrame), .accepted)
XCTAssertEqual(filter.accepts(nightScanFrame), .accepted)
// daytime passes because it has enough variance
XCTAssertEqual(filter.accepts(dayScanFrame), .accepted)
XCTAssertEqual(filter.accepts(dayScanFrame), .accepted)
XCTAssertEqual(filter.accepts(dayScanFrame), .accepted)
XCTAssertEqual(filter.accepts(dayScanFrame), .accepted)
// nighttime is rejected 6 times because it is too blurry and the throughput is superior to 0.25 on the last 8 frames
XCTAssertEqual(filter.accepts(nightScanFrame), .rejected(reason: .imageTooBlurry))
XCTAssertEqual(filter.accepts(nightScanFrame), .rejected(reason: .imageTooBlurry))
XCTAssertEqual(filter.accepts(nightScanFrame), .rejected(reason: .imageTooBlurry))
XCTAssertEqual(filter.accepts(nightScanFrame), .rejected(reason: .imageTooBlurry))
XCTAssertEqual(filter.accepts(nightScanFrame), .rejected(reason: .imageTooBlurry))
XCTAssertEqual(filter.accepts(nightScanFrame), .rejected(reason: .imageTooBlurry))
// on the 7th nighttime picture in a row, throughput gets back under 0.25 and it passes again
XCTAssertEqual(filter.accepts(nightScanFrame), .accepted)
XCTAssertEqual(filter.accepts(nightScanFrame), .accepted)
XCTAssertEqual(filter.accepts(nightScanFrame), .accepted)
XCTAssertEqual(filter.accepts(nightScanFrame), .accepted)
}
}
97 changes: 97 additions & 0 deletions FantasmoSDKTests/SDKGeometricTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
//
// SDKGeometricTests.swift
// FantasmoSDKTests
//
// Created by lucas kuzma on 8/4/21.
// Modified by che fisher on 27/9/21.

import XCTest
import CoreLocation
import ARKit

class SDKGeometricTests: XCTestCase {

override class func setUp() {
// Put setup code here that is run once (equal to mocha "before" hook)
}

override func setUpWithError() throws {
// Put setup code here is run before each test (equal to mocha "beforeEach" hook)
}

override func tearDownWithError() throws {
// Put teardown code that is run after each test case (equal to mocha "afterEach" hook)
}

override class func tearDown() {
// Put teardown code that is run once (equal to mocha "after" hook)
}

func testGeometricMedian() throws {
var locations: [CLLocation] = []
var median = CLLocation()
var expected = CLLocation()

locations.append(CLLocation(latitude: 0, longitude: 0))
median = CLLocation.geometricMedian(locations)
print(median.coordinate)

expected = CLLocation(latitude: 0, longitude: 0);
XCTAssertLessThan(median.degreeDistance(from: expected), 0.001)

locations = []
locations.append(CLLocation(latitude: 10, longitude: 0))
locations.append(CLLocation(latitude: -10, longitude: 0))
median = CLLocation.geometricMedian(locations)
print(median.coordinate)

expected = CLLocation(latitude: 0, longitude: 0);
XCTAssertLessThan(median.degreeDistance(from: expected), 0.001)

locations.append(CLLocation(latitude: 0, longitude: 10))
median = CLLocation.geometricMedian(locations)
print(median.coordinate)

expected = CLLocation(latitude: 0, longitude: 5.77);
XCTAssertLessThan(median.degreeDistance(from: expected), 0.01)

locations = []
locations.append(CLLocation(latitude: 10, longitude: 10))
locations.append(CLLocation(latitude: 20, longitude: 10))
locations.append(CLLocation(latitude: 10, longitude: 20))
locations.append(CLLocation(latitude: 20, longitude: 20))
median = CLLocation.geometricMedian(locations)
print(median.coordinate)

expected = CLLocation(latitude: 15, longitude: 15);
XCTAssertLessThan(median.degreeDistance(from: expected), 0.01)

locations.append(CLLocation(latitude: 15, longitude: 15))
median = CLLocation.geometricMedian(locations)
print(median.coordinate)

XCTAssertLessThan(median.degreeDistance(from: expected), 0.01)
}

func testGeometricMedianColinear() throws {
var locations: [CLLocation] = []
var median = CLLocation()
var expected = CLLocation()

locations = []
locations.append(CLLocation(latitude: 0, longitude: 0))
locations.append(CLLocation(latitude: 0, longitude: 10))
median = CLLocation.geometricMedian(locations)
print(median.coordinate)

expected = CLLocation(latitude: 0, longitude: 5);
XCTAssertLessThan(median.degreeDistance(from: expected), 0.01)

locations.append(CLLocation(latitude: 0, longitude: 20))
median = CLLocation.geometricMedian(locations)
print(median.coordinate)

expected = CLLocation(latitude: 0, longitude: 10);
XCTAssertLessThan(median.degreeDistance(from: expected), 0.01)
}
}
Loading

0 comments on commit ff85e6c

Please sign in to comment.