Handle multithreaded access crashes on unit tests using generated mocks

- always dispatch receivedInvocations mutations on the main queue
This commit is contained in:
Stefan Ceriu 2024-06-13 13:21:47 +03:00 committed by Stefan Ceriu
parent 8b3141ffec
commit b8dea8ac4e
5 changed files with 912 additions and 304 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -24,11 +24,15 @@ import {{ import }}
{% endset %} {% endset %}
{% if method.parameters.count == 1 and not hasNonEscapingClosures %} {% if method.parameters.count == 1 and not hasNonEscapingClosures %}
{% call swiftifyMethodName method.selectorName %}Received{% for param in method.parameters %}{{ param.name | replace:"`","" | upperFirstLetter }} = {{ param.name | replace:"`","" }}{% endfor %} {% call swiftifyMethodName method.selectorName %}Received{% for param in method.parameters %}{{ param.name | replace:"`","" | upperFirstLetter }} = {{ param.name | replace:"`","" }}{% endfor %}
{% call swiftifyMethodName method.selectorName %}ReceivedInvocations.append({% for param in method.parameters %}{{ param.name }}){% endfor %} DispatchQueue.main.async {
self.{% call swiftifyMethodName method.selectorName %}ReceivedInvocations.append({% for param in method.parameters %}{{ param.name }}){% endfor %}
}
{% else %} {% else %}
{% if not method.parameters.count == 0 and not hasNonEscapingClosures %} {% if not method.parameters.count == 0 and not hasNonEscapingClosures %}
{% call swiftifyMethodName method.selectorName %}ReceivedArguments = ({% for param in method.parameters %}{{ param.name | replace:"`","" }}: {{ param.name | replace:"`","" }}{% if not forloop.last%}, {% endif %}{% endfor %}) {% call swiftifyMethodName method.selectorName %}ReceivedArguments = ({% for param in method.parameters %}{{ param.name | replace:"`","" }}: {{ param.name | replace:"`","" }}{% if not forloop.last%}, {% endif %}{% endfor %})
{% call swiftifyMethodName method.selectorName %}ReceivedInvocations.append(({% for param in method.parameters %}{{ param.name | replace:"`","" }}: {{ param.name | replace:"`","" }}{% if not forloop.last%}, {% endif %}{% endfor %})) DispatchQueue.main.async {
self.{% call swiftifyMethodName method.selectorName %}ReceivedInvocations.append(({% for param in method.parameters %}{{ param.name | replace:"`","" }}: {{ param.name | replace:"`","" }}{% if not forloop.last%}, {% endif %}{% endfor %}))
}
{% endif %} {% endif %}
{% endif %} {% endif %}
{% endmacro %} {% endmacro %}

View File

@ -24,11 +24,15 @@ import {{ import }}
{% endset %} {% endset %}
{% if method.parameters.count == 1 and not hasNonEscapingClosures %} {% if method.parameters.count == 1 and not hasNonEscapingClosures %}
{% call swiftifyMethodName method.selectorName %}Received{% for param in method.parameters %}{{ param.name | replace:"`","" | upperFirstLetter }} = {{ param.name | replace:"`","" }}{% endfor %} {% call swiftifyMethodName method.selectorName %}Received{% for param in method.parameters %}{{ param.name | replace:"`","" | upperFirstLetter }} = {{ param.name | replace:"`","" }}{% endfor %}
{% call swiftifyMethodName method.selectorName %}ReceivedInvocations.append({% for param in method.parameters %}{{ param.name }}){% endfor %} DispatchQueue.main.async {
self.{% call swiftifyMethodName method.selectorName %}ReceivedInvocations.append({% for param in method.parameters %}{{ param.name }}){% endfor %}
}
{% else %} {% else %}
{% if not method.parameters.count == 0 and not hasNonEscapingClosures %} {% if not method.parameters.count == 0 and not hasNonEscapingClosures %}
{% call swiftifyMethodName method.selectorName %}ReceivedArguments = ({% for param in method.parameters %}{{ param.name | replace:"`","" }}: {{ param.name | replace:"`","" }}{% if not forloop.last%}, {% endif %}{% endfor %}) {% call swiftifyMethodName method.selectorName %}ReceivedArguments = ({% for param in method.parameters %}{{ param.name | replace:"`","" }}: {{ param.name | replace:"`","" }}{% if not forloop.last%}, {% endif %}{% endfor %})
{% call swiftifyMethodName method.selectorName %}ReceivedInvocations.append(({% for param in method.parameters %}{{ param.name | replace:"`","" }}: {{ param.name | replace:"`","" }}{% if not forloop.last%}, {% endif %}{% endfor %})) DispatchQueue.main.async {
self.{% call swiftifyMethodName method.selectorName %}ReceivedInvocations.append(({% for param in method.parameters %}{{ param.name | replace:"`","" }}: {{ param.name | replace:"`","" }}{% if not forloop.last%}, {% endif %}{% endfor %}))
}
{% endif %} {% endif %}
{% endif %} {% endif %}
{% endmacro %} {% endmacro %}

View File

@ -118,10 +118,12 @@ class ComposerToolbarViewModelTests: XCTestCase {
XCTAssertEqual(viewModel.state.suggestions, suggestions) XCTAssertEqual(viewModel.state.suggestions, suggestions)
} }
func testSuggestionTrigger() { func testSuggestionTrigger() async {
wysiwygViewModel.setMarkdownContent("@test") wysiwygViewModel.setMarkdownContent("@test")
wysiwygViewModel.setMarkdownContent("#not_implemented_yay") wysiwygViewModel.setMarkdownContent("#not_implemented_yay")
await Task.yield()
// The first one is nil because when initialised the view model is empty // The first one is nil because when initialised the view model is empty
XCTAssertEqual(completionSuggestionServiceMock.setSuggestionTriggerReceivedInvocations, [nil, .init(type: .user, text: "test", range: .init(location: 0, length: 5)), nil]) XCTAssertEqual(completionSuggestionServiceMock.setSuggestionTriggerReceivedInvocations, [nil, .init(type: .user, text: "test", range: .init(location: 0, length: 5)), nil])
} }