summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/i18n.test.ts62
-rw-r--r--test/mock-async-storage.ts3
-rw-r--r--test/mock-file.ts6
-rw-r--r--test/mock-i18n.ts5
-rw-r--r--test/mock-react-native-image.ts20
-rw-r--r--test/mock-reactotron.ts1
-rw-r--r--test/setup.ts13
-rw-r--r--test/storyshots.test.ts6
8 files changed, 116 insertions, 0 deletions
diff --git a/test/i18n.test.ts b/test/i18n.test.ts
new file mode 100644
index 0000000..61a4963
--- /dev/null
+++ b/test/i18n.test.ts
@@ -0,0 +1,62 @@
+const en = require("../app/i18n/en.json")
+const { exec } = require("child_process")
+
+// Use this array for keys that for whatever reason aren't greppable so they
+// don't hold your test suite hostage by always failing.
+const EXCEPTIONS = [
+ // "welcomeScreen.readyForLaunch",
+]
+
+function iterate(obj, stack, array) {
+ for (const property in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, property)) {
+ if (typeof obj[property] === "object") {
+ iterate(obj[property], `${stack}.${property}`, array)
+ } else {
+ array.push(`${stack.slice(1)}.${property}`)
+ }
+ }
+ }
+
+ return array
+}
+
+/**
+ * This tests your codebase for missing i18n strings so you can avoid error strings at render time
+ *
+ * It was taken from https://gist.github.com/Michaelvilleneuve/8808ba2775536665d95b7577c9d8d5a1
+ * and modified slightly to account for our Ignite higher order components,
+ * which take 'tx' and 'fooTx' props.
+ * The grep command is nasty looking, but it's essentially searching the codebase for 3 things:
+ *
+ * tx="*"
+ * Tx=""
+ * translate(""
+ *
+ * and then grabs the i18n key between the double quotes
+ *
+ * This approach isn't 100% perfect. If you are storing your key string in a variable because you
+ * are setting it conditionally, then it won't be picked up.
+ *
+ */
+
+describe("i18n", () => {
+ test("There are no missing keys", (done) => {
+ // Actual command output:
+ // grep "Tx=\"\S*\"\|tx=\"\S*\"\|translate(\"\S*\"" -ohr './app' | grep -o "\".*\""
+ const command = `grep "Tx=\\"\\S*\\"\\|tx=\\"\\S*\\"\\|translate(\\"\\S*\\"" -ohr './app' | grep -o "\\".*\\""`
+ exec(command, (_, stdout) => {
+ const allTranslationsDefined = iterate(en, "", [])
+ const allTranslationsUsed = stdout.replace(/"/g, "").split("\n")
+ allTranslationsUsed.splice(-1, 1)
+
+ for (let i = 0; i < allTranslationsUsed.length; i += 1) {
+ if (!EXCEPTIONS.includes(allTranslationsUsed[i])) {
+ // You can add keys to EXCEPTIONS (above) if you don't want them included in the test
+ expect(allTranslationsDefined).toContainEqual(allTranslationsUsed[i])
+ }
+ }
+ done()
+ })
+ }, 240000)
+})
diff --git a/test/mock-async-storage.ts b/test/mock-async-storage.ts
new file mode 100644
index 0000000..a4da056
--- /dev/null
+++ b/test/mock-async-storage.ts
@@ -0,0 +1,3 @@
+import mockAsyncStorage from "@react-native-async-storage/async-storage/jest/async-storage-mock"
+
+jest.mock("@react-native-async-storage/async-storage", () => mockAsyncStorage)
diff --git a/test/mock-file.ts b/test/mock-file.ts
new file mode 100644
index 0000000..5bf851a
--- /dev/null
+++ b/test/mock-file.ts
@@ -0,0 +1,6 @@
+export default {
+ height: 100,
+ width: 100,
+ scale: 2.0,
+ uri: "https://placekitten.com/200/200",
+}
diff --git a/test/mock-i18n.ts b/test/mock-i18n.ts
new file mode 100644
index 0000000..47a6417
--- /dev/null
+++ b/test/mock-i18n.ts
@@ -0,0 +1,5 @@
+jest.mock("i18n-js", () => {
+ return {
+ t: (key) => `${key}.test`,
+ }
+})
diff --git a/test/mock-react-native-image.ts b/test/mock-react-native-image.ts
new file mode 100644
index 0000000..eeae6bb
--- /dev/null
+++ b/test/mock-react-native-image.ts
@@ -0,0 +1,20 @@
+import * as ReactNative from "react-native"
+import mockFile from "./mock-file"
+
+jest.doMock("react-native", () => {
+ // Extend ReactNative
+ return Object.setPrototypeOf(
+ {
+ Image: {
+ ...ReactNative.Image,
+ resolveAssetSource: jest.fn((source) => mockFile), // eslint-disable-line @typescript-eslint/no-unused-vars
+ getSize: jest.fn((
+ uri: string, // eslint-disable-line @typescript-eslint/no-unused-vars
+ success: (width: number, height: number) => void,
+ failure?: (error: any) => void, // eslint-disable-line @typescript-eslint/no-unused-vars
+ ) => success(100, 100)),
+ },
+ },
+ ReactNative,
+ )
+})
diff --git a/test/mock-reactotron.ts b/test/mock-reactotron.ts
new file mode 100644
index 0000000..b3bb818
--- /dev/null
+++ b/test/mock-reactotron.ts
@@ -0,0 +1 @@
+declare const tron // eslint-disable-line @typescript-eslint/no-unused-vars
diff --git a/test/setup.ts b/test/setup.ts
new file mode 100644
index 0000000..c0137f2
--- /dev/null
+++ b/test/setup.ts
@@ -0,0 +1,13 @@
+// we always make sure 'react-native' gets included first
+import "react-native"
+
+// libraries to mock
+import "./mock-react-native-image"
+import "./mock-async-storage"
+import "./mock-i18n"
+import "./mock-reactotron"
+
+jest.useFakeTimers()
+declare global {
+ let __TEST__
+}
diff --git a/test/storyshots.test.ts b/test/storyshots.test.ts
new file mode 100644
index 0000000..337aed9
--- /dev/null
+++ b/test/storyshots.test.ts
@@ -0,0 +1,6 @@
+import initStoryshots from "@storybook/addon-storyshots"
+
+initStoryshots({
+ configPath: "./storybook",
+ framework: "react-native",
+})