Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add mock functions for testing and SSG #3437

Merged
merged 9 commits into from
Feb 13, 2022
Merged

Conversation

JonasKruckenberg
Copy link
Member

@JonasKruckenberg JonasKruckenberg commented Feb 13, 2022

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Docs
  • New Binding issue #___
  • Code style update
  • Refactor
  • Build-related changes
  • Other, please describe:

Does this PR introduce a breaking change?

  • Yes, and the changes were approved in issue #___
  • No

Checklist

  • When resolving issues, they are referenced in the PR's title (e.g fix: remove a typo, closes #___, #___)
  • A change file is added if any packages will require a version bump due to this PR per the instructions in the readme.
  • I have added a convincing reason for adding this feature, if necessary

Motivation

Allow developers to easier test and SSG their tauri frontends when using the IPC system. This currently requires massive amounts of guarding in if/else statements or mocking the tauri module import outright.
This PR provides two functions mockIPC and mockWindows that allow ergonomic mocking of the window.__TAURI_IPC__ and window.__TAURI_METADATA__ property respectively.

Example

This shows a vitest test.

import { invoke } from "@tauri-apps/api/tauri";
import { beforeAll, expect, test, vi } from "vitest";
import { randomFillSync } from "crypto";
import { mockIPC } from "@tauri-apps/api/mock";

// jsdom doesn't come with a WebCrypto implementation
beforeAll(() => {
  //@ts-ignore
  window.crypto = {
    getRandomValues: function (buffer) {
      return randomFillSync(buffer);
    },
  };
});

test('invoke', async () => {
    mockIPC((cmd, args) => {
        if(cmd === "add") {
           return (args.a as number) + (args.b as number)
        }
    })

    // we can now even track calls to the IPC system using established spying tools
    const spy = vi.spyOn(window, '__TAURI_IPC__')

    expect(invoke('add', { a: 12, b: 15 })).resolves.toBe(27)
    expect(spy).toHaveBeenCalled()
})

NOTE: Both functions throw an error if their respective properties are already defined, so they can not be used to hijack the IPC system (the user provided callback also has no access to the callback and error uids)

@JonasKruckenberg JonasKruckenberg requested review from a team and chippers February 13, 2022 14:29
@JonasKruckenberg
Copy link
Member Author

JonasKruckenberg commented Feb 13, 2022

The mock module is also only available as a path import @tauri-apps/api/mocks to better communicate it's not to be used in production code.

Copy link
Member

@lucasfernog lucasfernog left a comment

Choose a reason for hiding this comment

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

change file :)

@JonasKruckenberg
Copy link
Member Author

change file :)

nice, thanks 😄 I forget this every time

@JonasKruckenberg
Copy link
Member Author

@amrbashir maybe you can have a quick look too, to make sure it's what you imagined when we first came up with this

@amrbashir
Copy link
Member

amrbashir commented Feb 13, 2022

Yeah this is good; might be worth adding some JsDoc and an example on how/when one might use it.

- when we first came up with this
+ when you first came up with this

btw typo here

amrbashir
amrbashir previously approved these changes Feb 13, 2022
@JonasKruckenberg
Copy link
Member Author

JonasKruckenberg commented Feb 13, 2022

Yeah this is good; might be worth adding some JsDoc and an example on how/when one might use it.

True! Good point 👍🏻 I'm writing a thing for the guide rn, but in-code would be cool too.

- when we first came up with this
+ when you first came up with this

btw typo here

😄

@JonasKruckenberg
Copy link
Member Author

/** The WebviewWindow for the current window. */
const appWindow = new WebviewWindow(
window.__TAURI_METADATA__.__currentWindow.label,
{
// @ts-expect-error
skip: true
}
)

appWindow makes it very hard to use the window module in a testing context. 🤔
It tries to evaluate window.__TAURI_METADATA__ before we had a chance to mock it in the test.

So we either remove that (breaking) or allow both mock functions to override instead to throw errors.
I would like to remove appWindow since getCurrent returns the same thing and is more descriptive

@amrbashir
Copy link
Member

I would like to remove appWindow since getCurrent returns the same thing and is more descriptive

yeah we discussed this before and we will deprecate (or remove? don't remember) in v2

@JonasKruckenberg
Copy link
Member Author

JonasKruckenberg commented Feb 13, 2022

yeah we discussed this before and we will deprecate (or remove? don't remember) in v2

Good to know 👍🏻 What are the reasons for not removing it for v1? If we don't remove it now we will be stuck with it for the next 1 or 2 years (with deprecation and all) 😅

@amrbashir
Copy link
Member

it would be the biggest breaking change ever as 90% of tauri users are using it and it was too late to remove at the time. Honestly, I'd like to see it gone in v2 completely but we can discuss it later in v2 beta.

@JonasKruckenberg
Copy link
Member Author

JonasKruckenberg commented Feb 13, 2022

Hmm okay, so we allow the mock functions to override their properties then?

Edit: It would be enough to allow mockWindows to override it's property 🤔
Edit2: Or we tell people to import @tauri-apps/api/window using dynamic import during testing 🤔

@amrbashir
Copy link
Member

fine by me

@lucasfernog
Copy link
Member

let's keep appWindow, it's not a needed breaking change right now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants