Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 6.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Debug;
Expand All @@ -610,7 +610,7 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.packages.interactiveMediaAdsExample.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 6.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Release;
Expand All @@ -626,7 +626,7 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.packages.interactiveMediaAdsExample.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 6.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Profile;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,109 +4,103 @@

import Flutter
import GoogleInteractiveMediaAds
import XCTest
import Testing

@testable import interactive_media_ads

final class AdDisplayContainerTests: XCTestCase {
func testPigeonDefaultConstructor() {
@MainActor
struct AdDisplayContainerTests {
@Test func pigeonDefaultConstructor() throws {
let registrar = TestProxyApiRegistrar()
let api = registrar.apiDelegate.pigeonApiIMAAdDisplayContainer(registrar)

let instance = try? api.pigeonDelegate.pigeonDefaultConstructor(
let instance = try api.pigeonDelegate.pigeonDefaultConstructor(
pigeonApi: api, adContainer: UIView(), companionSlots: [],
adContainerViewController: UIViewController())
XCTAssertNotNil(instance)
}

func testAdContainer() {
@Test func adContainer() throws {
let registrar = TestProxyApiRegistrar()
let api = registrar.apiDelegate.pigeonApiIMAAdDisplayContainer(registrar)

let instance = TestAdDisplayContainer()
let value = try? api.pigeonDelegate.adContainer(pigeonApi: api, pigeonInstance: instance)
let instance = TestAdDisplayContainer(
adContainer: UIView(), viewController: UIViewController())
let value = try api.pigeonDelegate.adContainer(pigeonApi: api, pigeonInstance: instance)

XCTAssertEqual(value, instance.adContainer)
#expect(value == instance.adContainer)
}

func testCompanionSlots() {
@Test func companionSlots() throws {
let registrar = TestProxyApiRegistrar()
let api = registrar.apiDelegate.pigeonApiIMAAdDisplayContainer(registrar)

let instance = TestAdDisplayContainer()
let value = try? api.pigeonDelegate.companionSlots(pigeonApi: api, pigeonInstance: instance)
let instance = TestAdDisplayContainer(
adContainer: UIView(),
viewController: UIViewController(),
companionSlots: [IMACompanionAdSlot(view: UIView())])
let value = try api.pigeonDelegate.companionSlots(pigeonApi: api, pigeonInstance: instance)

XCTAssertEqual(value, instance.companionSlots)
#expect(value == instance.companionSlots)
}

func testSetAdContainerViewController() {
@Test func setAdContainerViewController() throws {
let registrar = TestProxyApiRegistrar()
let api = registrar.apiDelegate.pigeonApiIMAAdDisplayContainer(registrar)

let instance = TestAdDisplayContainer()
let instance = TestAdDisplayContainer(
adContainer: UIView(), viewController: UIViewController())
let controller = UIViewController()
try? api.pigeonDelegate.setAdContainerViewController(
try api.pigeonDelegate.setAdContainerViewController(
pigeonApi: api, pigeonInstance: instance, controller: controller)

XCTAssertEqual(instance.adContainerViewController, controller)
#expect(instance.adContainerViewController == controller)
}

func testGetAdContainerViewController() {
@Test func getAdContainerViewController() throws {
let registrar = TestProxyApiRegistrar()
let api = registrar.apiDelegate.pigeonApiIMAAdDisplayContainer(registrar)

let instance = TestAdDisplayContainer()
let instance = TestAdDisplayContainer(
adContainer: UIView(), viewController: UIViewController())
let adContainerViewController = UIViewController()
instance.adContainerViewController = adContainerViewController
let value = try? api.pigeonDelegate.getAdContainerViewController(
let value = try api.pigeonDelegate.getAdContainerViewController(
pigeonApi: api, pigeonInstance: instance)

XCTAssertEqual(value, adContainerViewController)
#expect(value == adContainerViewController)
}

func testRegisterFriendlyObstruction() {
@Test func registerFriendlyObstruction() throws {
let registrar = TestProxyApiRegistrar()
let api = registrar.apiDelegate.pigeonApiIMAAdDisplayContainer(registrar)

let instance = TestAdDisplayContainer()
let instance = TestAdDisplayContainer(
adContainer: UIView(), viewController: UIViewController())
let friendlyObstruction = IMAFriendlyObstruction(
view: UIView(), purpose: IMAFriendlyObstructionPurpose.closeAd, detailedReason: "reason")
try? api.pigeonDelegate.registerFriendlyObstruction(
try api.pigeonDelegate.registerFriendlyObstruction(
pigeonApi: api, pigeonInstance: instance, friendlyObstruction: friendlyObstruction)

XCTAssertEqual(instance.registerFriendlyObstructionArgs, [friendlyObstruction])
#expect(instance.registerFriendlyObstructionArgs as! [AnyHashable] == [friendlyObstruction])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we fix the type definition instead to avoid the unsafe cast?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better for it to crash in a test, or explicitly fail, we'll get a nice stack that says it's expected to be AnyHashable but instead it's X. That preferred pattern is why hard-assert patterns like try #require are being adopted.
I could swap it to a more explicit type check assert:

let registerFriendlyObstructionArgs = try #require(instance.registerFriendlyObstructionArgs as? [AnyHashable])
#expect(registerFriendlyObstructionArgs == [friendlyObstruction])

though in practice I you'll get the same information either way it crashes.

}

func testUnregisterAllFriendlyObstructions() {
@Test func unregisterAllFriendlyObstructions() throws {
let registrar = TestProxyApiRegistrar()
let api = registrar.apiDelegate.pigeonApiIMAAdDisplayContainer(registrar)

let instance = TestAdDisplayContainer()
try? api.pigeonDelegate.unregisterAllFriendlyObstructions(
let instance = TestAdDisplayContainer(
adContainer: UIView(), viewController: UIViewController())
try api.pigeonDelegate.unregisterAllFriendlyObstructions(
pigeonApi: api, pigeonInstance: instance)

XCTAssertTrue(instance.unregisterAllFriendlyObstructionsCalled)
#expect(instance.unregisterAllFriendlyObstructionsCalled)
}
}

class TestAdDisplayContainer: IMAAdDisplayContainer {
private var adContainerTestValue = UIView()
private var companionSlotsTestValue = [IMACompanionAdSlot(view: UIView())]
class TestAdDisplayContainer: IMAAdDisplayContainer, @unchecked Sendable {
var registerFriendlyObstructionArgs: [AnyHashable?]? = nil
var unregisterAllFriendlyObstructionsCalled = false

convenience init() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I deleted this convenience method because IMAAdDisplayContainer is still an Objective-C class, and creating @MainActor classes like UIView in a non-MainActor init, I was doing acrobatics with like MainActor.assumeIsolated, but IMACompanionAdSlot is also an Objective-C class, so it wasn't @Sendable, which it needs to be when returned from MainActor.assumeIsolated, etc, etc.

There's some duplication in the tests now, but the one @unchecked Sendable is cleaner than all that.

self.init(adContainer: UIView(), viewController: UIViewController())
}

override var adContainer: UIView {
return adContainerTestValue
}

override var companionSlots: [IMACompanionAdSlot] {
return companionSlotsTestValue
}

override func register(_ friendlyObstruction: IMAFriendlyObstruction) {
registerFriendlyObstructionArgs = [friendlyObstruction]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,42 @@

import Flutter
import GoogleInteractiveMediaAds
import XCTest
import Testing

@testable import interactive_media_ads

final class AdErrorTests: XCTestCase {
func testType() {
struct AdErrorTests {
@Test func type() throws {
let registrar = TestProxyApiRegistrar()
let api = registrar.apiDelegate.pigeonApiIMAAdError(registrar)

let instance = TestAdError.customInit()

let value = try? api.pigeonDelegate.type(pigeonApi: api, pigeonInstance: instance)
let value = try api.pigeonDelegate.type(pigeonApi: api, pigeonInstance: instance)

XCTAssertEqual(value, .loadingFailed)
#expect(value == .loadingFailed)
}

func testCode() {
@Test func code() throws {
let registrar = TestProxyApiRegistrar()
let api = registrar.apiDelegate.pigeonApiIMAAdError(registrar)

let instance = TestAdError.customInit()

let value = try? api.pigeonDelegate.code(pigeonApi: api, pigeonInstance: instance)
let value = try api.pigeonDelegate.code(pigeonApi: api, pigeonInstance: instance)

XCTAssertEqual(value, .apiError)
#expect(value == .apiError)
}

func testMessage() {
@Test func message() throws {
let registrar = TestProxyApiRegistrar()
let api = registrar.apiDelegate.pigeonApiIMAAdError(registrar)

let instance = TestAdError.customInit()

let value = try? api.pigeonDelegate.message(pigeonApi: api, pigeonInstance: instance)
let value = try api.pigeonDelegate.message(pigeonApi: api, pigeonInstance: instance)

XCTAssertEqual(value, "message")
#expect(value == "message")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,53 @@

import Flutter
import GoogleInteractiveMediaAds
import XCTest
import Testing

@testable import interactive_media_ads

final class AdEventTests: XCTestCase {
func testType() {
struct AdEventTests {
@Test func type() throws {
let registrar = TestProxyApiRegistrar()
let api = registrar.apiDelegate.pigeonApiIMAAdEvent(registrar)

let instance = TestAdEvent.customInit()

let value = try? api.pigeonDelegate.type(pigeonApi: api, pigeonInstance: instance)
let value = try api.pigeonDelegate.type(pigeonApi: api, pigeonInstance: instance)

XCTAssertEqual(value, .adBreakEnded)
#expect(value == .adBreakEnded)
}

func testMessage() {
@Test func message() throws {
let registrar = TestProxyApiRegistrar()
let api = registrar.apiDelegate.pigeonApiIMAAdEvent(registrar)

let instance = TestAdEvent.customInit()

let value = try? api.pigeonDelegate.typeString(pigeonApi: api, pigeonInstance: instance)
let value = try api.pigeonDelegate.typeString(pigeonApi: api, pigeonInstance: instance)

XCTAssertEqual(value, "message")
#expect(value == "message")
}

func testAdData() {
@Test func adData() throws {
let registrar = TestProxyApiRegistrar()
let api = registrar.apiDelegate.pigeonApiIMAAdEvent(registrar)

let instance = TestAdEvent.customInit()

let value = try? api.pigeonDelegate.adData(pigeonApi: api, pigeonInstance: instance)
let value = try api.pigeonDelegate.adData(pigeonApi: api, pigeonInstance: instance)

XCTAssertEqual(value as! [String: String], ["my": "string"])
#expect((value as! [String: String]) == ["my": "string"])
}

func testAd() {
@Test func ad() throws {
let registrar = TestProxyApiRegistrar()
let api = registrar.apiDelegate.pigeonApiIMAAdEvent(registrar)

let instance = TestAdEvent.customInit()
let value = try? api.pigeonDelegate.ad(pigeonApi: api, pigeonInstance: instance)
let value = try api.pigeonDelegate.ad(pigeonApi: api, pigeonInstance: instance)

XCTAssertNotNil(value)
XCTAssertEqual(value, instance.ad)
#expect(value != nil)
#expect(value == instance.ad)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@

import Flutter
import GoogleInteractiveMediaAds
import XCTest
import Testing

@testable import interactive_media_ads

final class AdLoadingErrorTests: XCTestCase {
func testAdError() {
struct AdLoadingErrorTests {
@Test func adError() throws {
let registrar = TestProxyApiRegistrar()
let api = registrar.apiDelegate.pigeonApiIMAAdLoadingErrorData(registrar)

let instance = TestAdLoadingErrorData.customInit()

let value = try? api.pigeonDelegate.adError(pigeonApi: api, pigeonInstance: instance)
let value = try api.pigeonDelegate.adError(pigeonApi: api, pigeonInstance: instance)

XCTAssertTrue(value is TestAdError)
#expect(value is TestAdError)
}
}

Expand Down
Loading
Loading