From a05479f2ba9323f13c8f89fd3170099c2f3a0cd7 Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Mon, 29 Jan 2024 14:40:22 -0500
Subject: [PATCH 01/51] Initial commit for component name annotate plugin
---
.../component-annotate-plugin/.babelrc.json | 3 +
.../component-annotate-plugin/.eslintrc.js | 20 +
packages/component-annotate-plugin/.gitignore | 3 +
packages/component-annotate-plugin/LICENSE | 29 +
packages/component-annotate-plugin/index.js | 536 ++++++++++++++++++
.../component-annotate-plugin/jest.config.js | 6 +
.../component-annotate-plugin/package.json | 72 +++
.../rollup.config.js | 42 ++
.../types.tsconfig.json | 11 +
9 files changed, 722 insertions(+)
create mode 100644 packages/component-annotate-plugin/.babelrc.json
create mode 100644 packages/component-annotate-plugin/.eslintrc.js
create mode 100644 packages/component-annotate-plugin/.gitignore
create mode 100644 packages/component-annotate-plugin/LICENSE
create mode 100644 packages/component-annotate-plugin/index.js
create mode 100644 packages/component-annotate-plugin/jest.config.js
create mode 100644 packages/component-annotate-plugin/package.json
create mode 100644 packages/component-annotate-plugin/rollup.config.js
create mode 100644 packages/component-annotate-plugin/types.tsconfig.json
diff --git a/packages/component-annotate-plugin/.babelrc.json b/packages/component-annotate-plugin/.babelrc.json
new file mode 100644
index 00000000..0c20c06e
--- /dev/null
+++ b/packages/component-annotate-plugin/.babelrc.json
@@ -0,0 +1,3 @@
+{
+ "presets": ["@babel/env", "@babel/typescript"]
+}
diff --git a/packages/component-annotate-plugin/.eslintrc.js b/packages/component-annotate-plugin/.eslintrc.js
new file mode 100644
index 00000000..42b35d84
--- /dev/null
+++ b/packages/component-annotate-plugin/.eslintrc.js
@@ -0,0 +1,20 @@
+const jestPackageJson = require("jest/package.json");
+
+/** @type {import('eslint').ESLint.Options} */
+module.exports = {
+ root: true,
+ extends: ["@sentry-internal/eslint-config/jest", "@sentry-internal/eslint-config/base"],
+ ignorePatterns: [".eslintrc.js", "dist", "jest.config.js", "rollup.config.js"],
+ parserOptions: {
+ tsconfigRootDir: __dirname,
+ project: ["./src/tsconfig.json", "./test/tsconfig.json"],
+ },
+ env: {
+ node: true,
+ },
+ settings: {
+ jest: {
+ version: jestPackageJson.version,
+ },
+ },
+};
diff --git a/packages/component-annotate-plugin/.gitignore b/packages/component-annotate-plugin/.gitignore
new file mode 100644
index 00000000..22fe5492
--- /dev/null
+++ b/packages/component-annotate-plugin/.gitignore
@@ -0,0 +1,3 @@
+dist
+README.md
+.DS_Store
\ No newline at end of file
diff --git a/packages/component-annotate-plugin/LICENSE b/packages/component-annotate-plugin/LICENSE
new file mode 100644
index 00000000..042360af
--- /dev/null
+++ b/packages/component-annotate-plugin/LICENSE
@@ -0,0 +1,29 @@
+# MIT License
+
+Copyright (c) 2024, Sentry
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+- Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+- Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/packages/component-annotate-plugin/index.js b/packages/component-annotate-plugin/index.js
new file mode 100644
index 00000000..5eff73ca
--- /dev/null
+++ b/packages/component-annotate-plugin/index.js
@@ -0,0 +1,536 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2020 Engineering at FullStory
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+/**
+ * The following code is based on the FullStory Babel plugin, but has been modified to work
+ * with Sentry products
+ */
+
+const webComponentName = "data-sentry-component";
+const webElementName = "data-sentry-element";
+const webSourceFileName = "data-sentry-source-file";
+
+const nativeComponentName = "dataSentryComponent";
+const nativeElementName = "dataSentryElement";
+const nativeSourceFileName = "dataSentrySourceFile";
+const fsTagName = "fsTagName";
+
+const annotateFragmentsOptionName = "annotate-fragments";
+const ignoreComponentsOptionName = "ignoreComponents";
+
+const knownIncompatiblePlugins = [
+ // This module might be causing an issue preventing clicks. For safety, we won't run on this module.
+ "react-native-testfairy",
+ // This module checks for unexpected property keys and throws an exception.
+ "@react-navigation",
+ // The victory* modules use `dataComponent` and we get a collision.
+ "victory",
+ "victory-area",
+ "victory-axis",
+ "victory-bar",
+ "victory-box-plot",
+ "victory-brush-container",
+ "victory-brush-line",
+ "victory-candlestick",
+ "victory-canvas",
+ "victory-chart",
+ "victory-core",
+ "victory-create-container",
+ "victory-cursor-container",
+ "victory-errorbar",
+ "victory-group",
+ "victory-histogram",
+ "victory-legend",
+ "victory-line",
+ "victory-native",
+ "victory-pie",
+ "victory-polar-axis",
+ "victory-scatter",
+ "victory-selection-container",
+ "victory-shared-events",
+ "victory-stack",
+ "victory-tooltip",
+ "victory-vendor",
+ "victory-voronoi",
+ "victory-voronoi-container",
+ "victory-zoom-container",
+];
+
+module.exports = function ({ types: t }) {
+ return {
+ pre() {
+ this.ignoreComponentsFromOption = this.opts[ignoreComponentsOptionName] || [];
+ if (this.opts.setFSTagName && !this.opts.native) {
+ throw new Error(
+ "`setFSTagName: true` is invalid unless `native: true` is also set in the configuration for @fullstory/babel-plugin-annotate-react"
+ );
+ }
+ },
+ visitor: {
+ FunctionDeclaration(path, state) {
+ if (!path.node.id || !path.node.id.name) return;
+ if (isKnownIncompatiblePluginFromState(state)) return;
+ functionBodyPushAttributes(
+ state.opts[annotateFragmentsOptionName] === true,
+ t,
+ path,
+ path.node.id.name,
+ sourceFileNameFromState(state),
+ attributeNamesFromState(state),
+ this.ignoreComponentsFromOption
+ );
+ },
+ ArrowFunctionExpression(path, state) {
+ if (!path.parent.id || !path.parent.id.name) return;
+ if (isKnownIncompatiblePluginFromState(state)) return;
+ functionBodyPushAttributes(
+ state.opts[annotateFragmentsOptionName] === true,
+ t,
+ path,
+ path.parent.id.name,
+ sourceFileNameFromState(state),
+ attributeNamesFromState(state),
+ this.ignoreComponentsFromOption
+ );
+ },
+ ClassDeclaration(path, state) {
+ const name = path.get("id");
+ const properties = path.get("body").get("body");
+ const render = properties.find((prop) => {
+ return prop.isClassMethod() && prop.get("key").isIdentifier({ name: "render" });
+ });
+
+ if (!render || !render.traverse) return;
+ if (isKnownIncompatiblePluginFromState(state)) return;
+
+ const ignoreComponentsFromOption = this.ignoreComponentsFromOption;
+
+ render.traverse({
+ ReturnStatement(returnStatement) {
+ const arg = returnStatement.get("argument");
+
+ if (!arg.isJSXElement() && !arg.isJSXFragment()) return;
+ processJSX(
+ state.opts[annotateFragmentsOptionName] === true,
+ t,
+ arg,
+ name.node && name.node.name,
+ sourceFileNameFromState(state),
+ attributeNamesFromState(state),
+ ignoreComponentsFromOption
+ );
+ },
+ });
+ },
+ },
+ };
+};
+
+function fullSourceFileNameFromState(state) {
+ const name = state.file.opts.parserOpts.sourceFileName;
+ if (typeof name !== "string") {
+ return undefined;
+ }
+ return name;
+}
+
+function sourceFileNameFromState(state) {
+ const name = fullSourceFileNameFromState(state);
+ if (name === undefined) {
+ return undefined;
+ }
+
+ if (name.indexOf("/") !== -1) {
+ return name.split("/").pop();
+ } else if (name.indexOf("\\") !== -1) {
+ return name.split("\\").pop();
+ } else {
+ return name;
+ }
+}
+
+function isKnownIncompatiblePluginFromState(state) {
+ const fullSourceFileName = fullSourceFileNameFromState(state);
+ if (fullSourceFileName == undefined) {
+ return false;
+ }
+
+ for (let i = 0; i < knownIncompatiblePlugins.length; i += 1) {
+ let pluginName = knownIncompatiblePlugins[i];
+ if (
+ fullSourceFileName.includes("/node_modules/" + pluginName + "/") ||
+ fullSourceFileName.includes("\\node_modules\\" + pluginName + "\\")
+ ) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+function attributeNamesFromState(state) {
+ if (state.opts.native) {
+ if (state.opts.setFSTagName) {
+ return [fsTagName, fsTagName, nativeSourceFileName];
+ } else {
+ return [nativeComponentName, nativeElementName, nativeSourceFileName];
+ }
+ }
+ return [webComponentName, webElementName, webSourceFileName];
+}
+
+function isReactFragment(openingElement) {
+ if (openingElement.isJSXFragment()) {
+ return true;
+ }
+
+ if (!openingElement.node || !openingElement.node.name) return;
+
+ if (
+ openingElement.node.name.name === "Fragment" ||
+ openingElement.node.name.name === "React.Fragment"
+ )
+ return true;
+
+ if (
+ !openingElement.node.name.type ||
+ !openingElement.node.name.object ||
+ !openingElement.node.name.property
+ )
+ return;
+
+ return (
+ openingElement.node.name.type === "JSXMemberExpression" &&
+ openingElement.node.name.object.name === "React" &&
+ openingElement.node.name.property.name === "Fragment"
+ );
+}
+
+function applyAttributes(
+ t,
+ openingElement,
+ componentName,
+ sourceFileName,
+ attributeNames,
+ ignoreComponentsFromOption
+) {
+ const [componentAttributeName, elementAttributeName, sourceFileAttributeName] = attributeNames;
+ if (
+ !openingElement ||
+ isReactFragment(openingElement) ||
+ !openingElement.node ||
+ !openingElement.node.name
+ ) {
+ return;
+ }
+ if (!openingElement.node.attributes) openingElement.node.attributes = {};
+
+ const elementName = openingElement.node.name.name || "unknown";
+
+ const ignoredComponentFromOptions =
+ ignoreComponentsFromOption &&
+ !!ignoreComponentsFromOption.find(
+ (component) =>
+ matchesIgnoreRule(component[0], sourceFileName) &&
+ matchesIgnoreRule(component[1], componentName) &&
+ matchesIgnoreRule(component[2], elementName)
+ );
+
+ let ignoredElement = false;
+ // Add a stable attribute for the element name but only for non-DOM names
+ if (
+ !ignoredComponentFromOptions &&
+ !hasNodeNamed(openingElement, componentAttributeName) &&
+ // if componentAttributeName and elementAttributeName are set to the same thing (fsTagName), then only set the element attribute when we don't have a component attribute
+ (componentAttributeName !== elementAttributeName || !componentName)
+ ) {
+ if (defaultIgnoredElements.includes(elementName)) {
+ ignoredElement = true;
+ } else {
+ openingElement.node.attributes.push(
+ t.jSXAttribute(t.jSXIdentifier(elementAttributeName), t.stringLiteral(elementName))
+ );
+ }
+ }
+
+ // Add a stable attribute for the component name (absent for non-root elements)
+ if (
+ componentName &&
+ !ignoredComponentFromOptions &&
+ !hasNodeNamed(openingElement, componentAttributeName)
+ ) {
+ openingElement.node.attributes.push(
+ t.jSXAttribute(t.jSXIdentifier(componentAttributeName), t.stringLiteral(componentName))
+ );
+ }
+
+ // Add a stable attribute for the source file name (absent for non-root elements)
+ if (
+ sourceFileName &&
+ !ignoredComponentFromOptions &&
+ (componentName || ignoredElement === false) &&
+ !hasNodeNamed(openingElement, sourceFileAttributeName)
+ ) {
+ openingElement.node.attributes.push(
+ t.jSXAttribute(t.jSXIdentifier(sourceFileAttributeName), t.stringLiteral(sourceFileName))
+ );
+ }
+}
+
+function processJSX(
+ annotateFragments,
+ t,
+ jsxNode,
+ componentName,
+ sourceFileName,
+ attributeNames,
+ ignoreComponentsFromOption
+) {
+ if (!jsxNode) {
+ return;
+ }
+
+ // only a JSXElement contains openingElement
+ const openingElement = jsxNode.get("openingElement");
+
+ applyAttributes(
+ t,
+ openingElement,
+ componentName,
+ sourceFileName,
+ attributeNames,
+ ignoreComponentsFromOption
+ );
+
+ const children = jsxNode.get("children");
+ if (children && children.length) {
+ let shouldSetComponentName = annotateFragments;
+ for (let i = 0; i < children.length; i += 1) {
+ const child = children[i];
+ // Children don't receive the data-component attribute so we pass null for componentName unless it's the first child of a Fragment with a node and `annotateFragments` is true
+ if (
+ shouldSetComponentName &&
+ child.get("openingElement") &&
+ child.get("openingElement").node
+ ) {
+ shouldSetComponentName = false;
+ processJSX(
+ annotateFragments,
+ t,
+ child,
+ componentName,
+ sourceFileName,
+ attributeNames,
+ ignoreComponentsFromOption
+ );
+ } else {
+ processJSX(
+ annotateFragments,
+ t,
+ child,
+ null,
+ sourceFileName,
+ attributeNames,
+ ignoreComponentsFromOption
+ );
+ }
+ }
+ }
+}
+
+function functionBodyPushAttributes(
+ annotateFragments,
+ t,
+ path,
+ componentName,
+ sourceFileName,
+ attributeNames,
+ ignoreComponentsFromOption
+) {
+ let jsxNode = null;
+ const functionBody = path.get("body").get("body");
+ if (
+ functionBody.parent &&
+ (functionBody.parent.type === "JSXElement" || functionBody.parent.type === "JSXFragment")
+ ) {
+ const maybeJsxNode = functionBody.find((c) => {
+ return c.type === "JSXElement" || c.type === "JSXFragment";
+ });
+ if (!maybeJsxNode) return;
+ jsxNode = maybeJsxNode;
+ } else {
+ const returnStatement = functionBody.find((c) => {
+ return c.type === "ReturnStatement";
+ });
+ if (!returnStatement) {
+ return;
+ }
+ const arg = returnStatement.get("argument");
+ if (!arg) {
+ return;
+ }
+ if (!arg.isJSXFragment() && !arg.isJSXElement()) {
+ return;
+ }
+ jsxNode = arg;
+ }
+ if (!jsxNode) return;
+ processJSX(
+ annotateFragments,
+ t,
+ jsxNode,
+ componentName,
+ sourceFileName,
+ attributeNames,
+ ignoreComponentsFromOption
+ );
+}
+
+function matchesIgnoreRule(rule, name) {
+ return rule === "*" || rule === name;
+}
+
+function hasNodeNamed(openingElement, name) {
+ return openingElement.node.attributes.find((node) => {
+ if (!node.name) return;
+ return node.name.name === name;
+ });
+}
+
+// We don't write data-element attributes for these names
+const defaultIgnoredElements = [
+ "a",
+ "abbr",
+ "address",
+ "area",
+ "article",
+ "aside",
+ "audio",
+ "b",
+ "base",
+ "bdi",
+ "bdo",
+ "blockquote",
+ "body",
+ "br",
+ "button",
+ "canvas",
+ "caption",
+ "cite",
+ "code",
+ "col",
+ "colgroup",
+ "data",
+ "datalist",
+ "dd",
+ "del",
+ "details",
+ "dfn",
+ "dialog",
+ "div",
+ "dl",
+ "dt",
+ "em",
+ "embed",
+ "fieldset",
+ "figure",
+ "footer",
+ "form",
+ "h1",
+ "h2",
+ "h3",
+ "h4",
+ "h5",
+ "h6",
+ "head",
+ "header",
+ "hgroup",
+ "hr",
+ "html",
+ "i",
+ "iframe",
+ "img",
+ "input",
+ "ins",
+ "kbd",
+ "keygen",
+ "label",
+ "legend",
+ "li",
+ "link",
+ "main",
+ "map",
+ "mark",
+ "menu",
+ "menuitem",
+ "meter",
+ "nav",
+ "noscript",
+ "object",
+ "ol",
+ "optgroup",
+ "option",
+ "output",
+ "p",
+ "param",
+ "pre",
+ "progress",
+ "q",
+ "rb",
+ "rp",
+ "rt",
+ "rtc",
+ "ruby",
+ "s",
+ "samp",
+ "script",
+ "section",
+ "select",
+ "small",
+ "source",
+ "span",
+ "strong",
+ "style",
+ "sub",
+ "summary",
+ "sup",
+ "table",
+ "tbody",
+ "td",
+ "template",
+ "textarea",
+ "tfoot",
+ "th",
+ "thead",
+ "time",
+ "title",
+ "tr",
+ "track",
+ "u",
+ "ul",
+ "var",
+ "video",
+ "wbr",
+];
diff --git a/packages/component-annotate-plugin/jest.config.js b/packages/component-annotate-plugin/jest.config.js
new file mode 100644
index 00000000..160178bb
--- /dev/null
+++ b/packages/component-annotate-plugin/jest.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ testEnvironment: "node",
+ transform: {
+ "^.+\\.(t|j)sx?$": ["@swc/jest"],
+ },
+};
diff --git a/packages/component-annotate-plugin/package.json b/packages/component-annotate-plugin/package.json
new file mode 100644
index 00000000..a8c57837
--- /dev/null
+++ b/packages/component-annotate-plugin/package.json
@@ -0,0 +1,72 @@
+{
+ "name": "@sentry/component-annotate-plugin",
+ "version": "1.0.0",
+ "description": "A Babel plugin that annotates frontend components with additional data to enrich the experience in Sentry",
+ "repository": "git://github.com/getsentry/sentry-javascript-bundler-plugins.git",
+ "homepage": "https://github.com/getsentry/sentry-javascript-bundler-plugins/tree/main/packages/component-annotate-plugin",
+ "author": "Sentry",
+ "license": "MIT",
+ "keywords": [
+ "Sentry",
+ "React",
+ "bundler",
+ "plugin",
+ "babel",
+ "component",
+ "annotate"
+ ],
+ "publishConfig": {
+ "access": "public"
+ },
+ "main": "index.js",
+ "scripts": {
+ "build": "rimraf ./out && run-p build:rollup build:types",
+ "build:watch": "run-p build:rollup:watch build:types:watch",
+ "build:rollup": "rollup --config rollup.config.js",
+ "build:rollup:watch": "rollup --config rollup.config.js --watch --no-watch.clearScreen",
+ "build:types": "tsc --project types.tsconfig.json",
+ "build:types:watch": "tsc --project types.tsconfig.json --watch --preserveWatchOutput",
+ "build:npm": "npm pack",
+ "check:types": "run-p check:types:src check:types:test",
+ "check:types:src": "tsc --project ./src/tsconfig.json --noEmit",
+ "check:types:test": "tsc --project ./test/tsconfig.json --noEmit",
+ "clean": "run-s clean:build",
+ "clean:all": "run-p clean clean:deps",
+ "clean:build": "rimraf ./dist *.tgz",
+ "clean:deps": "rimraf node_modules",
+ "test": "jest",
+ "lint": "eslint ./src ./test",
+ "prepack": "ts-node ./src/prepack.ts"
+ },
+ "jest": {
+ "roots": [
+ "/__tests__/"
+ ]
+ },
+ "devDependencies": {
+ "@babel/core": "7.18.5",
+ "@babel/preset-env": "7.18.2",
+ "@babel/preset-typescript": "7.17.12",
+ "@rollup/plugin-babel": "5.3.1",
+ "@rollup/plugin-node-resolve": "13.3.0",
+ "@sentry-internal/eslint-config": "2.10.3",
+ "@sentry-internal/sentry-bundler-plugin-tsconfig": "2.10.3",
+ "@swc/core": "^1.2.205",
+ "@swc/jest": "^0.2.21",
+ "@types/jest": "^28.1.3",
+ "@types/node": "^18.6.3",
+ "@types/uuid": "^9.0.1",
+ "eslint": "^8.18.0",
+ "jest": "^28.1.1",
+ "rimraf": "^3.0.2",
+ "rollup": "2.75.7",
+ "ts-node": "^10.9.1",
+ "typescript": "^4.7.4"
+ },
+ "volta": {
+ "extends": "../../package.json"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+}
diff --git a/packages/component-annotate-plugin/rollup.config.js b/packages/component-annotate-plugin/rollup.config.js
new file mode 100644
index 00000000..95b11585
--- /dev/null
+++ b/packages/component-annotate-plugin/rollup.config.js
@@ -0,0 +1,42 @@
+import resolve from "@rollup/plugin-node-resolve";
+import babel from "@rollup/plugin-babel";
+import packageJson from "./package.json";
+import modulePackage from "module";
+
+const input = ["src/index.ts"];
+
+const extensions = [".ts"];
+
+export default {
+ input,
+ external: [...Object.keys(packageJson.dependencies), ...modulePackage.builtinModules],
+ onwarn: (warning) => {
+ throw new Error(warning.message); // Warnings are usually high-consequence for us so let's throw to catch them
+ },
+ plugins: [
+ resolve({
+ extensions,
+ rootDir: "./src",
+ preferBuiltins: true,
+ }),
+ babel({
+ extensions,
+ babelHelpers: "bundled",
+ include: ["src/**/*"],
+ }),
+ ],
+ output: [
+ {
+ file: packageJson.module,
+ format: "esm",
+ exports: "named",
+ sourcemap: true,
+ },
+ {
+ file: packageJson.main,
+ format: "cjs",
+ exports: "named",
+ sourcemap: true,
+ },
+ ],
+};
diff --git a/packages/component-annotate-plugin/types.tsconfig.json b/packages/component-annotate-plugin/types.tsconfig.json
new file mode 100644
index 00000000..fb161bc4
--- /dev/null
+++ b/packages/component-annotate-plugin/types.tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "$schema": "https://json.schemastore.org/tsconfig",
+ "extends": "./src/tsconfig.json",
+ "include": ["./src/**/*"],
+ "compilerOptions": {
+ "rootDir": "./src",
+ "declaration": true,
+ "emitDeclarationOnly": true,
+ "declarationDir": "./dist/types"
+ }
+}
From 56e57770590090010618b30cc28dbd54fa73813f Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Mon, 29 Jan 2024 14:54:25 -0500
Subject: [PATCH 02/51] convert file to TS
---
packages/component-annotate-plugin/README_TEMPLATE.md | 0
.../component-annotate-plugin/{index.js => src/index.ts} | 0
packages/component-annotate-plugin/src/tsconfig.json | 8 ++++++++
3 files changed, 8 insertions(+)
create mode 100644 packages/component-annotate-plugin/README_TEMPLATE.md
rename packages/component-annotate-plugin/{index.js => src/index.ts} (100%)
create mode 100644 packages/component-annotate-plugin/src/tsconfig.json
diff --git a/packages/component-annotate-plugin/README_TEMPLATE.md b/packages/component-annotate-plugin/README_TEMPLATE.md
new file mode 100644
index 00000000..e69de29b
diff --git a/packages/component-annotate-plugin/index.js b/packages/component-annotate-plugin/src/index.ts
similarity index 100%
rename from packages/component-annotate-plugin/index.js
rename to packages/component-annotate-plugin/src/index.ts
diff --git a/packages/component-annotate-plugin/src/tsconfig.json b/packages/component-annotate-plugin/src/tsconfig.json
new file mode 100644
index 00000000..fd37e123
--- /dev/null
+++ b/packages/component-annotate-plugin/src/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "$schema": "https://json.schemastore.org/tsconfig",
+ "extends": "@sentry-internal/sentry-bundler-plugin-tsconfig/base-config.json",
+ "include": ["./**/*", "../package.json"],
+ "compilerOptions": {
+ "esModuleInterop": true
+ }
+}
From e63f275edffdf94ca6a614683ad46b28937d4ce6 Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Mon, 29 Jan 2024 15:32:18 -0500
Subject: [PATCH 03/51] Get the build working
---
packages/component-annotate-plugin/package.json | 15 ++++++++++++++-
packages/component-annotate-plugin/src/index.ts | 6 ++++--
packages/component-annotate-plugin/src/prepack.ts | 7 +++++++
3 files changed, 25 insertions(+), 3 deletions(-)
create mode 100644 packages/component-annotate-plugin/src/prepack.ts
diff --git a/packages/component-annotate-plugin/package.json b/packages/component-annotate-plugin/package.json
index a8c57837..dbf32646 100644
--- a/packages/component-annotate-plugin/package.json
+++ b/packages/component-annotate-plugin/package.json
@@ -18,7 +18,19 @@
"publishConfig": {
"access": "public"
},
- "main": "index.js",
+ "files": [
+ "dist"
+ ],
+ "exports": {
+ ".": {
+ "import": "./dist/esm/index.mjs",
+ "require": "./dist/cjs/index.js",
+ "types": "./dist/types/index.d.ts"
+ }
+ },
+ "main": "dist/cjs/index.js",
+ "module": "dist/esm/index.mjs",
+ "types": "dist/types/index.d.ts",
"scripts": {
"build": "rimraf ./out && run-p build:rollup build:types",
"build:watch": "run-p build:rollup:watch build:types:watch",
@@ -43,6 +55,7 @@
"/__tests__/"
]
},
+ "dependencies": {},
"devDependencies": {
"@babel/core": "7.18.5",
"@babel/preset-env": "7.18.2",
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index 5eff73ca..ccd9ac34 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -28,6 +28,8 @@
* with Sentry products
*/
+// @ts-nocheck
+
const webComponentName = "data-sentry-component";
const webElementName = "data-sentry-element";
const webSourceFileName = "data-sentry-source-file";
@@ -78,7 +80,7 @@ const knownIncompatiblePlugins = [
"victory-zoom-container",
];
-module.exports = function ({ types: t }) {
+export function componentNameAnnotatePlugin({ types: t }) {
return {
pre() {
this.ignoreComponentsFromOption = this.opts[ignoreComponentsOptionName] || [];
@@ -146,7 +148,7 @@ module.exports = function ({ types: t }) {
},
},
};
-};
+}
function fullSourceFileNameFromState(state) {
const name = state.file.opts.parserOpts.sourceFileName;
diff --git a/packages/component-annotate-plugin/src/prepack.ts b/packages/component-annotate-plugin/src/prepack.ts
new file mode 100644
index 00000000..55793e25
--- /dev/null
+++ b/packages/component-annotate-plugin/src/prepack.ts
@@ -0,0 +1,7 @@
+import { generateOptionsDocumentation } from "@sentry-internal/dev-utils";
+import * as fs from "fs";
+import * as path from "path";
+
+const readmeTemplate = fs.readFileSync(path.join(__dirname, "..", "README_TEMPLATE.md"), "utf-8");
+const readme = readmeTemplate.replace(/#OPTIONS_SECTION_INSERT#/, generateOptionsDocumentation());
+fs.writeFileSync(path.join(__dirname, "..", "README.md"), readme, "utf-8");
From be75356f5ac5a132842cdbe5d47047fe93992fc4 Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 12:03:25 -0500
Subject: [PATCH 04/51] Initial conversion
---
.../component-annotate-plugin/src/index.ts | 221 ++++++++++--------
1 file changed, 121 insertions(+), 100 deletions(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index ccd9ac34..0db3ddb0 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -28,7 +28,8 @@
* with Sentry products
*/
-// @ts-nocheck
+import type * as Babel from "@babel/core";
+import type { PluginObj, PluginPass } from "@babel/core";
const webComponentName = "data-sentry-component";
const webElementName = "data-sentry-element";
@@ -39,51 +40,30 @@ const nativeElementName = "dataSentryElement";
const nativeSourceFileName = "dataSentrySourceFile";
const fsTagName = "fsTagName";
-const annotateFragmentsOptionName = "annotate-fragments";
-const ignoreComponentsOptionName = "ignoreComponents";
-
const knownIncompatiblePlugins = [
// This module might be causing an issue preventing clicks. For safety, we won't run on this module.
"react-native-testfairy",
// This module checks for unexpected property keys and throws an exception.
"@react-navigation",
- // The victory* modules use `dataComponent` and we get a collision.
- "victory",
- "victory-area",
- "victory-axis",
- "victory-bar",
- "victory-box-plot",
- "victory-brush-container",
- "victory-brush-line",
- "victory-candlestick",
- "victory-canvas",
- "victory-chart",
- "victory-core",
- "victory-create-container",
- "victory-cursor-container",
- "victory-errorbar",
- "victory-group",
- "victory-histogram",
- "victory-legend",
- "victory-line",
- "victory-native",
- "victory-pie",
- "victory-polar-axis",
- "victory-scatter",
- "victory-selection-container",
- "victory-shared-events",
- "victory-stack",
- "victory-tooltip",
- "victory-vendor",
- "victory-voronoi",
- "victory-voronoi-container",
- "victory-zoom-container",
];
-export function componentNameAnnotatePlugin({ types: t }) {
+interface AnnotationOpts {
+ setFSTagName?: boolean;
+ native?: boolean;
+ "annotate-fragments"?: boolean;
+ excludedComponents?: boolean;
+}
+
+interface AnnotationPluginPass extends PluginPass {
+ opts: AnnotationOpts;
+}
+
+type AnnotationPlugin = PluginObj;
+
+export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlugin {
return {
pre() {
- this.ignoreComponentsFromOption = this.opts[ignoreComponentsOptionName] || [];
+ this["excludedComponents"] = this.opts["excludedComponents"] || [];
if (this.opts.setFSTagName && !this.opts.native) {
throw new Error(
"`setFSTagName: true` is invalid unless `native: true` is also set in the configuration for @fullstory/babel-plugin-annotate-react"
@@ -94,27 +74,35 @@ export function componentNameAnnotatePlugin({ types: t }) {
FunctionDeclaration(path, state) {
if (!path.node.id || !path.node.id.name) return;
if (isKnownIncompatiblePluginFromState(state)) return;
+
functionBodyPushAttributes(
- state.opts[annotateFragmentsOptionName] === true,
+ state.opts["annotate-fragments"] === true,
t,
path,
path.node.id.name,
sourceFileNameFromState(state),
attributeNamesFromState(state),
- this.ignoreComponentsFromOption
+ this["excludedComponents"] as string[]
);
},
ArrowFunctionExpression(path, state) {
- if (!path.parent.id || !path.parent.id.name) return;
+ const parent = path.parent; // We're expecting a `VariableDeclarator` like `const MyComponent =`
+ if (!parent) return;
+ if (!("id" in parent)) return;
+ if (!parent.id) return;
+ if (!("name" in parent.id)) return;
+ if (!parent.id.name) return;
+
if (isKnownIncompatiblePluginFromState(state)) return;
+
functionBodyPushAttributes(
- state.opts[annotateFragmentsOptionName] === true,
+ state.opts["annotate-fragments"] === true,
t,
path,
- path.parent.id.name,
+ parent.id.name,
sourceFileNameFromState(state),
attributeNamesFromState(state),
- this.ignoreComponentsFromOption
+ this["excludedComponents"] as string[]
);
},
ClassDeclaration(path, state) {
@@ -127,7 +115,7 @@ export function componentNameAnnotatePlugin({ types: t }) {
if (!render || !render.traverse) return;
if (isKnownIncompatiblePluginFromState(state)) return;
- const ignoreComponentsFromOption = this.ignoreComponentsFromOption;
+ const excludedComponents = this["excludedComponents"];
render.traverse({
ReturnStatement(returnStatement) {
@@ -135,13 +123,13 @@ export function componentNameAnnotatePlugin({ types: t }) {
if (!arg.isJSXElement() && !arg.isJSXFragment()) return;
processJSX(
- state.opts[annotateFragmentsOptionName] === true,
+ state.opts["annotate-fragments"] === true,
t,
arg,
name.node && name.node.name,
sourceFileNameFromState(state),
attributeNamesFromState(state),
- ignoreComponentsFromOption
+ excludedComponents as string[]
);
},
});
@@ -150,15 +138,18 @@ export function componentNameAnnotatePlugin({ types: t }) {
};
}
-function fullSourceFileNameFromState(state) {
- const name = state.file.opts.parserOpts.sourceFileName;
+function fullSourceFileNameFromState(state: AnnotationPluginPass) {
+ // NOTE: This was originally written as `sourceFileName` which is incorrect according to Babel types
+ const name = state.file.opts.parserOpts?.sourceFilename;
+
if (typeof name !== "string") {
return undefined;
}
+
return name;
}
-function sourceFileNameFromState(state) {
+function sourceFileNameFromState(state: AnnotationPluginPass) {
const name = fullSourceFileNameFromState(state);
if (name === undefined) {
return undefined;
@@ -173,14 +164,13 @@ function sourceFileNameFromState(state) {
}
}
-function isKnownIncompatiblePluginFromState(state) {
+function isKnownIncompatiblePluginFromState(state: AnnotationPluginPass) {
const fullSourceFileName = fullSourceFileNameFromState(state);
if (fullSourceFileName == undefined) {
return false;
}
-
for (let i = 0; i < knownIncompatiblePlugins.length; i += 1) {
- let pluginName = knownIncompatiblePlugins[i];
+ const pluginName = knownIncompatiblePlugins[i] as string;
if (
fullSourceFileName.includes("/node_modules/" + pluginName + "/") ||
fullSourceFileName.includes("\\node_modules\\" + pluginName + "\\")
@@ -192,7 +182,7 @@ function isKnownIncompatiblePluginFromState(state) {
return false;
}
-function attributeNamesFromState(state) {
+function attributeNamesFromState(state: AnnotationPluginPass): [string, string, string] {
if (state.opts.native) {
if (state.opts.setFSTagName) {
return [fsTagName, fsTagName, nativeSourceFileName];
@@ -203,25 +193,33 @@ function attributeNamesFromState(state) {
return [webComponentName, webElementName, webSourceFileName];
}
-function isReactFragment(openingElement) {
+function isReactFragment(openingElement: Babel.NodePath) {
if (openingElement.isJSXFragment()) {
return true;
}
- if (!openingElement.node || !openingElement.node.name) return;
+ if (!openingElement.node) return;
+ if (!("name" in openingElement.node)) return;
+ if (!openingElement.node.name) return;
- if (
- openingElement.node.name.name === "Fragment" ||
- openingElement.node.name.name === "React.Fragment"
- )
- return true;
+ let name;
+ if (typeof openingElement.node.name === "string") {
+ name = openingElement.node.name;
+ } else if ("name" in openingElement.node.name) {
+ name = openingElement.node.name.name;
+ }
- if (
- !openingElement.node.name.type ||
- !openingElement.node.name.object ||
- !openingElement.node.name.property
- )
- return;
+ if (!name) return;
+
+ if (name === "Fragment" || name === "React.Fragment") return true;
+
+ if (!("type" in openingElement))
+ if (
+ !openingElement.node.name.type ||
+ !openingElement.node.name.object ||
+ !openingElement.node.name.property
+ )
+ return;
return (
openingElement.node.name.type === "JSXMemberExpression" &&
@@ -231,29 +229,31 @@ function isReactFragment(openingElement) {
}
function applyAttributes(
- t,
- openingElement,
- componentName,
- sourceFileName,
- attributeNames,
- ignoreComponentsFromOption
+ t: typeof Babel.types,
+ openingElement: Babel.NodePath,
+ componentName: string | null,
+ sourceFileName: string | undefined,
+ attributeNames: string[],
+ excludedComponents?: string[]
) {
const [componentAttributeName, elementAttributeName, sourceFileAttributeName] = attributeNames;
+
if (
!openingElement ||
isReactFragment(openingElement) ||
!openingElement.node ||
- !openingElement.node.name
+ !("name" in openingElement.node)
) {
return;
}
+
if (!openingElement.node.attributes) openingElement.node.attributes = {};
const elementName = openingElement.node.name.name || "unknown";
const ignoredComponentFromOptions =
- ignoreComponentsFromOption &&
- !!ignoreComponentsFromOption.find(
+ excludedComponents &&
+ !!excludedComponents.find(
(component) =>
matchesIgnoreRule(component[0], sourceFileName) &&
matchesIgnoreRule(component[1], componentName) &&
@@ -302,13 +302,13 @@ function applyAttributes(
}
function processJSX(
- annotateFragments,
- t,
- jsxNode,
- componentName,
- sourceFileName,
- attributeNames,
- ignoreComponentsFromOption
+ annotateFragments: boolean,
+ t: typeof Babel.types,
+ jsxNode: Babel.NodePath,
+ componentName: string | null,
+ sourceFileName: string | undefined,
+ attributeNames: string[],
+ excludedComponents?: string[]
) {
if (!jsxNode) {
return;
@@ -316,6 +316,7 @@ function processJSX(
// only a JSXElement contains openingElement
const openingElement = jsxNode.get("openingElement");
+ if (Array.isArray(openingElement)) return;
applyAttributes(
t,
@@ -323,20 +324,26 @@ function processJSX(
componentName,
sourceFileName,
attributeNames,
- ignoreComponentsFromOption
+ excludedComponents
);
- const children = jsxNode.get("children");
+ let children = jsxNode.get("children");
+
+ if (children && !Array.isArray(children)) {
+ children = [children];
+ }
+
if (children && children.length) {
let shouldSetComponentName = annotateFragments;
+
for (let i = 0; i < children.length; i += 1) {
const child = children[i];
+ if (!child) continue;
// Children don't receive the data-component attribute so we pass null for componentName unless it's the first child of a Fragment with a node and `annotateFragments` is true
- if (
- shouldSetComponentName &&
- child.get("openingElement") &&
- child.get("openingElement").node
- ) {
+ const openingElement = child.get("openingElement");
+ if (Array.isArray(openingElement)) continue;
+
+ if (shouldSetComponentName && openingElement && openingElement.node) {
shouldSetComponentName = false;
processJSX(
annotateFragments,
@@ -345,7 +352,7 @@ function processJSX(
componentName,
sourceFileName,
attributeNames,
- ignoreComponentsFromOption
+ excludedComponents
);
} else {
processJSX(
@@ -355,7 +362,7 @@ function processJSX(
null,
sourceFileName,
attributeNames,
- ignoreComponentsFromOption
+ excludedComponents
);
}
}
@@ -363,16 +370,19 @@ function processJSX(
}
function functionBodyPushAttributes(
- annotateFragments,
- t,
- path,
- componentName,
- sourceFileName,
- attributeNames,
- ignoreComponentsFromOption
+ annotateFragments: boolean,
+ t: typeof Babel.types,
+ path: Babel.NodePath,
+ componentName: string,
+ sourceFileName: string | undefined,
+ attributeNames: string[],
+ excludedComponents?: string[]
) {
- let jsxNode = null;
+ let jsxNode: Babel.NodePath;
+
const functionBody = path.get("body").get("body");
+ if (Array.isArray(functionBody)) return;
+
if (
functionBody.parent &&
(functionBody.parent.type === "JSXElement" || functionBody.parent.type === "JSXFragment")
@@ -380,7 +390,9 @@ function functionBodyPushAttributes(
const maybeJsxNode = functionBody.find((c) => {
return c.type === "JSXElement" || c.type === "JSXFragment";
});
+
if (!maybeJsxNode) return;
+
jsxNode = maybeJsxNode;
} else {
const returnStatement = functionBody.find((c) => {
@@ -389,16 +401,25 @@ function functionBodyPushAttributes(
if (!returnStatement) {
return;
}
+
const arg = returnStatement.get("argument");
if (!arg) {
return;
}
+
+ if (Array.isArray(arg)) {
+ return;
+ }
+
if (!arg.isJSXFragment() && !arg.isJSXElement()) {
return;
}
+
jsxNode = arg;
}
+
if (!jsxNode) return;
+
processJSX(
annotateFragments,
t,
@@ -406,7 +427,7 @@ function functionBodyPushAttributes(
componentName,
sourceFileName,
attributeNames,
- ignoreComponentsFromOption
+ excludedComponents
);
}
From 9af8ac982da9e11d3239934ca365d357d502fead Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 12:18:34 -0500
Subject: [PATCH 05/51] Extract constants
---
.../src/constants.ts | 121 ++++++++++++++++
.../component-annotate-plugin/src/index.ts | 131 +-----------------
2 files changed, 126 insertions(+), 126 deletions(-)
create mode 100644 packages/component-annotate-plugin/src/constants.ts
diff --git a/packages/component-annotate-plugin/src/constants.ts b/packages/component-annotate-plugin/src/constants.ts
new file mode 100644
index 00000000..127a9301
--- /dev/null
+++ b/packages/component-annotate-plugin/src/constants.ts
@@ -0,0 +1,121 @@
+export const KNOWN_INCOMPATIBLE_PLUGINS = [
+ // This module might be causing an issue preventing clicks. For safety, we won't run on this module.
+ "react-native-testfairy",
+ // This module checks for unexpected property keys and throws an exception.
+ "@react-navigation",
+];
+
+export const DEFAULT_IGNORED_ELEMENTS = [
+ "a",
+ "abbr",
+ "address",
+ "area",
+ "article",
+ "aside",
+ "audio",
+ "b",
+ "base",
+ "bdi",
+ "bdo",
+ "blockquote",
+ "body",
+ "br",
+ "button",
+ "canvas",
+ "caption",
+ "cite",
+ "code",
+ "col",
+ "colgroup",
+ "data",
+ "datalist",
+ "dd",
+ "del",
+ "details",
+ "dfn",
+ "dialog",
+ "div",
+ "dl",
+ "dt",
+ "em",
+ "embed",
+ "fieldset",
+ "figure",
+ "footer",
+ "form",
+ "h1",
+ "h2",
+ "h3",
+ "h4",
+ "h5",
+ "h6",
+ "head",
+ "header",
+ "hgroup",
+ "hr",
+ "html",
+ "i",
+ "iframe",
+ "img",
+ "input",
+ "ins",
+ "kbd",
+ "keygen",
+ "label",
+ "legend",
+ "li",
+ "link",
+ "main",
+ "map",
+ "mark",
+ "menu",
+ "menuitem",
+ "meter",
+ "nav",
+ "noscript",
+ "object",
+ "ol",
+ "optgroup",
+ "option",
+ "output",
+ "p",
+ "param",
+ "pre",
+ "progress",
+ "q",
+ "rb",
+ "rp",
+ "rt",
+ "rtc",
+ "ruby",
+ "s",
+ "samp",
+ "script",
+ "section",
+ "select",
+ "small",
+ "source",
+ "span",
+ "strong",
+ "style",
+ "sub",
+ "summary",
+ "sup",
+ "table",
+ "tbody",
+ "td",
+ "template",
+ "textarea",
+ "tfoot",
+ "th",
+ "thead",
+ "time",
+ "title",
+ "tr",
+ "track",
+ "u",
+ "ul",
+ "var",
+ "video",
+ "wbr",
+];
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index 0db3ddb0..0c96f28a 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -31,6 +31,8 @@
import type * as Babel from "@babel/core";
import type { PluginObj, PluginPass } from "@babel/core";
+import { DEFAULT_IGNORED_ELEMENTS, KNOWN_INCOMPATIBLE_PLUGINS } from "./constants";
+
const webComponentName = "data-sentry-component";
const webElementName = "data-sentry-element";
const webSourceFileName = "data-sentry-source-file";
@@ -40,13 +42,6 @@ const nativeElementName = "dataSentryElement";
const nativeSourceFileName = "dataSentrySourceFile";
const fsTagName = "fsTagName";
-const knownIncompatiblePlugins = [
- // This module might be causing an issue preventing clicks. For safety, we won't run on this module.
- "react-native-testfairy",
- // This module checks for unexpected property keys and throws an exception.
- "@react-navigation",
-];
-
interface AnnotationOpts {
setFSTagName?: boolean;
native?: boolean;
@@ -169,8 +164,8 @@ function isKnownIncompatiblePluginFromState(state: AnnotationPluginPass) {
if (fullSourceFileName == undefined) {
return false;
}
- for (let i = 0; i < knownIncompatiblePlugins.length; i += 1) {
- const pluginName = knownIncompatiblePlugins[i] as string;
+ for (let i = 0; i < KNOWN_INCOMPATIBLE_PLUGINS.length; i += 1) {
+ const pluginName = KNOWN_INCOMPATIBLE_PLUGINS[i] as string;
if (
fullSourceFileName.includes("/node_modules/" + pluginName + "/") ||
fullSourceFileName.includes("\\node_modules\\" + pluginName + "\\")
@@ -268,7 +263,7 @@ function applyAttributes(
// if componentAttributeName and elementAttributeName are set to the same thing (fsTagName), then only set the element attribute when we don't have a component attribute
(componentAttributeName !== elementAttributeName || !componentName)
) {
- if (defaultIgnoredElements.includes(elementName)) {
+ if (DEFAULT_IGNORED_ELEMENTS.includes(elementName)) {
ignoredElement = true;
} else {
openingElement.node.attributes.push(
@@ -441,119 +436,3 @@ function hasNodeNamed(openingElement, name) {
return node.name.name === name;
});
}
-
-// We don't write data-element attributes for these names
-const defaultIgnoredElements = [
- "a",
- "abbr",
- "address",
- "area",
- "article",
- "aside",
- "audio",
- "b",
- "base",
- "bdi",
- "bdo",
- "blockquote",
- "body",
- "br",
- "button",
- "canvas",
- "caption",
- "cite",
- "code",
- "col",
- "colgroup",
- "data",
- "datalist",
- "dd",
- "del",
- "details",
- "dfn",
- "dialog",
- "div",
- "dl",
- "dt",
- "em",
- "embed",
- "fieldset",
- "figure",
- "footer",
- "form",
- "h1",
- "h2",
- "h3",
- "h4",
- "h5",
- "h6",
- "head",
- "header",
- "hgroup",
- "hr",
- "html",
- "i",
- "iframe",
- "img",
- "input",
- "ins",
- "kbd",
- "keygen",
- "label",
- "legend",
- "li",
- "link",
- "main",
- "map",
- "mark",
- "menu",
- "menuitem",
- "meter",
- "nav",
- "noscript",
- "object",
- "ol",
- "optgroup",
- "option",
- "output",
- "p",
- "param",
- "pre",
- "progress",
- "q",
- "rb",
- "rp",
- "rt",
- "rtc",
- "ruby",
- "s",
- "samp",
- "script",
- "section",
- "select",
- "small",
- "source",
- "span",
- "strong",
- "style",
- "sub",
- "summary",
- "sup",
- "table",
- "tbody",
- "td",
- "template",
- "textarea",
- "tfoot",
- "th",
- "thead",
- "time",
- "title",
- "tr",
- "track",
- "u",
- "ul",
- "var",
- "video",
- "wbr",
-];
From b91ccfb15b0759d4252247fa72fa279f7a66a27f Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 12:22:53 -0500
Subject: [PATCH 06/51] Move functions around
Arrange in calling order, for easier reading
---
.../component-annotate-plugin/src/index.ts | 352 +++++++++---------
1 file changed, 176 insertions(+), 176 deletions(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index 0c96f28a..ad78d268 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -133,94 +133,134 @@ export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlu
};
}
-function fullSourceFileNameFromState(state: AnnotationPluginPass) {
- // NOTE: This was originally written as `sourceFileName` which is incorrect according to Babel types
- const name = state.file.opts.parserOpts?.sourceFilename;
+function functionBodyPushAttributes(
+ annotateFragments: boolean,
+ t: typeof Babel.types,
+ path: Babel.NodePath,
+ componentName: string,
+ sourceFileName: string | undefined,
+ attributeNames: string[],
+ excludedComponents?: string[]
+) {
+ let jsxNode: Babel.NodePath;
- if (typeof name !== "string") {
- return undefined;
- }
+ const functionBody = path.get("body").get("body");
+ if (Array.isArray(functionBody)) return;
- return name;
-}
+ if (
+ functionBody.parent &&
+ (functionBody.parent.type === "JSXElement" || functionBody.parent.type === "JSXFragment")
+ ) {
+ const maybeJsxNode = functionBody.find((c) => {
+ return c.type === "JSXElement" || c.type === "JSXFragment";
+ });
-function sourceFileNameFromState(state: AnnotationPluginPass) {
- const name = fullSourceFileNameFromState(state);
- if (name === undefined) {
- return undefined;
- }
+ if (!maybeJsxNode) return;
- if (name.indexOf("/") !== -1) {
- return name.split("/").pop();
- } else if (name.indexOf("\\") !== -1) {
- return name.split("\\").pop();
+ jsxNode = maybeJsxNode;
} else {
- return name;
- }
-}
+ const returnStatement = functionBody.find((c) => {
+ return c.type === "ReturnStatement";
+ });
+ if (!returnStatement) {
+ return;
+ }
-function isKnownIncompatiblePluginFromState(state: AnnotationPluginPass) {
- const fullSourceFileName = fullSourceFileNameFromState(state);
- if (fullSourceFileName == undefined) {
- return false;
- }
- for (let i = 0; i < KNOWN_INCOMPATIBLE_PLUGINS.length; i += 1) {
- const pluginName = KNOWN_INCOMPATIBLE_PLUGINS[i] as string;
- if (
- fullSourceFileName.includes("/node_modules/" + pluginName + "/") ||
- fullSourceFileName.includes("\\node_modules\\" + pluginName + "\\")
- ) {
- return true;
+ const arg = returnStatement.get("argument");
+ if (!arg) {
+ return;
}
- }
- return false;
-}
+ if (Array.isArray(arg)) {
+ return;
+ }
-function attributeNamesFromState(state: AnnotationPluginPass): [string, string, string] {
- if (state.opts.native) {
- if (state.opts.setFSTagName) {
- return [fsTagName, fsTagName, nativeSourceFileName];
- } else {
- return [nativeComponentName, nativeElementName, nativeSourceFileName];
+ if (!arg.isJSXFragment() && !arg.isJSXElement()) {
+ return;
}
+
+ jsxNode = arg;
}
- return [webComponentName, webElementName, webSourceFileName];
+
+ if (!jsxNode) return;
+
+ processJSX(
+ annotateFragments,
+ t,
+ jsxNode,
+ componentName,
+ sourceFileName,
+ attributeNames,
+ excludedComponents
+ );
}
-function isReactFragment(openingElement: Babel.NodePath) {
- if (openingElement.isJSXFragment()) {
- return true;
+function processJSX(
+ annotateFragments: boolean,
+ t: typeof Babel.types,
+ jsxNode: Babel.NodePath,
+ componentName: string | null,
+ sourceFileName: string | undefined,
+ attributeNames: string[],
+ excludedComponents?: string[]
+) {
+ if (!jsxNode) {
+ return;
}
- if (!openingElement.node) return;
- if (!("name" in openingElement.node)) return;
- if (!openingElement.node.name) return;
+ // only a JSXElement contains openingElement
+ const openingElement = jsxNode.get("openingElement");
+ if (Array.isArray(openingElement)) return;
- let name;
- if (typeof openingElement.node.name === "string") {
- name = openingElement.node.name;
- } else if ("name" in openingElement.node.name) {
- name = openingElement.node.name.name;
- }
+ applyAttributes(
+ t,
+ openingElement,
+ componentName,
+ sourceFileName,
+ attributeNames,
+ excludedComponents
+ );
- if (!name) return;
+ let children = jsxNode.get("children");
- if (name === "Fragment" || name === "React.Fragment") return true;
+ if (children && !Array.isArray(children)) {
+ children = [children];
+ }
- if (!("type" in openingElement))
- if (
- !openingElement.node.name.type ||
- !openingElement.node.name.object ||
- !openingElement.node.name.property
- )
- return;
+ if (children && children.length) {
+ let shouldSetComponentName = annotateFragments;
- return (
- openingElement.node.name.type === "JSXMemberExpression" &&
- openingElement.node.name.object.name === "React" &&
- openingElement.node.name.property.name === "Fragment"
- );
+ for (let i = 0; i < children.length; i += 1) {
+ const child = children[i];
+ if (!child) continue;
+ // Children don't receive the data-component attribute so we pass null for componentName unless it's the first child of a Fragment with a node and `annotateFragments` is true
+ const openingElement = child.get("openingElement");
+ if (Array.isArray(openingElement)) continue;
+
+ if (shouldSetComponentName && openingElement && openingElement.node) {
+ shouldSetComponentName = false;
+ processJSX(
+ annotateFragments,
+ t,
+ child,
+ componentName,
+ sourceFileName,
+ attributeNames,
+ excludedComponents
+ );
+ } else {
+ processJSX(
+ annotateFragments,
+ t,
+ child,
+ null,
+ sourceFileName,
+ attributeNames,
+ excludedComponents
+ );
+ }
+ }
+ }
}
function applyAttributes(
@@ -296,133 +336,93 @@ function applyAttributes(
}
}
-function processJSX(
- annotateFragments: boolean,
- t: typeof Babel.types,
- jsxNode: Babel.NodePath,
- componentName: string | null,
- sourceFileName: string | undefined,
- attributeNames: string[],
- excludedComponents?: string[]
-) {
- if (!jsxNode) {
- return;
+function sourceFileNameFromState(state: AnnotationPluginPass) {
+ const name = fullSourceFileNameFromState(state);
+ if (name === undefined) {
+ return undefined;
}
- // only a JSXElement contains openingElement
- const openingElement = jsxNode.get("openingElement");
- if (Array.isArray(openingElement)) return;
-
- applyAttributes(
- t,
- openingElement,
- componentName,
- sourceFileName,
- attributeNames,
- excludedComponents
- );
+ if (name.indexOf("/") !== -1) {
+ return name.split("/").pop();
+ } else if (name.indexOf("\\") !== -1) {
+ return name.split("\\").pop();
+ } else {
+ return name;
+ }
+}
- let children = jsxNode.get("children");
+function fullSourceFileNameFromState(state: AnnotationPluginPass) {
+ // NOTE: This was originally written as `sourceFileName` which is incorrect according to Babel types
+ const name = state.file.opts.parserOpts?.sourceFilename;
- if (children && !Array.isArray(children)) {
- children = [children];
+ if (typeof name !== "string") {
+ return undefined;
}
- if (children && children.length) {
- let shouldSetComponentName = annotateFragments;
-
- for (let i = 0; i < children.length; i += 1) {
- const child = children[i];
- if (!child) continue;
- // Children don't receive the data-component attribute so we pass null for componentName unless it's the first child of a Fragment with a node and `annotateFragments` is true
- const openingElement = child.get("openingElement");
- if (Array.isArray(openingElement)) continue;
+ return name;
+}
- if (shouldSetComponentName && openingElement && openingElement.node) {
- shouldSetComponentName = false;
- processJSX(
- annotateFragments,
- t,
- child,
- componentName,
- sourceFileName,
- attributeNames,
- excludedComponents
- );
- } else {
- processJSX(
- annotateFragments,
- t,
- child,
- null,
- sourceFileName,
- attributeNames,
- excludedComponents
- );
- }
+function isKnownIncompatiblePluginFromState(state: AnnotationPluginPass) {
+ const fullSourceFileName = fullSourceFileNameFromState(state);
+ if (fullSourceFileName == undefined) {
+ return false;
+ }
+ for (let i = 0; i < KNOWN_INCOMPATIBLE_PLUGINS.length; i += 1) {
+ const pluginName = KNOWN_INCOMPATIBLE_PLUGINS[i] as string;
+ if (
+ fullSourceFileName.includes("/node_modules/" + pluginName + "/") ||
+ fullSourceFileName.includes("\\node_modules\\" + pluginName + "\\")
+ ) {
+ return true;
}
}
-}
-function functionBodyPushAttributes(
- annotateFragments: boolean,
- t: typeof Babel.types,
- path: Babel.NodePath,
- componentName: string,
- sourceFileName: string | undefined,
- attributeNames: string[],
- excludedComponents?: string[]
-) {
- let jsxNode: Babel.NodePath;
+ return false;
+}
- const functionBody = path.get("body").get("body");
- if (Array.isArray(functionBody)) return;
+function attributeNamesFromState(state: AnnotationPluginPass): [string, string, string] {
+ if (state.opts.native) {
+ if (state.opts.setFSTagName) {
+ return [fsTagName, fsTagName, nativeSourceFileName];
+ } else {
+ return [nativeComponentName, nativeElementName, nativeSourceFileName];
+ }
+ }
+ return [webComponentName, webElementName, webSourceFileName];
+}
- if (
- functionBody.parent &&
- (functionBody.parent.type === "JSXElement" || functionBody.parent.type === "JSXFragment")
- ) {
- const maybeJsxNode = functionBody.find((c) => {
- return c.type === "JSXElement" || c.type === "JSXFragment";
- });
+function isReactFragment(openingElement: Babel.NodePath) {
+ if (openingElement.isJSXFragment()) {
+ return true;
+ }
- if (!maybeJsxNode) return;
+ if (!openingElement.node) return;
+ if (!("name" in openingElement.node)) return;
+ if (!openingElement.node.name) return;
- jsxNode = maybeJsxNode;
- } else {
- const returnStatement = functionBody.find((c) => {
- return c.type === "ReturnStatement";
- });
- if (!returnStatement) {
- return;
- }
+ let name;
+ if (typeof openingElement.node.name === "string") {
+ name = openingElement.node.name;
+ } else if ("name" in openingElement.node.name) {
+ name = openingElement.node.name.name;
+ }
- const arg = returnStatement.get("argument");
- if (!arg) {
- return;
- }
+ if (!name) return;
- if (Array.isArray(arg)) {
- return;
- }
+ if (name === "Fragment" || name === "React.Fragment") return true;
- if (!arg.isJSXFragment() && !arg.isJSXElement()) {
+ if (!("type" in openingElement))
+ if (
+ !openingElement.node.name.type ||
+ !openingElement.node.name.object ||
+ !openingElement.node.name.property
+ )
return;
- }
- jsxNode = arg;
- }
-
- if (!jsxNode) return;
-
- processJSX(
- annotateFragments,
- t,
- jsxNode,
- componentName,
- sourceFileName,
- attributeNames,
- excludedComponents
+ return (
+ openingElement.node.name.type === "JSXMemberExpression" &&
+ openingElement.node.name.object.name === "React" &&
+ openingElement.node.name.property.name === "Fragment"
);
}
From 516803ff1c0a3340bf32f00b2982e56fc865be91 Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Tue, 30 Jan 2024 12:37:57 -0500
Subject: [PATCH 07/51] add tests and convert to TS
---
packages/component-annotate-plugin/.gitignore | 3 +-
.../component-annotate-plugin/package.json | 6 +-
.../component-annotate-plugin/src/index.ts | 2 -
.../test/test-plugin.test.ts | 4194 +++++++++++++++++
.../test/tsconfig.json | 8 +
5 files changed, 4205 insertions(+), 8 deletions(-)
create mode 100644 packages/component-annotate-plugin/test/test-plugin.test.ts
create mode 100644 packages/component-annotate-plugin/test/tsconfig.json
diff --git a/packages/component-annotate-plugin/.gitignore b/packages/component-annotate-plugin/.gitignore
index 22fe5492..08c41e9a 100644
--- a/packages/component-annotate-plugin/.gitignore
+++ b/packages/component-annotate-plugin/.gitignore
@@ -1,3 +1,4 @@
dist
README.md
-.DS_Store
\ No newline at end of file
+.DS_Store
+test/__snapshots__
\ No newline at end of file
diff --git a/packages/component-annotate-plugin/package.json b/packages/component-annotate-plugin/package.json
index dbf32646..1b82dfd6 100644
--- a/packages/component-annotate-plugin/package.json
+++ b/packages/component-annotate-plugin/package.json
@@ -50,15 +50,11 @@
"lint": "eslint ./src ./test",
"prepack": "ts-node ./src/prepack.ts"
},
- "jest": {
- "roots": [
- "/__tests__/"
- ]
- },
"dependencies": {},
"devDependencies": {
"@babel/core": "7.18.5",
"@babel/preset-env": "7.18.2",
+ "@babel/preset-react": "^7.23.3",
"@babel/preset-typescript": "7.17.12",
"@rollup/plugin-babel": "5.3.1",
"@rollup/plugin-node-resolve": "13.3.0",
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index ccd9ac34..377ff303 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -28,8 +28,6 @@
* with Sentry products
*/
-// @ts-nocheck
-
const webComponentName = "data-sentry-component";
const webElementName = "data-sentry-element";
const webSourceFileName = "data-sentry-source-file";
diff --git a/packages/component-annotate-plugin/test/test-plugin.test.ts b/packages/component-annotate-plugin/test/test-plugin.test.ts
new file mode 100644
index 00000000..ffe5759c
--- /dev/null
+++ b/packages/component-annotate-plugin/test/test-plugin.test.ts
@@ -0,0 +1,4194 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2020 Engineering at FullStory
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+import { transform } from "@babel/core";
+import { componentNameAnnotatePlugin as plugin } from "../src/index";
+
+const BananasPizzaAppStandardInput = `import React, { Component } from 'react';
+import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+
+UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = "String";
+
+class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return ;
+ }
+}
+
+class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = { text: '' };
+ }
+
+ render() {
+ return
+ this.setState({ text })} value={this.state.text} />
+
+ {this.state.text.split(' ').map(word => word && '🍕').join(' ')}
+
+ ;
+ }
+}
+
+export default function App() {
+ return
+ FullStory ReactNative testing app
+
+
+ ;
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
+});`;
+
+const BananasPizzaAppStandardOutputNoAttributes = `
+"import React, { Component } from 'react';
+import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+
+class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\"
+ });
+ }
+
+}
+
+class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ text: ''
+ };
+ }
+
+ render() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: {
+ padding: 10
+ }
+ }, /*#__PURE__*/React.createElement(TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: text => this.setState({
+ text
+ }),
+ value: this.state.text
+ }), /*#__PURE__*/React.createElement(Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ }
+ }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
+ }
+
+}
+
+export default function App() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: styles.container
+ }, /*#__PURE__*/React.createElement(Text, {
+ style: {
+ color: '#eee'
+ }
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, null), /*#__PURE__*/React.createElement(PizzaTranslator, null));
+}
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
+});"
+`;
+
+const BananasPizzaAppStandardOutputBananasPizzaAppAttributesNoBananasElements = `
+"import React, { Component } from 'react';
+import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+
+class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+
+}
+
+class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ text: ''
+ };
+ }
+
+ render() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: {
+ padding: 10
+ },
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: text => this.setState({
+ text
+ }),
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
+ }
+
+}
+
+export default function App() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: styles.container,
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"App\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(Text, {
+ style: {
+ color: '#eee'
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, null), /*#__PURE__*/React.createElement(PizzaTranslator, {
+ dataSentryElement: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }));
+}
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
+});"
+`;
+
+const BananasPizzaAppStandardOutputBananasPizzaAppAttributesNoPizzaElements = `
+"import React, { Component } from 'react';
+import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+
+class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+
+}
+
+class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ text: ''
+ };
+ }
+
+ render() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: {
+ padding: 10
+ },
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: text => this.setState({
+ text
+ }),
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
+ }
+
+}
+
+export default function App() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: styles.container,
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"App\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(Text, {
+ style: {
+ color: '#eee'
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
+ dataSentryElement: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(PizzaTranslator, null));
+}
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
+});"
+`;
+
+const BananasPizzaAppStandardOutputBananasPizzaAppAttributesNoBananasPizzaElements = `
+"import React, { Component } from 'react';
+import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+
+class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+
+}
+
+class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ text: ''
+ };
+ }
+
+ render() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: {
+ padding: 10
+ },
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: text => this.setState({
+ text
+ }),
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
+ }
+
+}
+
+export default function App() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: styles.container,
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"App\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(Text, {
+ style: {
+ color: '#eee'
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, null), /*#__PURE__*/React.createElement(PizzaTranslator, null));
+}
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
+});"
+`;
+
+const BananasPizzaAppStandardOutputBananasPizzaAppAttributes = `
+"import React, { Component } from 'react';
+import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+
+class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+
+}
+
+class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ text: ''
+ };
+ }
+
+ render() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: {
+ padding: 10
+ },
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: text => this.setState({
+ text
+ }),
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
+ }
+
+}
+
+export default function App() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: styles.container,
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"App\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(Text, {
+ style: {
+ color: '#eee'
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
+ dataSentryElement: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(PizzaTranslator, {
+ dataSentryElement: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }));
+}
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
+});"
+`;
+
+const BananasPizzaAppStandardOutputBananasAttributes = `
+"import React, { Component } from 'react';
+import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+
+class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+
+}
+
+class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ text: ''
+ };
+ }
+
+ render() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: {
+ padding: 10
+ }
+ }, /*#__PURE__*/React.createElement(TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: text => this.setState({
+ text
+ }),
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
+ }
+
+}
+
+export default function App() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: styles.container
+ }, /*#__PURE__*/React.createElement(Text, {
+ style: {
+ color: '#eee'
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
+ dataSentryElement: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(PizzaTranslator, {
+ dataSentryElement: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }));
+}
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
+});"
+`;
+
+const BananasPizzaAppStandardOutputPizzaAttributes = `
+"import React, { Component } from 'react';
+import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+
+class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\"
+ });
+ }
+
+}
+
+class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ text: ''
+ };
+ }
+
+ render() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: {
+ padding: 10
+ },
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: text => this.setState({
+ text
+ }),
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
+ }
+
+}
+
+export default function App() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: styles.container
+ }, /*#__PURE__*/React.createElement(Text, {
+ style: {
+ color: '#eee'
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
+ dataSentryElement: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(PizzaTranslator, {
+ dataSentryElement: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }));
+}
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
+});"
+`;
+
+const BananasPizzaAppStandardOutputAppAttributes = `
+"import React, { Component } from 'react';
+import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+
+class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\"
+ });
+ }
+
+}
+
+class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ text: ''
+ };
+ }
+
+ render() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: {
+ padding: 10
+ }
+ }, /*#__PURE__*/React.createElement(TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: text => this.setState({
+ text
+ }),
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
+ }
+
+}
+
+export default function App() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: styles.container,
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"App\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(Text, {
+ style: {
+ color: '#eee'
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
+ dataSentryElement: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(PizzaTranslator, {
+ dataSentryElement: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }));
+}
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
+});"
+`;
+
+const BananasPizzaAppStandardOutputBananasPizzaAttributes = `
+"import React, { Component } from 'react';
+import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+
+class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+
+}
+
+class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ text: ''
+ };
+ }
+
+ render() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: {
+ padding: 10
+ },
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: text => this.setState({
+ text
+ }),
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
+ }
+
+}
+
+export default function App() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: styles.container
+ }, /*#__PURE__*/React.createElement(Text, {
+ style: {
+ color: '#eee'
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
+ dataSentryElement: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(PizzaTranslator, {
+ dataSentryElement: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }));
+}
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
+});"
+`;
+
+const BananasPizzaAppStandardOutputBananasAppAttributes = `
+"import React, { Component } from 'react';
+import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+
+class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+
+}
+
+class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ text: ''
+ };
+ }
+
+ render() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: {
+ padding: 10
+ }
+ }, /*#__PURE__*/React.createElement(TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: text => this.setState({
+ text
+ }),
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
+ }
+
+}
+
+export default function App() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: styles.container,
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"App\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(Text, {
+ style: {
+ color: '#eee'
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
+ dataSentryElement: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(PizzaTranslator, {
+ dataSentryElement: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }));
+}
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
+});"
+`;
+
+const BananasPizzaAppStandardOutputPizzaAppAttributes = `
+"import React, { Component } from 'react';
+import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+
+class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\"
+ });
+ }
+
+}
+
+class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ text: ''
+ };
+ }
+
+ render() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: {
+ padding: 10
+ },
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: text => this.setState({
+ text
+ }),
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
+ }
+
+}
+
+export default function App() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: styles.container,
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"App\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(Text, {
+ style: {
+ color: '#eee'
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
+ dataSentryElement: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(PizzaTranslator, {
+ dataSentryElement: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }));
+}
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
+});"
+`;
+
+const BananasStandardInput = `import React, { Component } from 'react';
+import { Image } from 'react-native';
+
+class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return ;
+ }
+}`;
+
+const BananasStandardOutputNoAttributes = `
+"import React, { Component } from 'react';
+import { Image } from 'react-native';
+
+class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\"
+ });
+ }
+
+}"
+`;
+
+const BananasStandardOutputWithAttributes = `
+"import React, { Component } from 'react';
+import { Image } from 'react-native';
+
+class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+
+}"
+`;
+
+const BananasStandardOutputWithFSTagName = `
+"import React, { Component } from 'react';
+import { Image } from 'react-native';
+
+class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ fsTagName: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+
+}"
+`;
+
+it("unknown-element snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+class componentName extends Component {
+ render() {
+ return A
;
+ }
+}
+
+export default componentName;
+`,
+ {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("component-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component, Fragment } from 'react';
+
+class componentName extends Component {
+ render() {
+ return A;
+ }
+}
+
+export default componentName;
+`,
+ {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("component-react-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+class componentName extends Component {
+ render() {
+ return A;
+ }
+}
+
+export default componentName;
+`,
+ {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("component-shorthand-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+class componentName extends Component {
+ render() {
+ return <>A>;
+ }
+}
+
+export default componentName;
+`,
+ {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("component-annotate-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+class componentName extends Component {
+ render() {
+ return <>A>;
+ }
+}
+
+export default componentName;
+`,
+ {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("component-annotate-react-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+class componentName extends Component {
+ render() {
+ return
+ Hello world
+ ;
+ }
+}
+
+export default componentName;
+`,
+ {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { "annotate-fragments": true }]],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("component-annotate-shorthand-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+class componentName extends Component {
+ render() {
+ return <>
+ Hello world
+ >;
+ }
+}
+
+export default componentName;
+`,
+ {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { "annotate-fragments": true }]],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("arrow-noreturn-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component, Fragment } from 'react';
+
+const componentName = () => (
+
+ Hello world
+
+);
+
+export default componentName;
+`,
+ {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("arrow-noreturn-shorthand-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+const componentName = () => (
+ <>
+ Hello world
+ >
+);
+
+export default componentName;
+`,
+ {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("arrow-noreturn-react-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+const componentName = () => (
+
+ Hello world
+
+);
+
+export default componentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("arrow-noreturn-annotate-trivial-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component, Fragment } from 'react';
+
+const componentName = () => (
+ Hello world
+);
+
+export default componentName;
+`,
+ {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { "annotate-fragments": true }]],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("arrow-noreturn-annotate-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component, Fragment } from 'react';
+
+const componentName = () => (
+
+ Hello world
+
+);
+
+export default componentName;
+`,
+ {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { "annotate-fragments": true }]],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("arrow-noreturn-annotate-react-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+const componentName = () => (
+
+ Hello world
+
+);
+
+export default componentName;
+`,
+ {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { "annotate-fragments": true }]],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("arrow-noreturn-annotate-shorthand-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+const componentName = () => (
+ <>
+ Hello world
+ >
+);
+
+export default componentName;
+`,
+ {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { "annotate-fragments": true }]],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("arrow-noreturn-annotate-fragment-once snapshot matches", () => {
+ const result = transform(
+ `import React, { Component, Fragment } from 'react';
+
+const componentName = () => (
+
+ Hello world
+ Hola Sol
+
+);
+
+export default componentName;
+`,
+ {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { "annotate-fragments": true }]],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("arrow-noreturn-annotate-fragment-no-whitespace snapshot matches", () => {
+ const result = transform(
+ `import React, { Component, Fragment } from 'react';
+
+const componentName = () => (
+ Hello world
Hola Sol
+);
+
+export default componentName;
+`,
+ {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { "annotate-fragments": true }]],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("arrow snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+const componentName = () => {
+ return
+
Hello world
+
;
+};
+
+export default componentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("option-attribute snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+const componentName = () => {
+ return
+
Hello world
+ ;
+};
+
+export default componentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("component snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+class componentName extends Component {
+ render() {
+ return
+
Hello world
+ ;
+ }
+}
+
+export default componentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("rawfunction-annotate-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component, Fragment } from 'react';
+
+function SubComponent() {
+ return Sub;
+}
+
+const componentName = () => {
+ return
+
+ ;
+};
+
+export default componentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { "annotate-fragments": true }]],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("rawfunction-annotate-react-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+function SubComponent() {
+ return Sub;
+}
+
+const componentName = () => {
+ return
+
+ ;
+};
+
+export default componentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { "annotate-fragments": true }]],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("rawfunction-annotate-shorthand-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+function SubComponent() {
+ return <>Sub>;
+}
+
+const componentName = () => {
+ return <>
+
+ >;
+};
+
+export default componentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { "annotate-fragments": true }]],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("rawfunction-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component, Fragment } from 'react';
+
+function SubComponent() {
+ return Sub;
+}
+
+const componentName = () => {
+ return
+
+ ;
+};
+
+export default componentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("rawfunction-react-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+function SubComponent() {
+ return Sub;
+}
+
+const componentName = () => {
+ return
+
+ ;
+};
+
+export default componentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("rawfunction-shorthand-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+function SubComponent() {
+ return <>Sub>;
+}
+
+const componentName = () => {
+ return <>
+
+ >;
+};
+
+export default componentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("arrow-noreturn snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+const componentName = () => (
+
+
Hello world
+
+);
+
+export default componentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("tags snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+
+UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = "String";
+
+class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return ;
+ }
+}
+
+class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = { text: '' };
+ }
+
+ render() {
+ return
+ this.setState({ text })} value={this.state.text} />
+
+ {this.state.text.split(' ').map(word => word && '🍕').join(' ')}
+
+ ;
+ }
+}
+
+export default function App() {
+ return
+ FullStory ReactNative testing app
+
+
+ ;
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
+});
+`,
+ {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { native: true }]],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("option-format snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+const componentName = () => {
+ return
+
Hello world
+ ;
+};
+
+export default componentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("pureComponent-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Fragment } from 'react';
+
+class PureComponentName extends React.PureComponent {
+ render() {
+ return
+ Hello world
+ ;
+ }
+}
+
+export default PureComponentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("pureComponent-shorthand-fragment snapshot matches", () => {
+ const result = transform(
+ `import React from 'react';
+
+class PureComponentName extends React.PureComponent {
+ render() {
+ return <>
+ Hello world
+ >;
+ }
+}
+
+export default PureComponentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("pureComponent-react-fragment snapshot matches", () => {
+ const result = transform(
+ `import React from 'react';
+
+class PureComponentName extends React.PureComponent {
+ render() {
+ return
+ Hello world
+ ;
+ }
+}
+
+export default PureComponentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("rawfunction snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+function SubComponent() {
+ return Sub
;
+}
+
+const componentName = () => {
+ return
+
+
;
+};
+
+export default componentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("arrow-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component, Fragment } from 'react';
+
+const componentName = () => {
+ return
+ Hello world
+ ;
+};
+
+export default componentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("arrow-shorthand-fragment snapshot matches", () => {
+ const result = transform(
+ `import React from 'react';
+
+const componentName = () => {
+ return <>
+ Hello world
+ >;
+};
+
+export default componentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("arrow-react-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+const componentName = () => {
+ return
+ Hello world
+ ;
+};
+
+export default componentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("nonJSX snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+class TestClass extends Component {
+ test() {
+ return true;
+ }
+}
+
+export default TestClass;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("arrow-anonymous-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component, Fragment } from 'react';
+
+const componentName = () => {
+ return (() =>
+ Hello world
+ )();
+};
+
+export default componentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("arrow-anonymous-shorthand-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+const componentName = () => {
+ return (() => <>
+ Hello world
+ >)();
+};
+
+export default componentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("arrow-anonymous-react-fragment snapshot matches", () => {
+ const result = transform(
+ `import React, { Component } from 'react';
+
+const componentName = () => {
+ return (() =>
+ Hello world
+ )();
+};
+
+export default componentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("pure snapshot matches", () => {
+ const result = transform(
+ `import React from 'react';
+
+class PureComponentName extends React.PureComponent {
+ render() {
+ return
+
Hello world
+ ;
+ }
+}
+
+export default PureComponentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [plugin],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("component-fragment-native snapshot matches", () => {
+ const result = transform(
+ `import React, { Component, Fragment } from 'react';
+
+class componentName extends Component {
+ render() {
+ return A;
+ }
+}
+
+export default componentName;
+`,
+ {
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { native: true }]],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("pure-native snapshot matches", () => {
+ const result = transform(
+ `import React from 'react';
+
+class PureComponentName extends React.PureComponent {
+ render() {
+ return
+
Hello world
+ ;
+ }
+}
+
+export default PureComponentName;
+`,
+ {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { native: true }]],
+ }
+ );
+ expect(result?.code).toMatchSnapshot();
+});
+
+it("Bananas ignore components dataSentrySourceFile=nomatch dataSentryComponent=nomatch dataSentryElement=nomatch snapshot matches", () => {
+ const result = transform(BananasStandardInput, {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "nomatch", "nomatch"]] }]],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "\\"use strict\\";
+
+ function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
+ var _react = _interopRequireWildcard(require(\\"react\\"));
+ var _reactNative = require(\\"react-native\\");
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
+ function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
+ function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
+ function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+ var Bananas = /*#__PURE__*/function (_Component) {
+ _inherits(Bananas, _Component);
+ var _super = _createSuper(Bananas);
+ function Bananas() {
+ _classCallCheck(this, Bananas);
+ return _super.apply(this, arguments);
+ }
+ _createClass(Bananas, [{
+ key: \\"render\\",
+ value: function render() {
+ var pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+ }]);
+ return Bananas;
+ }(_react.Component);"
+ `
+ );
+});
+
+it("ignore components dataSentrySourceFile=* dataSentryComponent=nomatch dataSentryElement=nomatch snapshot matches", () => {
+ const result = transform(BananasStandardInput, {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { native: true, ignoreComponents: [["*", "nomatch", "nomatch"]] }]],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "\\"use strict\\";
+
+ function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
+ var _react = _interopRequireWildcard(require(\\"react\\"));
+ var _reactNative = require(\\"react-native\\");
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
+ function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
+ function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
+ function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+ var Bananas = /*#__PURE__*/function (_Component) {
+ _inherits(Bananas, _Component);
+ var _super = _createSuper(Bananas);
+ function Bananas() {
+ _classCallCheck(this, Bananas);
+ return _super.apply(this, arguments);
+ }
+ _createClass(Bananas, [{
+ key: \\"render\\",
+ value: function render() {
+ var pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+ }]);
+ return Bananas;
+ }(_react.Component);"
+ `
+ );
+});
+
+it("Bananas ignore components dataSentrySourceFile=nomatch dataSentryComponent=* dataSentryElement=nomatch snapshot matches", () => {
+ const result = transform(BananasStandardInput, {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "*", "nomatch"]] }]],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "\\"use strict\\";
+
+ function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
+ var _react = _interopRequireWildcard(require(\\"react\\"));
+ var _reactNative = require(\\"react-native\\");
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
+ function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
+ function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
+ function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+ var Bananas = /*#__PURE__*/function (_Component) {
+ _inherits(Bananas, _Component);
+ var _super = _createSuper(Bananas);
+ function Bananas() {
+ _classCallCheck(this, Bananas);
+ return _super.apply(this, arguments);
+ }
+ _createClass(Bananas, [{
+ key: \\"render\\",
+ value: function render() {
+ var pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+ }]);
+ return Bananas;
+ }(_react.Component);"
+ `
+ );
+});
+
+it("Bananas ignore components dataSentrySourceFile=nomatch dataSentryComponent=nomatch dataSentryElement=* snapshot matches", () => {
+ const result = transform(BananasStandardInput, {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "nomatch", "*"]] }]],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "\\"use strict\\";
+
+ function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
+ var _react = _interopRequireWildcard(require(\\"react\\"));
+ var _reactNative = require(\\"react-native\\");
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
+ function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
+ function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
+ function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+ var Bananas = /*#__PURE__*/function (_Component) {
+ _inherits(Bananas, _Component);
+ var _super = _createSuper(Bananas);
+ function Bananas() {
+ _classCallCheck(this, Bananas);
+ return _super.apply(this, arguments);
+ }
+ _createClass(Bananas, [{
+ key: \\"render\\",
+ value: function render() {
+ var pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+ }]);
+ return Bananas;
+ }(_react.Component);"
+ `
+ );
+});
+
+it("Bananas ignore components dataSentrySourceFile=* dataSentryComponent=* dataSentryElement=nomatch snapshot matches", () => {
+ const result = transform(BananasStandardInput, {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "nomatch", "nomatch"]] }]],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "\\"use strict\\";
+
+ function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
+ var _react = _interopRequireWildcard(require(\\"react\\"));
+ var _reactNative = require(\\"react-native\\");
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
+ function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
+ function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
+ function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+ var Bananas = /*#__PURE__*/function (_Component) {
+ _inherits(Bananas, _Component);
+ var _super = _createSuper(Bananas);
+ function Bananas() {
+ _classCallCheck(this, Bananas);
+ return _super.apply(this, arguments);
+ }
+ _createClass(Bananas, [{
+ key: \\"render\\",
+ value: function render() {
+ var pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+ }]);
+ return Bananas;
+ }(_react.Component);"
+ `
+ );
+});
+
+it("Bananas ignore components dataSentrySourceFile=* dataSentryComponent=nomatch dataSentryElement=* snapshot matches", () => {
+ const result = transform(BananasStandardInput, {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "nomatch", "nomatch"]] }]],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "\\"use strict\\";
+
+ function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
+ var _react = _interopRequireWildcard(require(\\"react\\"));
+ var _reactNative = require(\\"react-native\\");
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
+ function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
+ function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
+ function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+ var Bananas = /*#__PURE__*/function (_Component) {
+ _inherits(Bananas, _Component);
+ var _super = _createSuper(Bananas);
+ function Bananas() {
+ _classCallCheck(this, Bananas);
+ return _super.apply(this, arguments);
+ }
+ _createClass(Bananas, [{
+ key: \\"render\\",
+ value: function render() {
+ var pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+ }]);
+ return Bananas;
+ }(_react.Component);"
+ `
+ );
+});
+
+it("Bananas ignore components dataSentrySourceFile=nomatch dataSentryComponent=* dataSentryElement=* snapshot matches", () => {
+ const result = transform(BananasStandardInput, {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "nomatch", "nomatch"]] }]],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "\\"use strict\\";
+
+ function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
+ var _react = _interopRequireWildcard(require(\\"react\\"));
+ var _reactNative = require(\\"react-native\\");
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
+ function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
+ function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
+ function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+ var Bananas = /*#__PURE__*/function (_Component) {
+ _inherits(Bananas, _Component);
+ var _super = _createSuper(Bananas);
+ function Bananas() {
+ _classCallCheck(this, Bananas);
+ return _super.apply(this, arguments);
+ }
+ _createClass(Bananas, [{
+ key: \\"render\\",
+ value: function render() {
+ var pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+ }]);
+ return Bananas;
+ }(_react.Component);"
+ `
+ );
+});
+
+// This tests out matching only `dataSentryElement`, with * for the others
+it("Bananas ignore components dataSentrySourceFile=* dataSentryComponent=* dataSentryElement=match snapshot matches", () => {
+ const result = transform(BananasStandardInput, {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { native: true, ignoreComponents: [["*", "*", "Image"]] }]],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "\\"use strict\\";
+
+ function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
+ var _react = _interopRequireWildcard(require(\\"react\\"));
+ var _reactNative = require(\\"react-native\\");
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
+ function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
+ function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
+ function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+ var Bananas = /*#__PURE__*/function (_Component) {
+ _inherits(Bananas, _Component);
+ var _super = _createSuper(Bananas);
+ function Bananas() {
+ _classCallCheck(this, Bananas);
+ return _super.apply(this, arguments);
+ }
+ _createClass(Bananas, [{
+ key: \\"render\\",
+ value: function render() {
+ var pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\"
+ });
+ }
+ }]);
+ return Bananas;
+ }(_react.Component);"
+ `
+ );
+});
+
+// This tests out matching only `dataSentryElement` and `dataSentryComponent`, with * for `dataSentrySourceFile`
+it("Bananas ignore components dataSentrySourceFile=* dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
+ const result = transform(BananasStandardInput, {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { native: true, ignoreComponents: [["*", "Bananas", "Image"]] }]],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "\\"use strict\\";
+
+ function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
+ var _react = _interopRequireWildcard(require(\\"react\\"));
+ var _reactNative = require(\\"react-native\\");
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
+ function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
+ function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
+ function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+ var Bananas = /*#__PURE__*/function (_Component) {
+ _inherits(Bananas, _Component);
+ var _super = _createSuper(Bananas);
+ function Bananas() {
+ _classCallCheck(this, Bananas);
+ return _super.apply(this, arguments);
+ }
+ _createClass(Bananas, [{
+ key: \\"render\\",
+ value: function render() {
+ var pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\"
+ });
+ }
+ }]);
+ return Bananas;
+ }(_react.Component);"
+ `
+ );
+});
+
+// This tests out matching on all 3 of our ignore list values
+it("Bananas ignore components dataSentrySourceFile=match dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
+ const result = transform(BananasStandardInput, {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [
+ [plugin, { native: true, ignoreComponents: [["filename-test.js", "Bananas", "Image"]] }],
+ ],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "\\"use strict\\";
+
+ function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
+ var _react = _interopRequireWildcard(require(\\"react\\"));
+ var _reactNative = require(\\"react-native\\");
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
+ function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
+ function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
+ function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+ var Bananas = /*#__PURE__*/function (_Component) {
+ _inherits(Bananas, _Component);
+ var _super = _createSuper(Bananas);
+ function Bananas() {
+ _classCallCheck(this, Bananas);
+ return _super.apply(this, arguments);
+ }
+ _createClass(Bananas, [{
+ key: \\"render\\",
+ value: function render() {
+ var pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\"
+ });
+ }
+ }]);
+ return Bananas;
+ }(_react.Component);"
+ `
+ );
+});
+
+// This tests out matching on all 3 of our ignore list values via *
+it("Bananas/Pizza/App ignore components dataSentrySourceFile=* dataSentryComponent=* dataSentryElement=* snapshot matches", () => {
+ const result = transform(BananasPizzaAppStandardInput, {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { native: true, ignoreComponents: [["*", "*", "*"]] }]],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "\\"use strict\\";
+
+ function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
+ Object.defineProperty(exports, \\"__esModule\\", {
+ value: true
+ });
+ exports[\\"default\\"] = App;
+ var _react = _interopRequireWildcard(require(\\"react\\"));
+ var _reactNative = require(\\"react-native\\");
+ var _container;
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
+ function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
+ function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
+ function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+ _reactNative.UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+ var Bananas = /*#__PURE__*/function (_Component) {
+ _inherits(Bananas, _Component);
+ var _super = _createSuper(Bananas);
+ function Bananas() {
+ _classCallCheck(this, Bananas);
+ return _super.apply(this, arguments);
+ }
+ _createClass(Bananas, [{
+ key: \\"render\\",
+ value: function render() {
+ var pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\"
+ });
+ }
+ }]);
+ return Bananas;
+ }(_react.Component);
+ var PizzaTranslator = /*#__PURE__*/function (_Component2) {
+ _inherits(PizzaTranslator, _Component2);
+ var _super2 = _createSuper(PizzaTranslator);
+ function PizzaTranslator(props) {
+ var _this;
+ _classCallCheck(this, PizzaTranslator);
+ _this = _super2.call(this, props);
+ _this.state = {
+ text: ''
+ };
+ return _this;
+ }
+ _createClass(PizzaTranslator, [{
+ key: \\"render\\",
+ value: function render() {
+ var _this2 = this;
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ style: {
+ padding: 10
+ }
+ }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: function onChangeText(text) {
+ return _this2.setState({
+ text: text
+ });
+ },
+ value: this.state.text
+ }), /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ }
+ }, this.state.text.split(' ').map(function (word) {
+ return word && '🍕';
+ }).join(' ')));
+ }
+ }]);
+ return PizzaTranslator;
+ }(_react.Component);
+ function App() {
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ style: styles.container
+ }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ style: {
+ color: '#eee'
+ }
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/_react[\\"default\\"].createElement(Bananas, null), /*#__PURE__*/_react[\\"default\\"].createElement(PizzaTranslator, null));
+ }
+ var styles = _reactNative.StyleSheet.create({
+ container: (_container = {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222'
+ }, _defineProperty(_container, \\"alignItems\\", 'center'), _defineProperty(_container, \\"justifyContent\\", 'center'), _container)
+ });"
+ `
+ );
+});
+
+// This tests out matching on all 3 of our ignore list values
+it("Bananas/Pizza/App ignore components dataSentrySourceFile=nomatch dataSentryComponent=* dataSentryElement=* snapshot matches", () => {
+ const result = transform(BananasPizzaAppStandardInput, {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "*", "*"]] }]],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "\\"use strict\\";
+
+ function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
+ Object.defineProperty(exports, \\"__esModule\\", {
+ value: true
+ });
+ exports[\\"default\\"] = App;
+ var _react = _interopRequireWildcard(require(\\"react\\"));
+ var _reactNative = require(\\"react-native\\");
+ var _container;
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
+ function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
+ function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
+ function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+ _reactNative.UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+ var Bananas = /*#__PURE__*/function (_Component) {
+ _inherits(Bananas, _Component);
+ var _super = _createSuper(Bananas);
+ function Bananas() {
+ _classCallCheck(this, Bananas);
+ return _super.apply(this, arguments);
+ }
+ _createClass(Bananas, [{
+ key: \\"render\\",
+ value: function render() {
+ var pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+ }]);
+ return Bananas;
+ }(_react.Component);
+ var PizzaTranslator = /*#__PURE__*/function (_Component2) {
+ _inherits(PizzaTranslator, _Component2);
+ var _super2 = _createSuper(PizzaTranslator);
+ function PizzaTranslator(props) {
+ var _this;
+ _classCallCheck(this, PizzaTranslator);
+ _this = _super2.call(this, props);
+ _this.state = {
+ text: ''
+ };
+ return _this;
+ }
+ _createClass(PizzaTranslator, [{
+ key: \\"render\\",
+ value: function render() {
+ var _this2 = this;
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ style: {
+ padding: 10
+ },
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: function onChangeText(text) {
+ return _this2.setState({
+ text: text
+ });
+ },
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(function (word) {
+ return word && '🍕';
+ }).join(' ')));
+ }
+ }]);
+ return PizzaTranslator;
+ }(_react.Component);
+ function App() {
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ style: styles.container,
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"App\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ style: {
+ color: '#eee'
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/_react[\\"default\\"].createElement(Bananas, {
+ dataSentryElement: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/_react[\\"default\\"].createElement(PizzaTranslator, {
+ dataSentryElement: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }));
+ }
+ var styles = _reactNative.StyleSheet.create({
+ container: (_container = {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222'
+ }, _defineProperty(_container, \\"alignItems\\", 'center'), _defineProperty(_container, \\"justifyContent\\", 'center'), _container)
+ });"
+ `
+ );
+});
+
+it("Bananas/Pizza/App only Bananas dataSentrySourceFile=match dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
+ const result = transform(BananasPizzaAppStandardInput, {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [
+ [
+ plugin,
+ {
+ native: true,
+ ignoreComponents: [
+ // Pizza
+ ["filename-test.js", "PizzaTranslator", "View"],
+ // App
+ ["filename-test.js", "App", "View"],
+ ],
+ },
+ ],
+ ],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "\\"use strict\\";
+
+ function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
+ Object.defineProperty(exports, \\"__esModule\\", {
+ value: true
+ });
+ exports[\\"default\\"] = App;
+ var _react = _interopRequireWildcard(require(\\"react\\"));
+ var _reactNative = require(\\"react-native\\");
+ var _container;
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
+ function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
+ function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
+ function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+ _reactNative.UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+ var Bananas = /*#__PURE__*/function (_Component) {
+ _inherits(Bananas, _Component);
+ var _super = _createSuper(Bananas);
+ function Bananas() {
+ _classCallCheck(this, Bananas);
+ return _super.apply(this, arguments);
+ }
+ _createClass(Bananas, [{
+ key: \\"render\\",
+ value: function render() {
+ var pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+ }]);
+ return Bananas;
+ }(_react.Component);
+ var PizzaTranslator = /*#__PURE__*/function (_Component2) {
+ _inherits(PizzaTranslator, _Component2);
+ var _super2 = _createSuper(PizzaTranslator);
+ function PizzaTranslator(props) {
+ var _this;
+ _classCallCheck(this, PizzaTranslator);
+ _this = _super2.call(this, props);
+ _this.state = {
+ text: ''
+ };
+ return _this;
+ }
+ _createClass(PizzaTranslator, [{
+ key: \\"render\\",
+ value: function render() {
+ var _this2 = this;
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ style: {
+ padding: 10
+ }
+ }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: function onChangeText(text) {
+ return _this2.setState({
+ text: text
+ });
+ },
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(function (word) {
+ return word && '🍕';
+ }).join(' ')));
+ }
+ }]);
+ return PizzaTranslator;
+ }(_react.Component);
+ function App() {
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ style: styles.container
+ }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ style: {
+ color: '#eee'
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/_react[\\"default\\"].createElement(Bananas, {
+ dataSentryElement: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/_react[\\"default\\"].createElement(PizzaTranslator, {
+ dataSentryElement: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }));
+ }
+ var styles = _reactNative.StyleSheet.create({
+ container: (_container = {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222'
+ }, _defineProperty(_container, \\"alignItems\\", 'center'), _defineProperty(_container, \\"justifyContent\\", 'center'), _container)
+ });"
+ `
+ );
+});
+
+it("Bananas/Pizza/App only Pizza dataSentrySourceFile=match dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
+ const result = transform(BananasPizzaAppStandardInput, {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [
+ [
+ plugin,
+ {
+ native: true,
+ ignoreComponents: [
+ // Bananas
+ ["filename-test.js", "Bananas", "Image"],
+ // App
+ ["filename-test.js", "App", "View"],
+ ],
+ },
+ ],
+ ],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "\\"use strict\\";
+
+ function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
+ Object.defineProperty(exports, \\"__esModule\\", {
+ value: true
+ });
+ exports[\\"default\\"] = App;
+ var _react = _interopRequireWildcard(require(\\"react\\"));
+ var _reactNative = require(\\"react-native\\");
+ var _container;
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
+ function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
+ function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
+ function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+ _reactNative.UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+ var Bananas = /*#__PURE__*/function (_Component) {
+ _inherits(Bananas, _Component);
+ var _super = _createSuper(Bananas);
+ function Bananas() {
+ _classCallCheck(this, Bananas);
+ return _super.apply(this, arguments);
+ }
+ _createClass(Bananas, [{
+ key: \\"render\\",
+ value: function render() {
+ var pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\"
+ });
+ }
+ }]);
+ return Bananas;
+ }(_react.Component);
+ var PizzaTranslator = /*#__PURE__*/function (_Component2) {
+ _inherits(PizzaTranslator, _Component2);
+ var _super2 = _createSuper(PizzaTranslator);
+ function PizzaTranslator(props) {
+ var _this;
+ _classCallCheck(this, PizzaTranslator);
+ _this = _super2.call(this, props);
+ _this.state = {
+ text: ''
+ };
+ return _this;
+ }
+ _createClass(PizzaTranslator, [{
+ key: \\"render\\",
+ value: function render() {
+ var _this2 = this;
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ style: {
+ padding: 10
+ },
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: function onChangeText(text) {
+ return _this2.setState({
+ text: text
+ });
+ },
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(function (word) {
+ return word && '🍕';
+ }).join(' ')));
+ }
+ }]);
+ return PizzaTranslator;
+ }(_react.Component);
+ function App() {
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ style: styles.container
+ }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ style: {
+ color: '#eee'
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/_react[\\"default\\"].createElement(Bananas, {
+ dataSentryElement: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/_react[\\"default\\"].createElement(PizzaTranslator, {
+ dataSentryElement: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }));
+ }
+ var styles = _reactNative.StyleSheet.create({
+ container: (_container = {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222'
+ }, _defineProperty(_container, \\"alignItems\\", 'center'), _defineProperty(_container, \\"justifyContent\\", 'center'), _container)
+ });"
+ `
+ );
+});
+
+it("Bananas/Pizza/App only App dataSentrySourceFile=match dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
+ const result = transform(BananasPizzaAppStandardInput, {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [
+ [
+ plugin,
+ {
+ native: true,
+ ignoreComponents: [
+ // Bananas
+ ["filename-test.js", "Bananas", "Image"],
+ // Pizza
+ ["filename-test.js", "PizzaTranslator", "View"],
+ ],
+ },
+ ],
+ ],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "\\"use strict\\";
+
+ function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
+ Object.defineProperty(exports, \\"__esModule\\", {
+ value: true
+ });
+ exports[\\"default\\"] = App;
+ var _react = _interopRequireWildcard(require(\\"react\\"));
+ var _reactNative = require(\\"react-native\\");
+ var _container;
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
+ function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
+ function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
+ function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+ _reactNative.UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+ var Bananas = /*#__PURE__*/function (_Component) {
+ _inherits(Bananas, _Component);
+ var _super = _createSuper(Bananas);
+ function Bananas() {
+ _classCallCheck(this, Bananas);
+ return _super.apply(this, arguments);
+ }
+ _createClass(Bananas, [{
+ key: \\"render\\",
+ value: function render() {
+ var pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\"
+ });
+ }
+ }]);
+ return Bananas;
+ }(_react.Component);
+ var PizzaTranslator = /*#__PURE__*/function (_Component2) {
+ _inherits(PizzaTranslator, _Component2);
+ var _super2 = _createSuper(PizzaTranslator);
+ function PizzaTranslator(props) {
+ var _this;
+ _classCallCheck(this, PizzaTranslator);
+ _this = _super2.call(this, props);
+ _this.state = {
+ text: ''
+ };
+ return _this;
+ }
+ _createClass(PizzaTranslator, [{
+ key: \\"render\\",
+ value: function render() {
+ var _this2 = this;
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ style: {
+ padding: 10
+ }
+ }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: function onChangeText(text) {
+ return _this2.setState({
+ text: text
+ });
+ },
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(function (word) {
+ return word && '🍕';
+ }).join(' ')));
+ }
+ }]);
+ return PizzaTranslator;
+ }(_react.Component);
+ function App() {
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ style: styles.container,
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"App\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ style: {
+ color: '#eee'
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/_react[\\"default\\"].createElement(Bananas, {
+ dataSentryElement: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/_react[\\"default\\"].createElement(PizzaTranslator, {
+ dataSentryElement: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }));
+ }
+ var styles = _reactNative.StyleSheet.create({
+ container: (_container = {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222'
+ }, _defineProperty(_container, \\"alignItems\\", 'center'), _defineProperty(_container, \\"justifyContent\\", 'center'), _container)
+ });"
+ `
+ );
+});
+
+it("Bananas/Pizza/App No Pizza Elements dataSentrySourceFile=match dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
+ const result = transform(BananasPizzaAppStandardInput, {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [
+ [
+ plugin,
+ {
+ native: true,
+ ignoreComponents: [
+ // Pizza Element
+ ["filename-test.js", null, "PizzaTranslator"],
+ ],
+ },
+ ],
+ ],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "\\"use strict\\";
+
+ function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
+ Object.defineProperty(exports, \\"__esModule\\", {
+ value: true
+ });
+ exports[\\"default\\"] = App;
+ var _react = _interopRequireWildcard(require(\\"react\\"));
+ var _reactNative = require(\\"react-native\\");
+ var _container;
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
+ function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
+ function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
+ function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+ _reactNative.UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+ var Bananas = /*#__PURE__*/function (_Component) {
+ _inherits(Bananas, _Component);
+ var _super = _createSuper(Bananas);
+ function Bananas() {
+ _classCallCheck(this, Bananas);
+ return _super.apply(this, arguments);
+ }
+ _createClass(Bananas, [{
+ key: \\"render\\",
+ value: function render() {
+ var pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+ }]);
+ return Bananas;
+ }(_react.Component);
+ var PizzaTranslator = /*#__PURE__*/function (_Component2) {
+ _inherits(PizzaTranslator, _Component2);
+ var _super2 = _createSuper(PizzaTranslator);
+ function PizzaTranslator(props) {
+ var _this;
+ _classCallCheck(this, PizzaTranslator);
+ _this = _super2.call(this, props);
+ _this.state = {
+ text: ''
+ };
+ return _this;
+ }
+ _createClass(PizzaTranslator, [{
+ key: \\"render\\",
+ value: function render() {
+ var _this2 = this;
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ style: {
+ padding: 10
+ },
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: function onChangeText(text) {
+ return _this2.setState({
+ text: text
+ });
+ },
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(function (word) {
+ return word && '🍕';
+ }).join(' ')));
+ }
+ }]);
+ return PizzaTranslator;
+ }(_react.Component);
+ function App() {
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ style: styles.container,
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"App\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ style: {
+ color: '#eee'
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/_react[\\"default\\"].createElement(Bananas, {
+ dataSentryElement: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/_react[\\"default\\"].createElement(PizzaTranslator, null));
+ }
+ var styles = _reactNative.StyleSheet.create({
+ container: (_container = {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222'
+ }, _defineProperty(_container, \\"alignItems\\", 'center'), _defineProperty(_container, \\"justifyContent\\", 'center'), _container)
+ });"
+ `
+ );
+});
+
+it("Bananas/Pizza/App No Bananas Elements dataSentrySourceFile=match dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
+ const result = transform(BananasPizzaAppStandardInput, {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [
+ [
+ plugin,
+ {
+ native: true,
+ ignoreComponents: [
+ // Bananas Element
+ ["filename-test.js", null, "Bananas"],
+ ],
+ },
+ ],
+ ],
+ });
+
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "\\"use strict\\";
+
+ function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
+ Object.defineProperty(exports, \\"__esModule\\", {
+ value: true
+ });
+ exports[\\"default\\"] = App;
+ var _react = _interopRequireWildcard(require(\\"react\\"));
+ var _reactNative = require(\\"react-native\\");
+ var _container;
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
+ function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
+ function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
+ function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+ _reactNative.UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+ var Bananas = /*#__PURE__*/function (_Component) {
+ _inherits(Bananas, _Component);
+ var _super = _createSuper(Bananas);
+ function Bananas() {
+ _classCallCheck(this, Bananas);
+ return _super.apply(this, arguments);
+ }
+ _createClass(Bananas, [{
+ key: \\"render\\",
+ value: function render() {
+ var pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+ }]);
+ return Bananas;
+ }(_react.Component);
+ var PizzaTranslator = /*#__PURE__*/function (_Component2) {
+ _inherits(PizzaTranslator, _Component2);
+ var _super2 = _createSuper(PizzaTranslator);
+ function PizzaTranslator(props) {
+ var _this;
+ _classCallCheck(this, PizzaTranslator);
+ _this = _super2.call(this, props);
+ _this.state = {
+ text: ''
+ };
+ return _this;
+ }
+ _createClass(PizzaTranslator, [{
+ key: \\"render\\",
+ value: function render() {
+ var _this2 = this;
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ style: {
+ padding: 10
+ },
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: function onChangeText(text) {
+ return _this2.setState({
+ text: text
+ });
+ },
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(function (word) {
+ return word && '🍕';
+ }).join(' ')));
+ }
+ }]);
+ return PizzaTranslator;
+ }(_react.Component);
+ function App() {
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ style: styles.container,
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"App\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ style: {
+ color: '#eee'
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/_react[\\"default\\"].createElement(Bananas, null), /*#__PURE__*/_react[\\"default\\"].createElement(PizzaTranslator, {
+ dataSentryElement: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }));
+ }
+ var styles = _reactNative.StyleSheet.create({
+ container: (_container = {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222'
+ }, _defineProperty(_container, \\"alignItems\\", 'center'), _defineProperty(_container, \\"justifyContent\\", 'center'), _container)
+ });"
+ `
+ );
+});
+
+it("Bananas/Pizza/App No Bananas/Pizza Elements dataSentrySourceFile=match dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
+ const result = transform(BananasPizzaAppStandardInput, {
+ filename: "./filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [
+ [
+ plugin,
+ {
+ native: true,
+ ignoreComponents: [
+ // Bananas Element
+ ["filename-test.js", null, "Bananas"],
+ // Pizza Element
+ ["filename-test.js", null, "PizzaTranslator"],
+ ],
+ },
+ ],
+ ],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "\\"use strict\\";
+
+ function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
+ Object.defineProperty(exports, \\"__esModule\\", {
+ value: true
+ });
+ exports[\\"default\\"] = App;
+ var _react = _interopRequireWildcard(require(\\"react\\"));
+ var _reactNative = require(\\"react-native\\");
+ var _container;
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
+ function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
+ function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
+ function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+ _reactNative.UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+ var Bananas = /*#__PURE__*/function (_Component) {
+ _inherits(Bananas, _Component);
+ var _super = _createSuper(Bananas);
+ function Bananas() {
+ _classCallCheck(this, Bananas);
+ return _super.apply(this, arguments);
+ }
+ _createClass(Bananas, [{
+ key: \\"render\\",
+ value: function render() {
+ var pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+ }]);
+ return Bananas;
+ }(_react.Component);
+ var PizzaTranslator = /*#__PURE__*/function (_Component2) {
+ _inherits(PizzaTranslator, _Component2);
+ var _super2 = _createSuper(PizzaTranslator);
+ function PizzaTranslator(props) {
+ var _this;
+ _classCallCheck(this, PizzaTranslator);
+ _this = _super2.call(this, props);
+ _this.state = {
+ text: ''
+ };
+ return _this;
+ }
+ _createClass(PizzaTranslator, [{
+ key: \\"render\\",
+ value: function render() {
+ var _this2 = this;
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ style: {
+ padding: 10
+ },
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: function onChangeText(text) {
+ return _this2.setState({
+ text: text
+ });
+ },
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(function (word) {
+ return word && '🍕';
+ }).join(' ')));
+ }
+ }]);
+ return PizzaTranslator;
+ }(_react.Component);
+ function App() {
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ style: styles.container,
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"App\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ style: {
+ color: '#eee'
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/_react[\\"default\\"].createElement(Bananas, null), /*#__PURE__*/_react[\\"default\\"].createElement(PizzaTranslator, null));
+ }
+ var styles = _reactNative.StyleSheet.create({
+ container: (_container = {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222'
+ }, _defineProperty(_container, \\"alignItems\\", 'center'), _defineProperty(_container, \\"justifyContent\\", 'center'), _container)
+ });"
+ `
+ );
+});
+
+it("Bananas incompatible plugin victory-core source snapshot matches", () => {
+ const result = transform(BananasStandardInput, {
+ filename: "test/node_modules/victory-core/filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { native: true }]],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "import React, { Component } from 'react';
+ import { Image } from 'react-native';
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\"
+ });
+ }
+ }"
+ `
+ );
+});
+
+it("Bananas incompatible plugin victory-valid source snapshot matches", () => {
+ const result = transform(BananasStandardInput, {
+ filename: "test/node_modules/victory-valid/filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { native: true }]],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "import React, { Component } from 'react';
+ import { Image } from 'react-native';
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+ }"
+ `
+ );
+});
+
+it("Bananas incompatible plugin @react-navigation source snapshot matches", () => {
+ const result = transform(BananasStandardInput, {
+ filename: "test/node_modules/@react-navigation/core/filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [[plugin, { native: true }]],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "import React, { Component } from 'react';
+ import { Image } from 'react-native';
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\"
+ });
+ }
+ }"
+ `
+ );
+});
+
+it("setFSTagName sets fsTagName on component with its dataSentryComponent value", () => {
+ const result = transform(BananasStandardInput, {
+ filename: "filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [
+ [
+ plugin,
+ {
+ native: true,
+ setFSTagName: true,
+ },
+ ],
+ ],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "\\"use strict\\";
+
+ function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
+ var _react = _interopRequireWildcard(require(\\"react\\"));
+ var _reactNative = require(\\"react-native\\");
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
+ function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
+ function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
+ function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+ var Bananas = /*#__PURE__*/function (_Component) {
+ _inherits(Bananas, _Component);
+ var _super = _createSuper(Bananas);
+ function Bananas() {
+ _classCallCheck(this, Bananas);
+ return _super.apply(this, arguments);
+ }
+ _createClass(Bananas, [{
+ key: \\"render\\",
+ value: function render() {
+ var pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ fsTagName: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+ }]);
+ return Bananas;
+ }(_react.Component);"
+ `
+ );
+});
+
+it("Bananas custom attribute names let component override element with setFSTagName", () => {
+ const BananasInputCustomFSTagName = `import React, { Component } from 'react';
+import { Image } from 'react-native';
+
+class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return ;
+ }
+}`;
+
+ const result = transform(BananasInputCustomFSTagName, {
+ filename: "filename-test.js",
+ presets: ["@babel/preset-react"],
+ plugins: [
+ [
+ plugin,
+ {
+ native: true,
+ setFSTagName: true,
+ },
+ ],
+ ],
+ });
+ expect(result?.code).toMatchInlineSnapshot(
+ `
+ "\\"use strict\\";
+
+ function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
+ var _react = _interopRequireWildcard(require(\\"react\\"));
+ var _reactNative = require(\\"react-native\\");
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
+ function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
+ function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
+ function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+ var Bananas = /*#__PURE__*/function (_Component) {
+ _inherits(Bananas, _Component);
+ var _super = _createSuper(Bananas);
+ function Bananas() {
+ _classCallCheck(this, Bananas);
+ return _super.apply(this, arguments);
+ }
+ _createClass(Bananas, [{
+ key: \\"render\\",
+ value: function render() {
+ var pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ fsTagName: \\"CustomTagName\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+ }]);
+ return Bananas;
+ }(_react.Component);"
+ `
+ );
+});
diff --git a/packages/component-annotate-plugin/test/tsconfig.json b/packages/component-annotate-plugin/test/tsconfig.json
new file mode 100644
index 00000000..b73d9b53
--- /dev/null
+++ b/packages/component-annotate-plugin/test/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "$schema": "https://json.schemastore.org/tsconfig",
+ "extends": "../src/tsconfig.json",
+ "include": ["../src/**/*", "./**/*"],
+ "compilerOptions": {
+ "types": ["node", "jest"]
+ }
+}
From 30e1be7489cc74a998e2f59df8fda740c9f782f2 Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Tue, 30 Jan 2024 12:38:48 -0500
Subject: [PATCH 08/51] progress on adding types to plugin index file
---
.../component-annotate-plugin/src/index.ts | 264 +++++++++++-------
1 file changed, 157 insertions(+), 107 deletions(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index 377ff303..fd4c680f 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -28,6 +28,9 @@
* with Sentry products
*/
+import type * as Babel from "@babel/core";
+import type { PluginObj, PluginPass } from "@babel/core";
+
const webComponentName = "data-sentry-component";
const webElementName = "data-sentry-element";
const webSourceFileName = "data-sentry-source-file";
@@ -37,51 +40,30 @@ const nativeElementName = "dataSentryElement";
const nativeSourceFileName = "dataSentrySourceFile";
const fsTagName = "fsTagName";
-const annotateFragmentsOptionName = "annotate-fragments";
-const ignoreComponentsOptionName = "ignoreComponents";
-
const knownIncompatiblePlugins = [
// This module might be causing an issue preventing clicks. For safety, we won't run on this module.
"react-native-testfairy",
// This module checks for unexpected property keys and throws an exception.
"@react-navigation",
- // The victory* modules use `dataComponent` and we get a collision.
- "victory",
- "victory-area",
- "victory-axis",
- "victory-bar",
- "victory-box-plot",
- "victory-brush-container",
- "victory-brush-line",
- "victory-candlestick",
- "victory-canvas",
- "victory-chart",
- "victory-core",
- "victory-create-container",
- "victory-cursor-container",
- "victory-errorbar",
- "victory-group",
- "victory-histogram",
- "victory-legend",
- "victory-line",
- "victory-native",
- "victory-pie",
- "victory-polar-axis",
- "victory-scatter",
- "victory-selection-container",
- "victory-shared-events",
- "victory-stack",
- "victory-tooltip",
- "victory-vendor",
- "victory-voronoi",
- "victory-voronoi-container",
- "victory-zoom-container",
];
-export function componentNameAnnotatePlugin({ types: t }) {
+interface AnnotationOpts {
+ setFSTagName?: boolean;
+ native?: boolean;
+ "annotate-fragments"?: boolean;
+ excludedComponents?: boolean;
+}
+
+interface AnnotationPluginPass extends PluginPass {
+ opts: AnnotationOpts;
+}
+
+type AnnotationPlugin = PluginObj;
+
+export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlugin {
return {
pre() {
- this.ignoreComponentsFromOption = this.opts[ignoreComponentsOptionName] || [];
+ this["excludedComponents"] = this.opts["excludedComponents"] || [];
if (this.opts.setFSTagName && !this.opts.native) {
throw new Error(
"`setFSTagName: true` is invalid unless `native: true` is also set in the configuration for @fullstory/babel-plugin-annotate-react"
@@ -92,27 +74,35 @@ export function componentNameAnnotatePlugin({ types: t }) {
FunctionDeclaration(path, state) {
if (!path.node.id || !path.node.id.name) return;
if (isKnownIncompatiblePluginFromState(state)) return;
+
functionBodyPushAttributes(
- state.opts[annotateFragmentsOptionName] === true,
+ state.opts["annotate-fragments"] === true,
t,
path,
path.node.id.name,
sourceFileNameFromState(state),
attributeNamesFromState(state),
- this.ignoreComponentsFromOption
+ this["excludedComponents"] as [string, string, string][]
);
},
ArrowFunctionExpression(path, state) {
- if (!path.parent.id || !path.parent.id.name) return;
+ const parent = path.parent; // We're expecting a `VariableDeclarator` like `const MyComponent =`
+ if (!parent) return;
+ if (!("id" in parent)) return;
+ if (!parent.id) return;
+ if (!("name" in parent.id)) return;
+ if (!parent.id.name) return;
+
if (isKnownIncompatiblePluginFromState(state)) return;
+
functionBodyPushAttributes(
- state.opts[annotateFragmentsOptionName] === true,
+ state.opts["annotate-fragments"] === true,
t,
path,
- path.parent.id.name,
+ parent.id.name,
sourceFileNameFromState(state),
attributeNamesFromState(state),
- this.ignoreComponentsFromOption
+ this["excludedComponents"] as [string, string, string][]
);
},
ClassDeclaration(path, state) {
@@ -125,7 +115,7 @@ export function componentNameAnnotatePlugin({ types: t }) {
if (!render || !render.traverse) return;
if (isKnownIncompatiblePluginFromState(state)) return;
- const ignoreComponentsFromOption = this.ignoreComponentsFromOption;
+ const excludedComponents = this["excludedComponents"];
render.traverse({
ReturnStatement(returnStatement) {
@@ -133,13 +123,13 @@ export function componentNameAnnotatePlugin({ types: t }) {
if (!arg.isJSXElement() && !arg.isJSXFragment()) return;
processJSX(
- state.opts[annotateFragmentsOptionName] === true,
+ state.opts["annotate-fragments"] === true,
t,
arg,
name.node && name.node.name,
sourceFileNameFromState(state),
attributeNamesFromState(state),
- ignoreComponentsFromOption
+ excludedComponents as [string, string, string][]
);
},
});
@@ -148,15 +138,18 @@ export function componentNameAnnotatePlugin({ types: t }) {
};
}
-function fullSourceFileNameFromState(state) {
- const name = state.file.opts.parserOpts.sourceFileName;
+function fullSourceFileNameFromState(state: AnnotationPluginPass) {
+ // NOTE: This was originally written as `sourceFileName` which is incorrect according to Babel types
+ const name = state.file.opts.parserOpts?.sourceFilename;
+
if (typeof name !== "string") {
return undefined;
}
+
return name;
}
-function sourceFileNameFromState(state) {
+function sourceFileNameFromState(state: AnnotationPluginPass) {
const name = fullSourceFileNameFromState(state);
if (name === undefined) {
return undefined;
@@ -171,14 +164,13 @@ function sourceFileNameFromState(state) {
}
}
-function isKnownIncompatiblePluginFromState(state) {
+function isKnownIncompatiblePluginFromState(state: AnnotationPluginPass) {
const fullSourceFileName = fullSourceFileNameFromState(state);
if (fullSourceFileName == undefined) {
return false;
}
-
for (let i = 0; i < knownIncompatiblePlugins.length; i += 1) {
- let pluginName = knownIncompatiblePlugins[i];
+ const pluginName = knownIncompatiblePlugins[i] as string;
if (
fullSourceFileName.includes("/node_modules/" + pluginName + "/") ||
fullSourceFileName.includes("\\node_modules\\" + pluginName + "\\")
@@ -190,7 +182,7 @@ function isKnownIncompatiblePluginFromState(state) {
return false;
}
-function attributeNamesFromState(state) {
+function attributeNamesFromState(state: AnnotationPluginPass): [string, string, string] {
if (state.opts.native) {
if (state.opts.setFSTagName) {
return [fsTagName, fsTagName, nativeSourceFileName];
@@ -201,61 +193,94 @@ function attributeNamesFromState(state) {
return [webComponentName, webElementName, webSourceFileName];
}
-function isReactFragment(openingElement) {
+function isReactFragment(openingElement: Babel.NodePath) {
if (openingElement.isJSXFragment()) {
return true;
}
- if (!openingElement.node || !openingElement.node.name) return;
+ const node = openingElement.node;
- if (
- openingElement.node.name.name === "Fragment" ||
- openingElement.node.name.name === "React.Fragment"
- )
- return true;
+ if (!node) return;
+ if (!("name" in node)) return;
+ if (!node.name) return;
+
+ let name;
+ if (typeof node.name === "string") {
+ name = node.name;
+ } else if ("name" in node.name) {
+ name = node.name.name;
+ }
+
+ if (!name) return;
+
+ if (name === "Fragment" || name === "React.Fragment") return true;
if (
- !openingElement.node.name.type ||
- !openingElement.node.name.object ||
- !openingElement.node.name.property
+ typeof node.name === "string" ||
+ !("type" in node.name) ||
+ !("object" in node.name) ||
+ !("property" in node.name)
)
return;
+ if (!node.name.type || !node.name.object || !node.name.property) return;
+
return (
- openingElement.node.name.type === "JSXMemberExpression" &&
- openingElement.node.name.object.name === "React" &&
- openingElement.node.name.property.name === "Fragment"
+ node.name.type === "JSXMemberExpression" &&
+ "name" in node.name.object &&
+ node.name.object.name === "React" &&
+ node.name.property.name === "Fragment"
);
}
function applyAttributes(
- t,
- openingElement,
- componentName,
- sourceFileName,
- attributeNames,
- ignoreComponentsFromOption
+ t: typeof Babel.types,
+ openingElement: Babel.NodePath,
+ componentName: string | null,
+ sourceFileName: string | undefined,
+ attributeNames: [string, string, string],
+ excludedComponents?: [string, string, string][]
) {
const [componentAttributeName, elementAttributeName, sourceFileAttributeName] = attributeNames;
+
if (
!openingElement ||
isReactFragment(openingElement) ||
!openingElement.node ||
- !openingElement.node.name
+ !("name" in openingElement.node)
) {
return;
}
- if (!openingElement.node.attributes) openingElement.node.attributes = {};
- const elementName = openingElement.node.name.name || "unknown";
+ // @ts-expect-error This behaviour might not be defined for some types, but changing it is a risk
+ if (
+ !("attributes" in openingElement.node) ||
+ !openingElement.node.attributes ||
+ !Array.isArray(openingElement.node.attributes)
+ )
+ openingElement.node.attributes = [];
+
+ let elementName: string;
+
+ if (openingElement.node.name) {
+ if (typeof openingElement.node.name === "string") {
+ elementName = openingElement.node.name;
+ } else if ("name" in openingElement.node.name) {
+ elementName = openingElement.node.name.name.toString();
+ } else {
+ elementName = "unknown";
+ }
+ } else {
+ elementName = "unknown";
+ }
const ignoredComponentFromOptions =
- ignoreComponentsFromOption &&
- !!ignoreComponentsFromOption.find(
+ excludedComponents &&
+ !!excludedComponents.find(
(component) =>
- matchesIgnoreRule(component[0], sourceFileName) &&
- matchesIgnoreRule(component[1], componentName) &&
- matchesIgnoreRule(component[2], elementName)
+ matchesIgnoreRule(component[0], sourceFileName ?? "") &&
+ matchesIgnoreRule(component[1], componentName ?? "") &&
+ matchesIgnoreRule(component[2], elementName ?? "")
);
let ignoredElement = false;
@@ -281,6 +306,7 @@ function applyAttributes(
!ignoredComponentFromOptions &&
!hasNodeNamed(openingElement, componentAttributeName)
) {
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
openingElement.node.attributes.push(
t.jSXAttribute(t.jSXIdentifier(componentAttributeName), t.stringLiteral(componentName))
);
@@ -300,13 +326,13 @@ function applyAttributes(
}
function processJSX(
- annotateFragments,
- t,
- jsxNode,
- componentName,
- sourceFileName,
- attributeNames,
- ignoreComponentsFromOption
+ annotateFragments: boolean,
+ t: typeof Babel.types,
+ jsxNode: Babel.NodePath,
+ componentName: string | null,
+ sourceFileName: string | undefined,
+ attributeNames: [string, string, string],
+ excludedComponents?: [string, string, string][]
) {
if (!jsxNode) {
return;
@@ -314,6 +340,7 @@ function processJSX(
// only a JSXElement contains openingElement
const openingElement = jsxNode.get("openingElement");
+ if (Array.isArray(openingElement)) return;
applyAttributes(
t,
@@ -321,20 +348,26 @@ function processJSX(
componentName,
sourceFileName,
attributeNames,
- ignoreComponentsFromOption
+ excludedComponents
);
- const children = jsxNode.get("children");
+ let children = jsxNode.get("children");
+
+ if (children && !Array.isArray(children)) {
+ children = [children];
+ }
+
if (children && children.length) {
let shouldSetComponentName = annotateFragments;
+
for (let i = 0; i < children.length; i += 1) {
const child = children[i];
+ if (!child) continue;
// Children don't receive the data-component attribute so we pass null for componentName unless it's the first child of a Fragment with a node and `annotateFragments` is true
- if (
- shouldSetComponentName &&
- child.get("openingElement") &&
- child.get("openingElement").node
- ) {
+ const openingElement = child.get("openingElement");
+ if (Array.isArray(openingElement)) continue;
+
+ if (shouldSetComponentName && openingElement && openingElement.node) {
shouldSetComponentName = false;
processJSX(
annotateFragments,
@@ -343,7 +376,7 @@ function processJSX(
componentName,
sourceFileName,
attributeNames,
- ignoreComponentsFromOption
+ excludedComponents
);
} else {
processJSX(
@@ -353,7 +386,7 @@ function processJSX(
null,
sourceFileName,
attributeNames,
- ignoreComponentsFromOption
+ excludedComponents
);
}
}
@@ -361,16 +394,19 @@ function processJSX(
}
function functionBodyPushAttributes(
- annotateFragments,
- t,
- path,
- componentName,
- sourceFileName,
- attributeNames,
- ignoreComponentsFromOption
+ annotateFragments: boolean,
+ t: typeof Babel.types,
+ path: Babel.NodePath,
+ componentName: string,
+ sourceFileName: string | undefined,
+ attributeNames: [string, string, string],
+ excludedComponents?: [string, string, string][]
) {
- let jsxNode = null;
+ let jsxNode: Babel.NodePath;
+
const functionBody = path.get("body").get("body");
+ if (Array.isArray(functionBody)) return;
+
if (
functionBody.parent &&
(functionBody.parent.type === "JSXElement" || functionBody.parent.type === "JSXFragment")
@@ -378,7 +414,9 @@ function functionBodyPushAttributes(
const maybeJsxNode = functionBody.find((c) => {
return c.type === "JSXElement" || c.type === "JSXFragment";
});
+
if (!maybeJsxNode) return;
+
jsxNode = maybeJsxNode;
} else {
const returnStatement = functionBody.find((c) => {
@@ -387,16 +425,25 @@ function functionBodyPushAttributes(
if (!returnStatement) {
return;
}
+
const arg = returnStatement.get("argument");
if (!arg) {
return;
}
+
+ if (Array.isArray(arg)) {
+ return;
+ }
+
if (!arg.isJSXFragment() && !arg.isJSXElement()) {
return;
}
+
jsxNode = arg;
}
+
if (!jsxNode) return;
+
processJSX(
annotateFragments,
t,
@@ -404,16 +451,19 @@ function functionBodyPushAttributes(
componentName,
sourceFileName,
attributeNames,
- ignoreComponentsFromOption
+ excludedComponents
);
}
-function matchesIgnoreRule(rule, name) {
+function matchesIgnoreRule(rule: string, name: string): boolean {
return rule === "*" || rule === name;
}
-function hasNodeNamed(openingElement, name) {
- return openingElement.node.attributes.find((node) => {
+function hasNodeNamed(openingElement: Babel.NodePath, name: string): boolean {
+ if (!("attributes" in openingElement.node)) return false;
+
+ return openingElement.node.attributes.some((node) => {
+ if (!("name" in node)) return;
if (!node.name) return;
return node.name.name === name;
});
From 8cbc95dcb808062011125f1cc9701d2690a3abea Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Tue, 30 Jan 2024 12:47:16 -0500
Subject: [PATCH 09/51] yarn lock
---
yarn.lock | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 95 insertions(+)
diff --git a/yarn.lock b/yarn.lock
index 51d3cfb7..17504116 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -81,6 +81,13 @@
dependencies:
"@babel/types" "^7.18.6"
+"@babel/helper-annotate-as-pure@^7.22.5":
+ version "7.22.5"
+ resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882"
+ integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==
+ dependencies:
+ "@babel/types" "^7.22.5"
+
"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6":
version "7.21.5"
resolved "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.21.5.tgz#817f73b6c59726ab39f6ba18c234268a519e5abb"
@@ -169,6 +176,13 @@
dependencies:
"@babel/types" "^7.21.4"
+"@babel/helper-module-imports@^7.22.15":
+ version "7.22.15"
+ resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0"
+ integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==
+ dependencies:
+ "@babel/types" "^7.22.15"
+
"@babel/helper-module-transforms@^7.18.0", "@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.20.11", "@babel/helper-module-transforms@^7.21.5":
version "7.21.5"
resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.5.tgz#d937c82e9af68d31ab49039136a222b17ac0b420"
@@ -195,6 +209,11 @@
resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.21.5.tgz#345f2377d05a720a4e5ecfa39cbf4474a4daed56"
integrity sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg==
+"@babel/helper-plugin-utils@^7.22.5":
+ version "7.22.5"
+ resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295"
+ integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==
+
"@babel/helper-remap-async-to-generator@^7.18.9":
version "7.18.9"
resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519"
@@ -243,16 +262,31 @@
resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz#2b3eea65443c6bdc31c22d037c65f6d323b6b2bd"
integrity sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==
+"@babel/helper-string-parser@^7.23.4":
+ version "7.23.4"
+ resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83"
+ integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==
+
"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1":
version "7.19.1"
resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2"
integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==
+"@babel/helper-validator-identifier@^7.22.20":
+ version "7.22.20"
+ resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0"
+ integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==
+
"@babel/helper-validator-option@^7.16.7", "@babel/helper-validator-option@^7.21.0":
version "7.21.0"
resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz#8224c7e13ace4bafdc4004da2cf064ef42673180"
integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==
+"@babel/helper-validator-option@^7.22.15":
+ version "7.23.5"
+ resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307"
+ integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==
+
"@babel/helper-wrap-function@^7.18.9":
version "7.20.5"
resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz#75e2d84d499a0ab3b31c33bcfe59d6b8a45f62e3"
@@ -494,6 +528,13 @@
dependencies:
"@babel/helper-plugin-utils" "^7.8.0"
+"@babel/plugin-syntax-jsx@^7.23.3":
+ version "7.23.3"
+ resolved "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz#8f2e4f8a9b5f9aa16067e142c1ac9cd9f810f473"
+ integrity sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.22.5"
+
"@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3":
version "7.10.4"
resolved "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699"
@@ -742,6 +783,39 @@
dependencies:
"@babel/helper-plugin-utils" "^7.18.6"
+"@babel/plugin-transform-react-display-name@^7.23.3":
+ version "7.23.3"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz#70529f034dd1e561045ad3c8152a267f0d7b6200"
+ integrity sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.22.5"
+
+"@babel/plugin-transform-react-jsx-development@^7.22.5":
+ version "7.22.5"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz#e716b6edbef972a92165cd69d92f1255f7e73e87"
+ integrity sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==
+ dependencies:
+ "@babel/plugin-transform-react-jsx" "^7.22.5"
+
+"@babel/plugin-transform-react-jsx@^7.22.15", "@babel/plugin-transform-react-jsx@^7.22.5":
+ version "7.23.4"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz#393f99185110cea87184ea47bcb4a7b0c2e39312"
+ integrity sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.22.5"
+ "@babel/helper-module-imports" "^7.22.15"
+ "@babel/helper-plugin-utils" "^7.22.5"
+ "@babel/plugin-syntax-jsx" "^7.23.3"
+ "@babel/types" "^7.23.4"
+
+"@babel/plugin-transform-react-pure-annotations@^7.23.3":
+ version "7.23.3"
+ resolved "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz#fabedbdb8ee40edf5da96f3ecfc6958e3783b93c"
+ integrity sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.22.5"
+ "@babel/helper-plugin-utils" "^7.22.5"
+
"@babel/plugin-transform-regenerator@^7.18.0":
version "7.21.5"
resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.21.5.tgz#576c62f9923f94bcb1c855adc53561fd7913724e"
@@ -910,6 +984,18 @@
"@babel/types" "^7.4.4"
esutils "^2.0.2"
+"@babel/preset-react@^7.23.3":
+ version "7.23.3"
+ resolved "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.23.3.tgz#f73ca07e7590f977db07eb54dbe46538cc015709"
+ integrity sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.22.5"
+ "@babel/helper-validator-option" "^7.22.15"
+ "@babel/plugin-transform-react-display-name" "^7.23.3"
+ "@babel/plugin-transform-react-jsx" "^7.22.15"
+ "@babel/plugin-transform-react-jsx-development" "^7.22.5"
+ "@babel/plugin-transform-react-pure-annotations" "^7.23.3"
+
"@babel/preset-typescript@7.17.12":
version "7.17.12"
resolved "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.17.12.tgz#40269e0a0084d56fc5731b6c40febe1c9a4a3e8c"
@@ -965,6 +1051,15 @@
"@babel/helper-validator-identifier" "^7.19.1"
to-fast-properties "^2.0.0"
+"@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.4":
+ version "7.23.9"
+ resolved "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz#1dd7b59a9a2b5c87f8b41e52770b5ecbf492e002"
+ integrity sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==
+ dependencies:
+ "@babel/helper-string-parser" "^7.23.4"
+ "@babel/helper-validator-identifier" "^7.22.20"
+ to-fast-properties "^2.0.0"
+
"@bcoe/v8-coverage@^0.2.3":
version "0.2.3"
resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
From 2f3306276e50799d32f6568dc9a415ac1e9446d9 Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 12:55:52 -0500
Subject: [PATCH 10/51] Improve typing of `applyAttributes`
- more explicit `ExcludedComponent` type
- correct `JSXOpeningElement` node type
- extract helper to fetch the component name
- remove unnecessary checks
---
.../component-annotate-plugin/src/index.ts | 138 ++++++++++--------
1 file changed, 81 insertions(+), 57 deletions(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index ad78d268..8942d54a 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -53,6 +53,8 @@ interface AnnotationPluginPass extends PluginPass {
opts: AnnotationOpts;
}
+type ExcludedComponent = [file: string, component: string, element: string];
+
type AnnotationPlugin = PluginObj;
export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlugin {
@@ -77,7 +79,7 @@ export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlu
path.node.id.name,
sourceFileNameFromState(state),
attributeNamesFromState(state),
- this["excludedComponents"] as string[]
+ this["excludedComponents"] as ExcludedComponent[]
);
},
ArrowFunctionExpression(path, state) {
@@ -97,7 +99,7 @@ export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlu
parent.id.name,
sourceFileNameFromState(state),
attributeNamesFromState(state),
- this["excludedComponents"] as string[]
+ this["excludedComponents"] as ExcludedComponent[]
);
},
ClassDeclaration(path, state) {
@@ -124,7 +126,7 @@ export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlu
name.node && name.node.name,
sourceFileNameFromState(state),
attributeNamesFromState(state),
- excludedComponents as string[]
+ excludedComponents as ExcludedComponent[]
);
},
});
@@ -140,7 +142,7 @@ function functionBodyPushAttributes(
componentName: string,
sourceFileName: string | undefined,
attributeNames: string[],
- excludedComponents?: string[]
+ excludedComponents: ExcludedComponent[]
) {
let jsxNode: Babel.NodePath;
@@ -202,24 +204,27 @@ function processJSX(
componentName: string | null,
sourceFileName: string | undefined,
attributeNames: string[],
- excludedComponents?: string[]
+ excludedComponents: ExcludedComponent[]
) {
if (!jsxNode) {
return;
}
- // only a JSXElement contains openingElement
- const openingElement = jsxNode.get("openingElement");
- if (Array.isArray(openingElement)) return;
-
- applyAttributes(
- t,
- openingElement,
- componentName,
- sourceFileName,
- attributeNames,
- excludedComponents
- );
+ // NOTE: I don't know of a case where `openingElement` would have more than one item,
+ // but it's safer to always iterate
+ const paths = jsxNode.get("openingElement");
+ const openingElements = Array.isArray(paths) ? paths : [paths];
+
+ openingElements.forEach((openingElement) => {
+ applyAttributes(
+ t,
+ openingElement as Babel.NodePath,
+ componentName,
+ sourceFileName,
+ attributeNames,
+ excludedComponents
+ );
+ });
let children = jsxNode.get("children");
@@ -265,74 +270,73 @@ function processJSX(
function applyAttributes(
t: typeof Babel.types,
- openingElement: Babel.NodePath,
+ openingElement: Babel.NodePath,
componentName: string | null,
sourceFileName: string | undefined,
attributeNames: string[],
- excludedComponents?: string[]
+ excludedComponents: ExcludedComponent[]
) {
const [componentAttributeName, elementAttributeName, sourceFileAttributeName] = attributeNames;
- if (
- !openingElement ||
- isReactFragment(openingElement) ||
- !openingElement.node ||
- !("name" in openingElement.node)
- ) {
- return;
- }
-
- if (!openingElement.node.attributes) openingElement.node.attributes = {};
+ if (isReactFragment(openingElement)) return;
- const elementName = openingElement.node.name.name || "unknown";
+ if (!openingElement.node.attributes) openingElement.node.attributes = [];
+ const elementName = getPathName(openingElement);
- const ignoredComponentFromOptions =
- excludedComponents &&
- !!excludedComponents.find(
- (component) =>
- matchesIgnoreRule(component[0], sourceFileName) &&
- matchesIgnoreRule(component[1], componentName) &&
- matchesIgnoreRule(component[2], elementName)
- );
+ const isAnIgnoredComponent = excludedComponents.some(
+ (excludedComponent) =>
+ matchesIgnoreRule(excludedComponent[0], sourceFileName) &&
+ matchesIgnoreRule(excludedComponent[1], componentName) &&
+ matchesIgnoreRule(excludedComponent[2], elementName)
+ );
- let ignoredElement = false;
// Add a stable attribute for the element name but only for non-DOM names
+ let isAnIgnoredElement = false;
if (
- !ignoredComponentFromOptions &&
- !hasNodeNamed(openingElement, componentAttributeName) &&
+ !isAnIgnoredComponent &&
+ !hasAttributeWithName(openingElement, componentAttributeName) &&
// if componentAttributeName and elementAttributeName are set to the same thing (fsTagName), then only set the element attribute when we don't have a component attribute
(componentAttributeName !== elementAttributeName || !componentName)
) {
if (DEFAULT_IGNORED_ELEMENTS.includes(elementName)) {
- ignoredElement = true;
+ isAnIgnoredElement = true;
} else {
- openingElement.node.attributes.push(
- t.jSXAttribute(t.jSXIdentifier(elementAttributeName), t.stringLiteral(elementName))
- );
+ // TODO: Is it possible to avoid this null check?
+ if (elementAttributeName) {
+ openingElement.node.attributes.push(
+ t.jSXAttribute(t.jSXIdentifier(elementAttributeName), t.stringLiteral(elementName))
+ );
+ }
}
}
// Add a stable attribute for the component name (absent for non-root elements)
if (
componentName &&
- !ignoredComponentFromOptions &&
- !hasNodeNamed(openingElement, componentAttributeName)
+ !isAnIgnoredComponent &&
+ !hasAttributeWithName(openingElement, componentAttributeName)
) {
- openingElement.node.attributes.push(
- t.jSXAttribute(t.jSXIdentifier(componentAttributeName), t.stringLiteral(componentName))
- );
+ // TODO: Is it possible to avoid this null check?
+ if (componentAttributeName) {
+ openingElement.node.attributes.push(
+ t.jSXAttribute(t.jSXIdentifier(componentAttributeName), t.stringLiteral(componentName))
+ );
+ }
}
// Add a stable attribute for the source file name (absent for non-root elements)
if (
sourceFileName &&
- !ignoredComponentFromOptions &&
- (componentName || ignoredElement === false) &&
- !hasNodeNamed(openingElement, sourceFileAttributeName)
+ !isAnIgnoredComponent &&
+ (componentName || isAnIgnoredElement === false) &&
+ !hasAttributeWithName(openingElement, sourceFileAttributeName)
) {
- openingElement.node.attributes.push(
- t.jSXAttribute(t.jSXIdentifier(sourceFileAttributeName), t.stringLiteral(sourceFileName))
- );
+ // TODO: Is it possible to avoid this null check?
+ if (sourceFileAttributeName) {
+ openingElement.node.attributes.push(
+ t.jSXAttribute(t.jSXIdentifier(sourceFileAttributeName), t.stringLiteral(sourceFileName))
+ );
+ }
}
}
@@ -430,9 +434,29 @@ function matchesIgnoreRule(rule, name) {
return rule === "*" || rule === name;
}
-function hasNodeNamed(openingElement, name) {
+function hasAttributeWithName(openingElement, name) {
return openingElement.node.attributes.find((node) => {
if (!node.name) return;
return node.name.name === name;
});
}
+
+function getPathName(path: Babel.NodePath): string {
+ if (!path.node) return UNKNOWN_ELEMENT_NAME;
+ if (!("name" in path.node)) return UNKNOWN_ELEMENT_NAME;
+
+ const name = path.node.name;
+ if (typeof name === "string") return name;
+
+ if (path.isIdentifier() || path.isJSXIdentifier()) {
+ return path.node.name;
+ }
+
+ if (path.isJSXNamespacedName()) {
+ return path.node.name.name;
+ }
+
+ return UNKNOWN_ELEMENT_NAME;
+}
+
+const UNKNOWN_ELEMENT_NAME = "unknown";
From e35150fee435f9856fce3695cceb3a4c392beab7 Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 12:59:48 -0500
Subject: [PATCH 11/51] Improve `isReactFragment`
- remove redundant name finding logic
- add explicit return type
---
.../component-annotate-plugin/src/index.ts | 32 +++----------------
1 file changed, 4 insertions(+), 28 deletions(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index 8942d54a..03d567df 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -395,39 +395,15 @@ function attributeNamesFromState(state: AnnotationPluginPass): [string, string,
return [webComponentName, webElementName, webSourceFileName];
}
-function isReactFragment(openingElement: Babel.NodePath) {
+function isReactFragment(openingElement: Babel.NodePath): boolean {
if (openingElement.isJSXFragment()) {
return true;
}
- if (!openingElement.node) return;
- if (!("name" in openingElement.node)) return;
- if (!openingElement.node.name) return;
-
- let name;
- if (typeof openingElement.node.name === "string") {
- name = openingElement.node.name;
- } else if ("name" in openingElement.node.name) {
- name = openingElement.node.name.name;
- }
-
- if (!name) return;
-
- if (name === "Fragment" || name === "React.Fragment") return true;
-
- if (!("type" in openingElement))
- if (
- !openingElement.node.name.type ||
- !openingElement.node.name.object ||
- !openingElement.node.name.property
- )
- return;
+ const elementName = getPathName(openingElement);
+ if (elementName === "Fragment" || elementName === "React.Fragment") return true;
- return (
- openingElement.node.name.type === "JSXMemberExpression" &&
- openingElement.node.name.object.name === "React" &&
- openingElement.node.name.property.name === "Fragment"
- );
+ return false;
}
function matchesIgnoreRule(rule, name) {
From 30fabf21c40ca2687b5734a9dcb24ceb8fa239e2 Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 13:00:17 -0500
Subject: [PATCH 12/51] Add types to `matchesIgnoreRule`
---
packages/component-annotate-plugin/src/index.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index 03d567df..76e0e7e4 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -406,7 +406,7 @@ function isReactFragment(openingElement: Babel.NodePath): boolean {
return false;
}
-function matchesIgnoreRule(rule, name) {
+function matchesIgnoreRule(rule: string, name: string) {
return rule === "*" || rule === name;
}
From 7be1a2e4242f30f37202648e30078c6754e24456 Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 13:03:22 -0500
Subject: [PATCH 13/51] Improve `hasAttributeWithName`
- add types
- add explicit type checking logic
---
packages/component-annotate-plugin/src/index.ts | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index 76e0e7e4..6bb07ded 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -410,10 +410,16 @@ function matchesIgnoreRule(rule: string, name: string) {
return rule === "*" || rule === name;
}
-function hasAttributeWithName(openingElement, name) {
- return openingElement.node.attributes.find((node) => {
- if (!node.name) return;
- return node.name.name === name;
+function hasAttributeWithName(
+ openingElement: Babel.NodePath,
+ name: string
+): boolean {
+ return openingElement.node.attributes.some((node) => {
+ if (node.type === "JSXAttribute") {
+ return node.name.name === name;
+ }
+
+ return false;
});
}
From a9bdc698ac303d1ac4446930cc7428aa46e65de9 Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 13:04:53 -0500
Subject: [PATCH 14/51] Loosen types on string comparisons
---
packages/component-annotate-plugin/src/index.ts | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index 6bb07ded..70c9aedb 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -406,14 +406,17 @@ function isReactFragment(openingElement: Babel.NodePath): boolean {
return false;
}
-function matchesIgnoreRule(rule: string, name: string) {
+function matchesIgnoreRule(rule: string, name: string | undefined | null) {
+ if (!name) return false;
return rule === "*" || rule === name;
}
function hasAttributeWithName(
openingElement: Babel.NodePath,
- name: string
+ name: string | undefined | null
): boolean {
+ if (!name) return false;
+
return openingElement.node.attributes.some((node) => {
if (node.type === "JSXAttribute") {
return node.name.name === name;
From a726b39790774bcac2ce2f8ecf65dfbc7479c6d4 Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 13:06:55 -0500
Subject: [PATCH 15/51] Remove FSTagName
---
packages/component-annotate-plugin/src/index.ts | 15 ++-------------
1 file changed, 2 insertions(+), 13 deletions(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index 70c9aedb..a208ab49 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -40,10 +40,8 @@ const webSourceFileName = "data-sentry-source-file";
const nativeComponentName = "dataSentryComponent";
const nativeElementName = "dataSentryElement";
const nativeSourceFileName = "dataSentrySourceFile";
-const fsTagName = "fsTagName";
interface AnnotationOpts {
- setFSTagName?: boolean;
native?: boolean;
"annotate-fragments"?: boolean;
excludedComponents?: boolean;
@@ -61,11 +59,6 @@ export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlu
return {
pre() {
this["excludedComponents"] = this.opts["excludedComponents"] || [];
- if (this.opts.setFSTagName && !this.opts.native) {
- throw new Error(
- "`setFSTagName: true` is invalid unless `native: true` is also set in the configuration for @fullstory/babel-plugin-annotate-react"
- );
- }
},
visitor: {
FunctionDeclaration(path, state) {
@@ -295,7 +288,6 @@ function applyAttributes(
if (
!isAnIgnoredComponent &&
!hasAttributeWithName(openingElement, componentAttributeName) &&
- // if componentAttributeName and elementAttributeName are set to the same thing (fsTagName), then only set the element attribute when we don't have a component attribute
(componentAttributeName !== elementAttributeName || !componentName)
) {
if (DEFAULT_IGNORED_ELEMENTS.includes(elementName)) {
@@ -386,12 +378,9 @@ function isKnownIncompatiblePluginFromState(state: AnnotationPluginPass) {
function attributeNamesFromState(state: AnnotationPluginPass): [string, string, string] {
if (state.opts.native) {
- if (state.opts.setFSTagName) {
- return [fsTagName, fsTagName, nativeSourceFileName];
- } else {
- return [nativeComponentName, nativeElementName, nativeSourceFileName];
- }
+ return [nativeComponentName, nativeElementName, nativeSourceFileName];
}
+
return [webComponentName, webElementName, webSourceFileName];
}
From ca3aa49a950d429aaac686b24b0b9a2c9c05b481 Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 13:08:44 -0500
Subject: [PATCH 16/51] Remove unnecessary state
---
packages/component-annotate-plugin/src/index.ts | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index a208ab49..dfa53c31 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -44,7 +44,7 @@ const nativeSourceFileName = "dataSentrySourceFile";
interface AnnotationOpts {
native?: boolean;
"annotate-fragments"?: boolean;
- excludedComponents?: boolean;
+ excludedComponents?: ExcludedComponent[];
}
interface AnnotationPluginPass extends PluginPass {
@@ -57,9 +57,6 @@ type AnnotationPlugin = PluginObj;
export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlugin {
return {
- pre() {
- this["excludedComponents"] = this.opts["excludedComponents"] || [];
- },
visitor: {
FunctionDeclaration(path, state) {
if (!path.node.id || !path.node.id.name) return;
@@ -72,7 +69,7 @@ export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlu
path.node.id.name,
sourceFileNameFromState(state),
attributeNamesFromState(state),
- this["excludedComponents"] as ExcludedComponent[]
+ state.opts.excludedComponents ?? []
);
},
ArrowFunctionExpression(path, state) {
@@ -92,7 +89,7 @@ export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlu
parent.id.name,
sourceFileNameFromState(state),
attributeNamesFromState(state),
- this["excludedComponents"] as ExcludedComponent[]
+ state.opts.excludedComponents ?? []
);
},
ClassDeclaration(path, state) {
@@ -105,7 +102,7 @@ export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlu
if (!render || !render.traverse) return;
if (isKnownIncompatiblePluginFromState(state)) return;
- const excludedComponents = this["excludedComponents"];
+ const excludedComponents = state.opts.excludedComponents ?? [];
render.traverse({
ReturnStatement(returnStatement) {
@@ -119,7 +116,7 @@ export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlu
name.node && name.node.name,
sourceFileNameFromState(state),
attributeNamesFromState(state),
- excludedComponents as ExcludedComponent[]
+ excludedComponents
);
},
});
From cea5c8a834118a6f64debc34d307853cd632c330 Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 13:12:01 -0500
Subject: [PATCH 17/51] Improve `isKnownIncompatiblePluginFromState`
- cleaner iteration pattern
- remove unneeded `as`
---
packages/component-annotate-plugin/src/index.ts | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index dfa53c31..fd035434 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -357,20 +357,21 @@ function fullSourceFileNameFromState(state: AnnotationPluginPass) {
function isKnownIncompatiblePluginFromState(state: AnnotationPluginPass) {
const fullSourceFileName = fullSourceFileNameFromState(state);
+
if (fullSourceFileName == undefined) {
return false;
}
- for (let i = 0; i < KNOWN_INCOMPATIBLE_PLUGINS.length; i += 1) {
- const pluginName = KNOWN_INCOMPATIBLE_PLUGINS[i] as string;
+
+ return KNOWN_INCOMPATIBLE_PLUGINS.some((pluginName) => {
if (
fullSourceFileName.includes("/node_modules/" + pluginName + "/") ||
fullSourceFileName.includes("\\node_modules\\" + pluginName + "\\")
) {
return true;
}
- }
- return false;
+ return false;
+ });
}
function attributeNamesFromState(state: AnnotationPluginPass): [string, string, string] {
From 137400daebba40444d0262abb67fb36883ec298e Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 13:56:09 -0500
Subject: [PATCH 18/51] Fix component name fetching
- fix incorrect logic that was based on the path
- add some clarifying comments
---
.../component-annotate-plugin/src/index.ts | 20 ++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index fd035434..d8c97d3b 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -268,10 +268,11 @@ function applyAttributes(
) {
const [componentAttributeName, elementAttributeName, sourceFileAttributeName] = attributeNames;
- if (isReactFragment(openingElement)) return;
+ if (isReactFragment(t, openingElement)) return;
+ if (!openingElement.node) return; // e.g., Raw JSX text like the `A` in `a
`
if (!openingElement.node.attributes) openingElement.node.attributes = [];
- const elementName = getPathName(openingElement);
+ const elementName = getPathName(t, openingElement);
const isAnIgnoredComponent = excludedComponents.some(
(excludedComponent) =>
@@ -382,12 +383,12 @@ function attributeNamesFromState(state: AnnotationPluginPass): [string, string,
return [webComponentName, webElementName, webSourceFileName];
}
-function isReactFragment(openingElement: Babel.NodePath): boolean {
+function isReactFragment(t: typeof Babel.types, openingElement: Babel.NodePath): boolean {
if (openingElement.isJSXFragment()) {
return true;
}
- const elementName = getPathName(openingElement);
+ const elementName = getPathName(t, openingElement);
if (elementName === "Fragment" || elementName === "React.Fragment") return true;
return false;
@@ -413,19 +414,20 @@ function hasAttributeWithName(
});
}
-function getPathName(path: Babel.NodePath): string {
+function getPathName(t: typeof Babel.types, path: Babel.NodePath): string {
if (!path.node) return UNKNOWN_ELEMENT_NAME;
if (!("name" in path.node)) return UNKNOWN_ELEMENT_NAME;
const name = path.node.name;
+
if (typeof name === "string") return name;
- if (path.isIdentifier() || path.isJSXIdentifier()) {
- return path.node.name;
+ if (t.isIdentifier(name) || t.isJSXIdentifier(name)) {
+ return name.name;
}
- if (path.isJSXNamespacedName()) {
- return path.node.name.name;
+ if (t.isJSXNamespacedName(name)) {
+ return name.name.name;
}
return UNKNOWN_ELEMENT_NAME;
From f7bb682d1b2d9230557cba435d431374f67f823b Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 15:02:57 -0500
Subject: [PATCH 19/51] Improve `processJSX` handling
- more robust logic for checking for arrays
- more robust null checks for missing child nodes
- improve old-school iteration patterns
---
.../component-annotate-plugin/src/index.ts | 71 ++++++++++---------
1 file changed, 36 insertions(+), 35 deletions(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index d8c97d3b..f052ccaa 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -217,45 +217,46 @@ function processJSX(
});
let children = jsxNode.get("children");
-
- if (children && !Array.isArray(children)) {
+ // TODO: See why `Array.isArray` doesn't have correct behaviour here
+ if (children && !("length" in children)) {
+ // A single child was found, maybe a bit of static text
children = [children];
}
- if (children && children.length) {
- let shouldSetComponentName = annotateFragments;
-
- for (let i = 0; i < children.length; i += 1) {
- const child = children[i];
- if (!child) continue;
- // Children don't receive the data-component attribute so we pass null for componentName unless it's the first child of a Fragment with a node and `annotateFragments` is true
- const openingElement = child.get("openingElement");
- if (Array.isArray(openingElement)) continue;
-
- if (shouldSetComponentName && openingElement && openingElement.node) {
- shouldSetComponentName = false;
- processJSX(
- annotateFragments,
- t,
- child,
- componentName,
- sourceFileName,
- attributeNames,
- excludedComponents
- );
- } else {
- processJSX(
- annotateFragments,
- t,
- child,
- null,
- sourceFileName,
- attributeNames,
- excludedComponents
- );
- }
+ let shouldSetComponentName = annotateFragments;
+
+ children.forEach((child) => {
+ if (!child.node) return; // Happens for some node types like plain text
+
+ // Children don't receive the data-component attribute so we pass null for componentName unless it's the first child of a Fragment with a node and `annotateFragments` is true
+ const openingElement = child.get("openingElement");
+ // TODO: Improve this. We never expect to have multiple opening elements
+ // but if it's possible, this should work
+ if (Array.isArray(openingElement)) return;
+
+ if (shouldSetComponentName && openingElement && openingElement.node) {
+ shouldSetComponentName = false;
+ processJSX(
+ annotateFragments,
+ t,
+ child,
+ componentName,
+ sourceFileName,
+ attributeNames,
+ excludedComponents
+ );
+ } else {
+ processJSX(
+ annotateFragments,
+ t,
+ child,
+ null,
+ sourceFileName,
+ attributeNames,
+ excludedComponents
+ );
}
- }
+ });
}
function applyAttributes(
From c155af2c6554bef802c5c23869ffa902671612bf Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 15:12:45 -0500
Subject: [PATCH 20/51] Rename stale option name
---
.../component-annotate-plugin/src/index.ts | 36 +++++++++----------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index f052ccaa..6884b20c 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -44,14 +44,14 @@ const nativeSourceFileName = "dataSentrySourceFile";
interface AnnotationOpts {
native?: boolean;
"annotate-fragments"?: boolean;
- excludedComponents?: ExcludedComponent[];
+ ignoredComponents?: IgnoredComponent[];
}
interface AnnotationPluginPass extends PluginPass {
opts: AnnotationOpts;
}
-type ExcludedComponent = [file: string, component: string, element: string];
+type IgnoredComponent = [file: string, component: string, element: string];
type AnnotationPlugin = PluginObj;
@@ -69,7 +69,7 @@ export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlu
path.node.id.name,
sourceFileNameFromState(state),
attributeNamesFromState(state),
- state.opts.excludedComponents ?? []
+ state.opts.ignoredComponents ?? []
);
},
ArrowFunctionExpression(path, state) {
@@ -89,7 +89,7 @@ export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlu
parent.id.name,
sourceFileNameFromState(state),
attributeNamesFromState(state),
- state.opts.excludedComponents ?? []
+ state.opts.ignoredComponents ?? []
);
},
ClassDeclaration(path, state) {
@@ -102,7 +102,7 @@ export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlu
if (!render || !render.traverse) return;
if (isKnownIncompatiblePluginFromState(state)) return;
- const excludedComponents = state.opts.excludedComponents ?? [];
+ const ignoredComponents = state.opts.ignoredComponents ?? [];
render.traverse({
ReturnStatement(returnStatement) {
@@ -116,7 +116,7 @@ export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlu
name.node && name.node.name,
sourceFileNameFromState(state),
attributeNamesFromState(state),
- excludedComponents
+ ignoredComponents
);
},
});
@@ -132,7 +132,7 @@ function functionBodyPushAttributes(
componentName: string,
sourceFileName: string | undefined,
attributeNames: string[],
- excludedComponents: ExcludedComponent[]
+ ignoredComponents: IgnoredComponent[]
) {
let jsxNode: Babel.NodePath;
@@ -183,7 +183,7 @@ function functionBodyPushAttributes(
componentName,
sourceFileName,
attributeNames,
- excludedComponents
+ ignoredComponents
);
}
@@ -194,7 +194,7 @@ function processJSX(
componentName: string | null,
sourceFileName: string | undefined,
attributeNames: string[],
- excludedComponents: ExcludedComponent[]
+ ignoredComponents: IgnoredComponent[]
) {
if (!jsxNode) {
return;
@@ -212,7 +212,7 @@ function processJSX(
componentName,
sourceFileName,
attributeNames,
- excludedComponents
+ ignoredComponents
);
});
@@ -243,7 +243,7 @@ function processJSX(
componentName,
sourceFileName,
attributeNames,
- excludedComponents
+ ignoredComponents
);
} else {
processJSX(
@@ -253,7 +253,7 @@ function processJSX(
null,
sourceFileName,
attributeNames,
- excludedComponents
+ ignoredComponents
);
}
});
@@ -265,7 +265,7 @@ function applyAttributes(
componentName: string | null,
sourceFileName: string | undefined,
attributeNames: string[],
- excludedComponents: ExcludedComponent[]
+ ignoredComponents: IgnoredComponent[]
) {
const [componentAttributeName, elementAttributeName, sourceFileAttributeName] = attributeNames;
@@ -275,11 +275,11 @@ function applyAttributes(
if (!openingElement.node.attributes) openingElement.node.attributes = [];
const elementName = getPathName(t, openingElement);
- const isAnIgnoredComponent = excludedComponents.some(
- (excludedComponent) =>
- matchesIgnoreRule(excludedComponent[0], sourceFileName) &&
- matchesIgnoreRule(excludedComponent[1], componentName) &&
- matchesIgnoreRule(excludedComponent[2], elementName)
+ const isAnIgnoredComponent = ignoredComponents.some(
+ (ignoredComponent) =>
+ matchesIgnoreRule(ignoredComponent[0], sourceFileName) &&
+ matchesIgnoreRule(ignoredComponent[1], componentName) &&
+ matchesIgnoreRule(ignoredComponent[2], elementName)
);
// Add a stable attribute for the element name but only for non-DOM names
From 9aea4c832fd014fdb2d642d4155c67f93b182c01 Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 15:23:11 -0500
Subject: [PATCH 21/51] Improve file name logic
- use correctly type-incorrect property
- add stricter types
---
.../component-annotate-plugin/src/index.ts | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index 6884b20c..50bcbe53 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -333,7 +333,7 @@ function applyAttributes(
function sourceFileNameFromState(state: AnnotationPluginPass) {
const name = fullSourceFileNameFromState(state);
- if (name === undefined) {
+ if (!name) {
return undefined;
}
@@ -346,23 +346,21 @@ function sourceFileNameFromState(state: AnnotationPluginPass) {
}
}
-function fullSourceFileNameFromState(state: AnnotationPluginPass) {
- // NOTE: This was originally written as `sourceFileName` which is incorrect according to Babel types
- const name = state.file.opts.parserOpts?.sourceFilename;
+function fullSourceFileNameFromState(state: AnnotationPluginPass): string | null {
+ // @ts-expect-error This type is incorrect in Babel, `sourceFileName` is the correct type
+ const name = state.file.opts.parserOpts?.sourceFileName as unknown;
- if (typeof name !== "string") {
- return undefined;
+ if (typeof name === "string") {
+ return name;
}
- return name;
+ return null;
}
function isKnownIncompatiblePluginFromState(state: AnnotationPluginPass) {
const fullSourceFileName = fullSourceFileNameFromState(state);
- if (fullSourceFileName == undefined) {
- return false;
- }
+ if (!fullSourceFileName) return false;
return KNOWN_INCOMPATIBLE_PLUGINS.some((pluginName) => {
if (
From f5617cb9a24322294283d4636532fc398bfdd116 Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 15:56:55 -0500
Subject: [PATCH 22/51] Update plugin import
---
packages/component-annotate-plugin/test/test-plugin.test.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/component-annotate-plugin/test/test-plugin.test.ts b/packages/component-annotate-plugin/test/test-plugin.test.ts
index ffe5759c..ebc035f4 100644
--- a/packages/component-annotate-plugin/test/test-plugin.test.ts
+++ b/packages/component-annotate-plugin/test/test-plugin.test.ts
@@ -24,7 +24,7 @@
*/
import { transform } from "@babel/core";
-import { componentNameAnnotatePlugin as plugin } from "../src/index";
+import plugin from "../src/index";
const BananasPizzaAppStandardInput = `import React, { Component } from 'react';
import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
From 696856f7f1fe547dc5ea6727fa76049062f28558 Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 15:57:04 -0500
Subject: [PATCH 23/51] Ignore Babel config file
---
.../test/test-plugin.test.ts | 105 ++++++++++++------
1 file changed, 70 insertions(+), 35 deletions(-)
diff --git a/packages/component-annotate-plugin/test/test-plugin.test.ts b/packages/component-annotate-plugin/test/test-plugin.test.ts
index ebc035f4..d4fc0406 100644
--- a/packages/component-annotate-plugin/test/test-plugin.test.ts
+++ b/packages/component-annotate-plugin/test/test-plugin.test.ts
@@ -1219,7 +1219,8 @@ class componentName extends Component {
export default componentName;
`,
{
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [plugin],
}
@@ -1240,7 +1241,8 @@ class componentName extends Component {
export default componentName;
`,
{
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [plugin],
}
@@ -1261,7 +1263,8 @@ class componentName extends Component {
export default componentName;
`,
{
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [plugin],
}
@@ -1282,7 +1285,8 @@ class componentName extends Component {
export default componentName;
`,
{
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [plugin],
}
@@ -1303,7 +1307,8 @@ class componentName extends Component {
export default componentName;
`,
{
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [plugin],
}
@@ -1326,7 +1331,8 @@ class componentName extends Component {
export default componentName;
`,
{
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { "annotate-fragments": true }]],
}
@@ -1349,7 +1355,8 @@ class componentName extends Component {
export default componentName;
`,
{
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { "annotate-fragments": true }]],
}
@@ -1370,7 +1377,8 @@ const componentName = () => (
export default componentName;
`,
{
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [plugin],
}
@@ -1391,7 +1399,8 @@ const componentName = () => (
export default componentName;
`,
{
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [plugin],
}
@@ -1430,7 +1439,8 @@ const componentName = () => (
export default componentName;
`,
{
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { "annotate-fragments": true }]],
}
@@ -1451,7 +1461,8 @@ const componentName = () => (
export default componentName;
`,
{
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { "annotate-fragments": true }]],
}
@@ -1472,7 +1483,8 @@ const componentName = () => (
export default componentName;
`,
{
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { "annotate-fragments": true }]],
}
@@ -1493,7 +1505,8 @@ const componentName = () => (
export default componentName;
`,
{
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { "annotate-fragments": true }]],
}
@@ -1515,7 +1528,8 @@ const componentName = () => (
export default componentName;
`,
{
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { "annotate-fragments": true }]],
}
@@ -1534,7 +1548,8 @@ const componentName = () => (
export default componentName;
`,
{
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { "annotate-fragments": true }]],
}
@@ -1825,7 +1840,8 @@ const styles = StyleSheet.create({
});
`,
{
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true }]],
}
@@ -2140,7 +2156,8 @@ class PureComponentName extends React.PureComponent {
export default PureComponentName;
`,
{
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true }]],
}
@@ -2150,7 +2167,8 @@ export default PureComponentName;
it("Bananas ignore components dataSentrySourceFile=nomatch dataSentryComponent=nomatch dataSentryElement=nomatch snapshot matches", () => {
const result = transform(BananasStandardInput, {
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "nomatch", "nomatch"]] }]],
});
@@ -2210,7 +2228,8 @@ it("Bananas ignore components dataSentrySourceFile=nomatch dataSentryComponent=n
it("ignore components dataSentrySourceFile=* dataSentryComponent=nomatch dataSentryElement=nomatch snapshot matches", () => {
const result = transform(BananasStandardInput, {
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["*", "nomatch", "nomatch"]] }]],
});
@@ -2270,7 +2289,8 @@ it("ignore components dataSentrySourceFile=* dataSentryComponent=nomatch dataSen
it("Bananas ignore components dataSentrySourceFile=nomatch dataSentryComponent=* dataSentryElement=nomatch snapshot matches", () => {
const result = transform(BananasStandardInput, {
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "*", "nomatch"]] }]],
});
@@ -2330,7 +2350,8 @@ it("Bananas ignore components dataSentrySourceFile=nomatch dataSentryComponent=*
it("Bananas ignore components dataSentrySourceFile=nomatch dataSentryComponent=nomatch dataSentryElement=* snapshot matches", () => {
const result = transform(BananasStandardInput, {
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "nomatch", "*"]] }]],
});
@@ -2390,7 +2411,8 @@ it("Bananas ignore components dataSentrySourceFile=nomatch dataSentryComponent=n
it("Bananas ignore components dataSentrySourceFile=* dataSentryComponent=* dataSentryElement=nomatch snapshot matches", () => {
const result = transform(BananasStandardInput, {
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "nomatch", "nomatch"]] }]],
});
@@ -2450,7 +2472,8 @@ it("Bananas ignore components dataSentrySourceFile=* dataSentryComponent=* dataS
it("Bananas ignore components dataSentrySourceFile=* dataSentryComponent=nomatch dataSentryElement=* snapshot matches", () => {
const result = transform(BananasStandardInput, {
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "nomatch", "nomatch"]] }]],
});
@@ -2510,7 +2533,8 @@ it("Bananas ignore components dataSentrySourceFile=* dataSentryComponent=nomatch
it("Bananas ignore components dataSentrySourceFile=nomatch dataSentryComponent=* dataSentryElement=* snapshot matches", () => {
const result = transform(BananasStandardInput, {
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "nomatch", "nomatch"]] }]],
});
@@ -2571,7 +2595,8 @@ it("Bananas ignore components dataSentrySourceFile=nomatch dataSentryComponent=*
// This tests out matching only `dataSentryElement`, with * for the others
it("Bananas ignore components dataSentrySourceFile=* dataSentryComponent=* dataSentryElement=match snapshot matches", () => {
const result = transform(BananasStandardInput, {
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["*", "*", "Image"]] }]],
});
@@ -2629,7 +2654,8 @@ it("Bananas ignore components dataSentrySourceFile=* dataSentryComponent=* dataS
// This tests out matching only `dataSentryElement` and `dataSentryComponent`, with * for `dataSentrySourceFile`
it("Bananas ignore components dataSentrySourceFile=* dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
const result = transform(BananasStandardInput, {
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["*", "Bananas", "Image"]] }]],
});
@@ -2687,7 +2713,8 @@ it("Bananas ignore components dataSentrySourceFile=* dataSentryComponent=match d
// This tests out matching on all 3 of our ignore list values
it("Bananas ignore components dataSentrySourceFile=match dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
const result = transform(BananasStandardInput, {
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [
[plugin, { native: true, ignoreComponents: [["filename-test.js", "Bananas", "Image"]] }],
@@ -2747,7 +2774,8 @@ it("Bananas ignore components dataSentrySourceFile=match dataSentryComponent=mat
// This tests out matching on all 3 of our ignore list values via *
it("Bananas/Pizza/App ignore components dataSentrySourceFile=* dataSentryComponent=* dataSentryElement=* snapshot matches", () => {
const result = transform(BananasPizzaAppStandardInput, {
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["*", "*", "*"]] }]],
});
@@ -2875,7 +2903,8 @@ it("Bananas/Pizza/App ignore components dataSentrySourceFile=* dataSentryCompone
// This tests out matching on all 3 of our ignore list values
it("Bananas/Pizza/App ignore components dataSentrySourceFile=nomatch dataSentryComponent=* dataSentryElement=* snapshot matches", () => {
const result = transform(BananasPizzaAppStandardInput, {
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "*", "*"]] }]],
});
@@ -3023,7 +3052,8 @@ it("Bananas/Pizza/App ignore components dataSentrySourceFile=nomatch dataSentryC
it("Bananas/Pizza/App only Bananas dataSentrySourceFile=match dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
const result = transform(BananasPizzaAppStandardInput, {
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [
[
@@ -3178,7 +3208,8 @@ it("Bananas/Pizza/App only Bananas dataSentrySourceFile=match dataSentryComponen
it("Bananas/Pizza/App only Pizza dataSentrySourceFile=match dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
const result = transform(BananasPizzaAppStandardInput, {
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [
[
@@ -3333,7 +3364,8 @@ it("Bananas/Pizza/App only Pizza dataSentrySourceFile=match dataSentryComponent=
it("Bananas/Pizza/App only App dataSentrySourceFile=match dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
const result = transform(BananasPizzaAppStandardInput, {
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [
[
@@ -3488,7 +3520,8 @@ it("Bananas/Pizza/App only App dataSentrySourceFile=match dataSentryComponent=ma
it("Bananas/Pizza/App No Pizza Elements dataSentrySourceFile=match dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
const result = transform(BananasPizzaAppStandardInput, {
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [
[
@@ -3644,7 +3677,8 @@ it("Bananas/Pizza/App No Pizza Elements dataSentrySourceFile=match dataSentryCom
it("Bananas/Pizza/App No Bananas Elements dataSentrySourceFile=match dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
const result = transform(BananasPizzaAppStandardInput, {
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [
[
@@ -3801,7 +3835,8 @@ it("Bananas/Pizza/App No Bananas Elements dataSentrySourceFile=match dataSentryC
it("Bananas/Pizza/App No Bananas/Pizza Elements dataSentrySourceFile=match dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
const result = transform(BananasPizzaAppStandardInput, {
- filename: "./filename-test.js",
+ filename: "/filename-test.js",
+ configFile: false,
presets: ["@babel/preset-react"],
plugins: [
[
From 85d75bd3491f84e4fb98745946d11e1c26819b7c Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 16:17:53 -0500
Subject: [PATCH 24/51] Update incompatible plugins
---
.../src/constants.ts | 31 +++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/packages/component-annotate-plugin/src/constants.ts b/packages/component-annotate-plugin/src/constants.ts
index 127a9301..faddd652 100644
--- a/packages/component-annotate-plugin/src/constants.ts
+++ b/packages/component-annotate-plugin/src/constants.ts
@@ -3,6 +3,37 @@ export const KNOWN_INCOMPATIBLE_PLUGINS = [
"react-native-testfairy",
// This module checks for unexpected property keys and throws an exception.
"@react-navigation",
+ // The victory* modules use `dataComponent` and we get a collision.
+ "victory",
+ "victory-area",
+ "victory-axis",
+ "victory-bar",
+ "victory-box-plot",
+ "victory-brush-container",
+ "victory-brush-line",
+ "victory-candlestick",
+ "victory-canvas",
+ "victory-chart",
+ "victory-core",
+ "victory-create-container",
+ "victory-cursor-container",
+ "victory-errorbar",
+ "victory-group",
+ "victory-histogram",
+ "victory-legend",
+ "victory-line",
+ "victory-native",
+ "victory-pie",
+ "victory-polar-axis",
+ "victory-scatter",
+ "victory-selection-container",
+ "victory-shared-events",
+ "victory-stack",
+ "victory-tooltip",
+ "victory-vendor",
+ "victory-voronoi",
+ "victory-voronoi-container",
+ "victory-zoom-container",
];
export const DEFAULT_IGNORED_ELEMENTS = [
From 0d41794c4380e95761ad69d3a2d73699b6bdcf98 Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 16:50:45 -0500
Subject: [PATCH 25/51] Improve `React.Fragment` handling
Add more robust checking logic
---
.../component-annotate-plugin/src/index.ts | 38 +++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index 50bcbe53..f16eadd4 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -388,8 +388,46 @@ function isReactFragment(t: typeof Babel.types, openingElement: Babel.NodePath):
}
const elementName = getPathName(t, openingElement);
+
if (elementName === "Fragment" || elementName === "React.Fragment") return true;
+ // TODO: All these objects are typed as unknown, maybe an oversight in Babel types?
+ if (
+ openingElement.node &&
+ "name" in openingElement.node &&
+ openingElement.node.name &&
+ typeof openingElement.node.name === "object" &&
+ "type" in openingElement.node.name &&
+ openingElement.node.name.type === "JSXMemberExpression"
+ ) {
+ if (!("name" in openingElement.node)) return false;
+
+ const nodeName = openingElement.node.name;
+ if (typeof nodeName !== "object" || !nodeName) {
+ return false;
+ }
+
+ if ("object" in nodeName && "property" in nodeName) {
+ const nodeNameObject = nodeName.object;
+ const nodeNameProperty = nodeName.property;
+
+ if (typeof nodeNameObject !== "object" || typeof nodeNameProperty !== "object") {
+ return false;
+ }
+
+ if (!nodeNameObject || !nodeNameProperty) {
+ return false;
+ }
+
+ const objectName = "name" in nodeNameObject && nodeNameObject.name;
+ const propertyName = "name" in nodeNameProperty && nodeNameProperty.name;
+
+ if (objectName === "React" && propertyName === "Fragment") {
+ return true;
+ }
+ }
+ }
+
return false;
}
From a513911f5803ebc6f180b292149d1bee54af491e Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 16:57:59 -0500
Subject: [PATCH 26/51] More robust function body checks
Again, `Array.isArray` doesn't do the right thing here.
---
packages/component-annotate-plugin/src/index.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index f16eadd4..8d37c631 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -137,9 +137,9 @@ function functionBodyPushAttributes(
let jsxNode: Babel.NodePath;
const functionBody = path.get("body").get("body");
- if (Array.isArray(functionBody)) return;
if (
+ !("length" in functionBody) &&
functionBody.parent &&
(functionBody.parent.type === "JSXElement" || functionBody.parent.type === "JSXFragment")
) {
From 52ea127ed79d34e4693ed6a9bcbdb14f36da67b9 Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 17:01:35 -0500
Subject: [PATCH 27/51] Fix bad rename
---
packages/component-annotate-plugin/src/index.ts | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index 8d37c631..fd23c365 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -44,7 +44,7 @@ const nativeSourceFileName = "dataSentrySourceFile";
interface AnnotationOpts {
native?: boolean;
"annotate-fragments"?: boolean;
- ignoredComponents?: IgnoredComponent[];
+ ignoreComponents?: IgnoredComponent[];
}
interface AnnotationPluginPass extends PluginPass {
@@ -69,7 +69,7 @@ export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlu
path.node.id.name,
sourceFileNameFromState(state),
attributeNamesFromState(state),
- state.opts.ignoredComponents ?? []
+ state.opts.ignoreComponents ?? []
);
},
ArrowFunctionExpression(path, state) {
@@ -89,7 +89,7 @@ export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlu
parent.id.name,
sourceFileNameFromState(state),
attributeNamesFromState(state),
- state.opts.ignoredComponents ?? []
+ state.opts.ignoreComponents ?? []
);
},
ClassDeclaration(path, state) {
@@ -102,7 +102,7 @@ export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlu
if (!render || !render.traverse) return;
if (isKnownIncompatiblePluginFromState(state)) return;
- const ignoredComponents = state.opts.ignoredComponents ?? [];
+ const ignoredComponents = state.opts.ignoreComponents ?? [];
render.traverse({
ReturnStatement(returnStatement) {
From d9a0477cfa2dcb75faeafb548ca85d0d64292500 Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 17:04:08 -0500
Subject: [PATCH 28/51] Fix logical fault in comparator
Nice try, but the null check needs to be lower
---
packages/component-annotate-plugin/src/index.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index fd23c365..5422e6e7 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -432,7 +432,6 @@ function isReactFragment(t: typeof Babel.types, openingElement: Babel.NodePath):
}
function matchesIgnoreRule(rule: string, name: string | undefined | null) {
- if (!name) return false;
return rule === "*" || rule === name;
}
From d5a67be07f77568a2ce8625381f8dc0c502eebde Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 30 Jan 2024 17:13:13 -0500
Subject: [PATCH 29/51] Remove unnecessary excludes
---
.../src/constants.ts | 31 -------------------
1 file changed, 31 deletions(-)
diff --git a/packages/component-annotate-plugin/src/constants.ts b/packages/component-annotate-plugin/src/constants.ts
index faddd652..127a9301 100644
--- a/packages/component-annotate-plugin/src/constants.ts
+++ b/packages/component-annotate-plugin/src/constants.ts
@@ -3,37 +3,6 @@ export const KNOWN_INCOMPATIBLE_PLUGINS = [
"react-native-testfairy",
// This module checks for unexpected property keys and throws an exception.
"@react-navigation",
- // The victory* modules use `dataComponent` and we get a collision.
- "victory",
- "victory-area",
- "victory-axis",
- "victory-bar",
- "victory-box-plot",
- "victory-brush-container",
- "victory-brush-line",
- "victory-candlestick",
- "victory-canvas",
- "victory-chart",
- "victory-core",
- "victory-create-container",
- "victory-cursor-container",
- "victory-errorbar",
- "victory-group",
- "victory-histogram",
- "victory-legend",
- "victory-line",
- "victory-native",
- "victory-pie",
- "victory-polar-axis",
- "victory-scatter",
- "victory-selection-container",
- "victory-shared-events",
- "victory-stack",
- "victory-tooltip",
- "victory-vendor",
- "victory-voronoi",
- "victory-voronoi-container",
- "victory-zoom-container",
];
export const DEFAULT_IGNORED_ELEMENTS = [
From 981c835525fd2c65b14895025fd48f167c61c5cd Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 10:25:15 -0500
Subject: [PATCH 30/51] remove preset
---
packages/component-annotate-plugin/.babelrc.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/component-annotate-plugin/.babelrc.json b/packages/component-annotate-plugin/.babelrc.json
index 0c20c06e..f878e8f9 100644
--- a/packages/component-annotate-plugin/.babelrc.json
+++ b/packages/component-annotate-plugin/.babelrc.json
@@ -1,3 +1,3 @@
{
- "presets": ["@babel/env", "@babel/typescript"]
+ "presets": ["@babel/typescript"]
}
From 1e567347b70cafe50fa2aeb0a6b132d02dee991a Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 10:28:55 -0500
Subject: [PATCH 31/51] remove irrelevant tests
---
.../test/test-plugin.test.ts | 234 ------------------
1 file changed, 234 deletions(-)
diff --git a/packages/component-annotate-plugin/test/test-plugin.test.ts b/packages/component-annotate-plugin/test/test-plugin.test.ts
index d4fc0406..b36bfe04 100644
--- a/packages/component-annotate-plugin/test/test-plugin.test.ts
+++ b/packages/component-annotate-plugin/test/test-plugin.test.ts
@@ -1181,31 +1181,6 @@ class Bananas extends Component {
}"
`;
-const BananasStandardOutputWithFSTagName = `
-"import React, { Component } from 'react';
-import { Image } from 'react-native';
-
-class Bananas extends Component {
- render() {
- let pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/React.createElement(Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- fsTagName: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
-
-}"
-`;
-
it("unknown-element snapshot matches", () => {
const result = transform(
`import React, { Component } from 'react';
@@ -3989,69 +3964,6 @@ it("Bananas/Pizza/App No Bananas/Pizza Elements dataSentrySourceFile=match dataS
);
});
-it("Bananas incompatible plugin victory-core source snapshot matches", () => {
- const result = transform(BananasStandardInput, {
- filename: "test/node_modules/victory-core/filename-test.js",
- presets: ["@babel/preset-react"],
- plugins: [[plugin, { native: true }]],
- });
- expect(result?.code).toMatchInlineSnapshot(
- `
- "import React, { Component } from 'react';
- import { Image } from 'react-native';
- class Bananas extends Component {
- render() {
- let pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/React.createElement(Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\"
- });
- }
- }"
- `
- );
-});
-
-it("Bananas incompatible plugin victory-valid source snapshot matches", () => {
- const result = transform(BananasStandardInput, {
- filename: "test/node_modules/victory-valid/filename-test.js",
- presets: ["@babel/preset-react"],
- plugins: [[plugin, { native: true }]],
- });
- expect(result?.code).toMatchInlineSnapshot(
- `
- "import React, { Component } from 'react';
- import { Image } from 'react-native';
- class Bananas extends Component {
- render() {
- let pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/React.createElement(Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
- }"
- `
- );
-});
-
it("Bananas incompatible plugin @react-navigation source snapshot matches", () => {
const result = transform(BananasStandardInput, {
filename: "test/node_modules/@react-navigation/core/filename-test.js",
@@ -4081,149 +3993,3 @@ it("Bananas incompatible plugin @react-navigation source snapshot matches", () =
`
);
});
-
-it("setFSTagName sets fsTagName on component with its dataSentryComponent value", () => {
- const result = transform(BananasStandardInput, {
- filename: "filename-test.js",
- presets: ["@babel/preset-react"],
- plugins: [
- [
- plugin,
- {
- native: true,
- setFSTagName: true,
- },
- ],
- ],
- });
- expect(result?.code).toMatchInlineSnapshot(
- `
- "\\"use strict\\";
-
- function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
- var _react = _interopRequireWildcard(require(\\"react\\"));
- var _reactNative = require(\\"react-native\\");
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
- function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
- function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
- function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
- var Bananas = /*#__PURE__*/function (_Component) {
- _inherits(Bananas, _Component);
- var _super = _createSuper(Bananas);
- function Bananas() {
- _classCallCheck(this, Bananas);
- return _super.apply(this, arguments);
- }
- _createClass(Bananas, [{
- key: \\"render\\",
- value: function render() {
- var pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- fsTagName: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
- }]);
- return Bananas;
- }(_react.Component);"
- `
- );
-});
-
-it("Bananas custom attribute names let component override element with setFSTagName", () => {
- const BananasInputCustomFSTagName = `import React, { Component } from 'react';
-import { Image } from 'react-native';
-
-class Bananas extends Component {
- render() {
- let pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return ;
- }
-}`;
-
- const result = transform(BananasInputCustomFSTagName, {
- filename: "filename-test.js",
- presets: ["@babel/preset-react"],
- plugins: [
- [
- plugin,
- {
- native: true,
- setFSTagName: true,
- },
- ],
- ],
- });
- expect(result?.code).toMatchInlineSnapshot(
- `
- "\\"use strict\\";
-
- function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
- var _react = _interopRequireWildcard(require(\\"react\\"));
- var _reactNative = require(\\"react-native\\");
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
- function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
- function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
- function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
- var Bananas = /*#__PURE__*/function (_Component) {
- _inherits(Bananas, _Component);
- var _super = _createSuper(Bananas);
- function Bananas() {
- _classCallCheck(this, Bananas);
- return _super.apply(this, arguments);
- }
- _createClass(Bananas, [{
- key: \\"render\\",
- value: function render() {
- var pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- fsTagName: \\"CustomTagName\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
- }]);
- return Bananas;
- }(_react.Component);"
- `
- );
-});
From 31839a1f8ad5988f1d3fbc56306fc61c90f530ef Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 10:52:55 -0500
Subject: [PATCH 32/51] Update inline snapshots
---
.../test/test-plugin.test.ts | 2164 ++++++-----------
1 file changed, 748 insertions(+), 1416 deletions(-)
diff --git a/packages/component-annotate-plugin/test/test-plugin.test.ts b/packages/component-annotate-plugin/test/test-plugin.test.ts
index b36bfe04..80110ed9 100644
--- a/packages/component-annotate-plugin/test/test-plugin.test.ts
+++ b/packages/component-annotate-plugin/test/test-plugin.test.ts
@@ -2147,58 +2147,29 @@ it("Bananas ignore components dataSentrySourceFile=nomatch dataSentryComponent=n
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "nomatch", "nomatch"]] }]],
});
- expect(result?.code).toMatchInlineSnapshot(
- `
- "\\"use strict\\";
-
- function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
- var _react = _interopRequireWildcard(require(\\"react\\"));
- var _reactNative = require(\\"react-native\\");
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
- function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
- function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
- function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
- var Bananas = /*#__PURE__*/function (_Component) {
- _inherits(Bananas, _Component);
- var _super = _createSuper(Bananas);
- function Bananas() {
- _classCallCheck(this, Bananas);
- return _super.apply(this, arguments);
+ expect(result?.code).toMatchInlineSnapshot(`
+ "import React, { Component } from 'react';
+ import { Image } from 'react-native';
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
}
- _createClass(Bananas, [{
- key: \\"render\\",
- value: function render() {
- var pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
- }]);
- return Bananas;
- }(_react.Component);"
- `
- );
+ }"
+ `);
});
it("ignore components dataSentrySourceFile=* dataSentryComponent=nomatch dataSentryElement=nomatch snapshot matches", () => {
@@ -2208,58 +2179,29 @@ it("ignore components dataSentrySourceFile=* dataSentryComponent=nomatch dataSen
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["*", "nomatch", "nomatch"]] }]],
});
- expect(result?.code).toMatchInlineSnapshot(
- `
- "\\"use strict\\";
-
- function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
- var _react = _interopRequireWildcard(require(\\"react\\"));
- var _reactNative = require(\\"react-native\\");
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
- function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
- function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
- function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
- var Bananas = /*#__PURE__*/function (_Component) {
- _inherits(Bananas, _Component);
- var _super = _createSuper(Bananas);
- function Bananas() {
- _classCallCheck(this, Bananas);
- return _super.apply(this, arguments);
+ expect(result?.code).toMatchInlineSnapshot(`
+ "import React, { Component } from 'react';
+ import { Image } from 'react-native';
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
}
- _createClass(Bananas, [{
- key: \\"render\\",
- value: function render() {
- var pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
- }]);
- return Bananas;
- }(_react.Component);"
- `
- );
+ }"
+ `);
});
it("Bananas ignore components dataSentrySourceFile=nomatch dataSentryComponent=* dataSentryElement=nomatch snapshot matches", () => {
@@ -2269,58 +2211,29 @@ it("Bananas ignore components dataSentrySourceFile=nomatch dataSentryComponent=*
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "*", "nomatch"]] }]],
});
- expect(result?.code).toMatchInlineSnapshot(
- `
- "\\"use strict\\";
-
- function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
- var _react = _interopRequireWildcard(require(\\"react\\"));
- var _reactNative = require(\\"react-native\\");
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
- function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
- function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
- function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
- var Bananas = /*#__PURE__*/function (_Component) {
- _inherits(Bananas, _Component);
- var _super = _createSuper(Bananas);
- function Bananas() {
- _classCallCheck(this, Bananas);
- return _super.apply(this, arguments);
+ expect(result?.code).toMatchInlineSnapshot(`
+ "import React, { Component } from 'react';
+ import { Image } from 'react-native';
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
}
- _createClass(Bananas, [{
- key: \\"render\\",
- value: function render() {
- var pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
- }]);
- return Bananas;
- }(_react.Component);"
- `
- );
+ }"
+ `);
});
it("Bananas ignore components dataSentrySourceFile=nomatch dataSentryComponent=nomatch dataSentryElement=* snapshot matches", () => {
@@ -2330,58 +2243,29 @@ it("Bananas ignore components dataSentrySourceFile=nomatch dataSentryComponent=n
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "nomatch", "*"]] }]],
});
- expect(result?.code).toMatchInlineSnapshot(
- `
- "\\"use strict\\";
-
- function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
- var _react = _interopRequireWildcard(require(\\"react\\"));
- var _reactNative = require(\\"react-native\\");
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
- function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
- function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
- function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
- var Bananas = /*#__PURE__*/function (_Component) {
- _inherits(Bananas, _Component);
- var _super = _createSuper(Bananas);
- function Bananas() {
- _classCallCheck(this, Bananas);
- return _super.apply(this, arguments);
+ expect(result?.code).toMatchInlineSnapshot(`
+ "import React, { Component } from 'react';
+ import { Image } from 'react-native';
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
}
- _createClass(Bananas, [{
- key: \\"render\\",
- value: function render() {
- var pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
- }]);
- return Bananas;
- }(_react.Component);"
- `
- );
+ }"
+ `);
});
it("Bananas ignore components dataSentrySourceFile=* dataSentryComponent=* dataSentryElement=nomatch snapshot matches", () => {
@@ -2391,58 +2275,29 @@ it("Bananas ignore components dataSentrySourceFile=* dataSentryComponent=* dataS
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "nomatch", "nomatch"]] }]],
});
- expect(result?.code).toMatchInlineSnapshot(
- `
- "\\"use strict\\";
-
- function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
- var _react = _interopRequireWildcard(require(\\"react\\"));
- var _reactNative = require(\\"react-native\\");
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
- function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
- function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
- function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
- var Bananas = /*#__PURE__*/function (_Component) {
- _inherits(Bananas, _Component);
- var _super = _createSuper(Bananas);
- function Bananas() {
- _classCallCheck(this, Bananas);
- return _super.apply(this, arguments);
+ expect(result?.code).toMatchInlineSnapshot(`
+ "import React, { Component } from 'react';
+ import { Image } from 'react-native';
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
}
- _createClass(Bananas, [{
- key: \\"render\\",
- value: function render() {
- var pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
- }]);
- return Bananas;
- }(_react.Component);"
- `
- );
+ }"
+ `);
});
it("Bananas ignore components dataSentrySourceFile=* dataSentryComponent=nomatch dataSentryElement=* snapshot matches", () => {
@@ -2452,58 +2307,29 @@ it("Bananas ignore components dataSentrySourceFile=* dataSentryComponent=nomatch
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "nomatch", "nomatch"]] }]],
});
- expect(result?.code).toMatchInlineSnapshot(
- `
- "\\"use strict\\";
-
- function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
- var _react = _interopRequireWildcard(require(\\"react\\"));
- var _reactNative = require(\\"react-native\\");
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
- function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
- function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
- function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
- var Bananas = /*#__PURE__*/function (_Component) {
- _inherits(Bananas, _Component);
- var _super = _createSuper(Bananas);
- function Bananas() {
- _classCallCheck(this, Bananas);
- return _super.apply(this, arguments);
+ expect(result?.code).toMatchInlineSnapshot(`
+ "import React, { Component } from 'react';
+ import { Image } from 'react-native';
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
}
- _createClass(Bananas, [{
- key: \\"render\\",
- value: function render() {
- var pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
- }]);
- return Bananas;
- }(_react.Component);"
- `
- );
+ }"
+ `);
});
it("Bananas ignore components dataSentrySourceFile=nomatch dataSentryComponent=* dataSentryElement=* snapshot matches", () => {
@@ -2513,58 +2339,29 @@ it("Bananas ignore components dataSentrySourceFile=nomatch dataSentryComponent=*
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "nomatch", "nomatch"]] }]],
});
- expect(result?.code).toMatchInlineSnapshot(
- `
- "\\"use strict\\";
-
- function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
- var _react = _interopRequireWildcard(require(\\"react\\"));
- var _reactNative = require(\\"react-native\\");
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
- function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
- function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
- function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
- var Bananas = /*#__PURE__*/function (_Component) {
- _inherits(Bananas, _Component);
- var _super = _createSuper(Bananas);
- function Bananas() {
- _classCallCheck(this, Bananas);
- return _super.apply(this, arguments);
+ expect(result?.code).toMatchInlineSnapshot(`
+ "import React, { Component } from 'react';
+ import { Image } from 'react-native';
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
}
- _createClass(Bananas, [{
- key: \\"render\\",
- value: function render() {
- var pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
- }]);
- return Bananas;
- }(_react.Component);"
- `
- );
+ }"
+ `);
});
// This tests out matching only `dataSentryElement`, with * for the others
@@ -2575,55 +2372,26 @@ it("Bananas ignore components dataSentrySourceFile=* dataSentryComponent=* dataS
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["*", "*", "Image"]] }]],
});
- expect(result?.code).toMatchInlineSnapshot(
- `
- "\\"use strict\\";
-
- function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
- var _react = _interopRequireWildcard(require(\\"react\\"));
- var _reactNative = require(\\"react-native\\");
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
- function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
- function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
- function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
- var Bananas = /*#__PURE__*/function (_Component) {
- _inherits(Bananas, _Component);
- var _super = _createSuper(Bananas);
- function Bananas() {
- _classCallCheck(this, Bananas);
- return _super.apply(this, arguments);
+ expect(result?.code).toMatchInlineSnapshot(`
+ "import React, { Component } from 'react';
+ import { Image } from 'react-native';
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\"
+ });
}
- _createClass(Bananas, [{
- key: \\"render\\",
- value: function render() {
- var pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\"
- });
- }
- }]);
- return Bananas;
- }(_react.Component);"
- `
- );
+ }"
+ `);
});
// This tests out matching only `dataSentryElement` and `dataSentryComponent`, with * for `dataSentrySourceFile`
@@ -2634,55 +2402,26 @@ it("Bananas ignore components dataSentrySourceFile=* dataSentryComponent=match d
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["*", "Bananas", "Image"]] }]],
});
- expect(result?.code).toMatchInlineSnapshot(
- `
- "\\"use strict\\";
-
- function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
- var _react = _interopRequireWildcard(require(\\"react\\"));
- var _reactNative = require(\\"react-native\\");
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
- function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
- function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
- function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
- var Bananas = /*#__PURE__*/function (_Component) {
- _inherits(Bananas, _Component);
- var _super = _createSuper(Bananas);
- function Bananas() {
- _classCallCheck(this, Bananas);
- return _super.apply(this, arguments);
+ expect(result?.code).toMatchInlineSnapshot(`
+ "import React, { Component } from 'react';
+ import { Image } from 'react-native';
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\"
+ });
}
- _createClass(Bananas, [{
- key: \\"render\\",
- value: function render() {
- var pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\"
- });
- }
- }]);
- return Bananas;
- }(_react.Component);"
- `
- );
+ }"
+ `);
});
// This tests out matching on all 3 of our ignore list values
@@ -2695,55 +2434,26 @@ it("Bananas ignore components dataSentrySourceFile=match dataSentryComponent=mat
[plugin, { native: true, ignoreComponents: [["filename-test.js", "Bananas", "Image"]] }],
],
});
- expect(result?.code).toMatchInlineSnapshot(
- `
- "\\"use strict\\";
-
- function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
- var _react = _interopRequireWildcard(require(\\"react\\"));
- var _reactNative = require(\\"react-native\\");
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
- function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
- function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
- function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
- var Bananas = /*#__PURE__*/function (_Component) {
- _inherits(Bananas, _Component);
- var _super = _createSuper(Bananas);
- function Bananas() {
- _classCallCheck(this, Bananas);
- return _super.apply(this, arguments);
+ expect(result?.code).toMatchInlineSnapshot(`
+ "import React, { Component } from 'react';
+ import { Image } from 'react-native';
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\"
+ });
}
- _createClass(Bananas, [{
- key: \\"render\\",
- value: function render() {
- var pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\"
- });
- }
- }]);
- return Bananas;
- }(_react.Component);"
- `
- );
+ }"
+ `);
});
// This tests out matching on all 3 of our ignore list values via *
@@ -2754,125 +2464,78 @@ it("Bananas/Pizza/App ignore components dataSentrySourceFile=* dataSentryCompone
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["*", "*", "*"]] }]],
});
- expect(result?.code).toMatchInlineSnapshot(
- `
- "\\"use strict\\";
-
- function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
- Object.defineProperty(exports, \\"__esModule\\", {
- value: true
- });
- exports[\\"default\\"] = App;
- var _react = _interopRequireWildcard(require(\\"react\\"));
- var _reactNative = require(\\"react-native\\");
- var _container;
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
- function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
- function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
- function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
- _reactNative.UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
- var Bananas = /*#__PURE__*/function (_Component) {
- _inherits(Bananas, _Component);
- var _super = _createSuper(Bananas);
- function Bananas() {
- _classCallCheck(this, Bananas);
- return _super.apply(this, arguments);
+ expect(result?.code).toMatchInlineSnapshot(`
+ "import React, { Component } from 'react';
+ import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+ UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\"
+ });
}
- _createClass(Bananas, [{
- key: \\"render\\",
- value: function render() {
- var pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\"
- });
- }
- }]);
- return Bananas;
- }(_react.Component);
- var PizzaTranslator = /*#__PURE__*/function (_Component2) {
- _inherits(PizzaTranslator, _Component2);
- var _super2 = _createSuper(PizzaTranslator);
- function PizzaTranslator(props) {
- var _this;
- _classCallCheck(this, PizzaTranslator);
- _this = _super2.call(this, props);
- _this.state = {
+ }
+ class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
text: ''
};
- return _this;
}
- _createClass(PizzaTranslator, [{
- key: \\"render\\",
- value: function render() {
- var _this2 = this;
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
- style: {
- padding: 10
- }
- }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.TextInput, {
- style: {
- backgroundColor: '#000',
- color: '#eee',
- padding: 8
- },
- placeholder: \\"Type here to translate!\\" // not supported on iOS
- ,
- onChangeText: function onChangeText(text) {
- return _this2.setState({
- text: text
- });
- },
- value: this.state.text
- }), /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
- style: {
- padding: 10,
- fontSize: 42
- }
- }, this.state.text.split(' ').map(function (word) {
- return word && '🍕';
- }).join(' ')));
- }
- }]);
- return PizzaTranslator;
- }(_react.Component);
- function App() {
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ render() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: {
+ padding: 10
+ }
+ }, /*#__PURE__*/React.createElement(TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: text => this.setState({
+ text
+ }),
+ value: this.state.text
+ }), /*#__PURE__*/React.createElement(Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ }
+ }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
+ }
+ }
+ export default function App() {
+ return /*#__PURE__*/React.createElement(View, {
style: styles.container
- }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ }, /*#__PURE__*/React.createElement(Text, {
style: {
color: '#eee'
}
- }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/_react[\\"default\\"].createElement(Bananas, null), /*#__PURE__*/_react[\\"default\\"].createElement(PizzaTranslator, null));
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, null), /*#__PURE__*/React.createElement(PizzaTranslator, null));
}
- var styles = _reactNative.StyleSheet.create({
- container: (_container = {
+ const styles = StyleSheet.create({
+ container: {
flex: 1,
justifyContent: 'center',
alignItems: 'stretch',
- backgroundColor: '#222'
- }, _defineProperty(_container, \\"alignItems\\", 'center'), _defineProperty(_container, \\"justifyContent\\", 'center'), _container)
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
});"
- `
- );
+ `);
});
// This tests out matching on all 3 of our ignore list values
@@ -2883,146 +2546,99 @@ it("Bananas/Pizza/App ignore components dataSentrySourceFile=nomatch dataSentryC
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true, ignoreComponents: [["nomatch.js", "*", "*"]] }]],
});
- expect(result?.code).toMatchInlineSnapshot(
- `
- "\\"use strict\\";
-
- function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
- Object.defineProperty(exports, \\"__esModule\\", {
- value: true
- });
- exports[\\"default\\"] = App;
- var _react = _interopRequireWildcard(require(\\"react\\"));
- var _reactNative = require(\\"react-native\\");
- var _container;
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
- function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
- function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
- function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
- _reactNative.UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
- var Bananas = /*#__PURE__*/function (_Component) {
- _inherits(Bananas, _Component);
- var _super = _createSuper(Bananas);
- function Bananas() {
- _classCallCheck(this, Bananas);
- return _super.apply(this, arguments);
+ expect(result?.code).toMatchInlineSnapshot(`
+ "import React, { Component } from 'react';
+ import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+ UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
}
- _createClass(Bananas, [{
- key: \\"render\\",
- value: function render() {
- var pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
- }]);
- return Bananas;
- }(_react.Component);
- var PizzaTranslator = /*#__PURE__*/function (_Component2) {
- _inherits(PizzaTranslator, _Component2);
- var _super2 = _createSuper(PizzaTranslator);
- function PizzaTranslator(props) {
- var _this;
- _classCallCheck(this, PizzaTranslator);
- _this = _super2.call(this, props);
- _this.state = {
+ }
+ class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
text: ''
};
- return _this;
}
- _createClass(PizzaTranslator, [{
- key: \\"render\\",
- value: function render() {
- var _this2 = this;
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
- style: {
- padding: 10
- },
- dataSentryElement: \\"View\\",
- dataSentryComponent: \\"PizzaTranslator\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.TextInput, {
- style: {
- backgroundColor: '#000',
- color: '#eee',
- padding: 8
- },
- placeholder: \\"Type here to translate!\\" // not supported on iOS
- ,
- onChangeText: function onChangeText(text) {
- return _this2.setState({
- text: text
- });
- },
- value: this.state.text,
- dataSentryElement: \\"TextInput\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
- style: {
- padding: 10,
- fontSize: 42
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, this.state.text.split(' ').map(function (word) {
- return word && '🍕';
- }).join(' ')));
- }
- }]);
- return PizzaTranslator;
- }(_react.Component);
- function App() {
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ render() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: {
+ padding: 10
+ },
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: text => this.setState({
+ text
+ }),
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
+ }
+ }
+ export default function App() {
+ return /*#__PURE__*/React.createElement(View, {
style: styles.container,
dataSentryElement: \\"View\\",
dataSentryComponent: \\"App\\",
dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ }, /*#__PURE__*/React.createElement(Text, {
style: {
color: '#eee'
},
dataSentryElement: \\"Text\\",
dataSentrySourceFile: \\"filename-test.js\\"
- }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/_react[\\"default\\"].createElement(Bananas, {
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
dataSentryElement: \\"Bananas\\",
dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/_react[\\"default\\"].createElement(PizzaTranslator, {
+ }), /*#__PURE__*/React.createElement(PizzaTranslator, {
dataSentryElement: \\"PizzaTranslator\\",
dataSentrySourceFile: \\"filename-test.js\\"
}));
}
- var styles = _reactNative.StyleSheet.create({
- container: (_container = {
+ const styles = StyleSheet.create({
+ container: {
flex: 1,
justifyContent: 'center',
alignItems: 'stretch',
- backgroundColor: '#222'
- }, _defineProperty(_container, \\"alignItems\\", 'center'), _defineProperty(_container, \\"justifyContent\\", 'center'), _container)
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
});"
- `
- );
+ `);
});
it("Bananas/Pizza/App only Bananas dataSentrySourceFile=match dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
@@ -3045,140 +2661,93 @@ it("Bananas/Pizza/App only Bananas dataSentrySourceFile=match dataSentryComponen
],
],
});
- expect(result?.code).toMatchInlineSnapshot(
- `
- "\\"use strict\\";
-
- function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
- Object.defineProperty(exports, \\"__esModule\\", {
- value: true
- });
- exports[\\"default\\"] = App;
- var _react = _interopRequireWildcard(require(\\"react\\"));
- var _reactNative = require(\\"react-native\\");
- var _container;
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
- function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
- function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
- function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
- _reactNative.UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
- var Bananas = /*#__PURE__*/function (_Component) {
- _inherits(Bananas, _Component);
- var _super = _createSuper(Bananas);
- function Bananas() {
- _classCallCheck(this, Bananas);
- return _super.apply(this, arguments);
+ expect(result?.code).toMatchInlineSnapshot(`
+ "import React, { Component } from 'react';
+ import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+ UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
}
- _createClass(Bananas, [{
- key: \\"render\\",
- value: function render() {
- var pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
- }]);
- return Bananas;
- }(_react.Component);
- var PizzaTranslator = /*#__PURE__*/function (_Component2) {
- _inherits(PizzaTranslator, _Component2);
- var _super2 = _createSuper(PizzaTranslator);
- function PizzaTranslator(props) {
- var _this;
- _classCallCheck(this, PizzaTranslator);
- _this = _super2.call(this, props);
- _this.state = {
+ }
+ class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
text: ''
};
- return _this;
}
- _createClass(PizzaTranslator, [{
- key: \\"render\\",
- value: function render() {
- var _this2 = this;
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
- style: {
- padding: 10
- }
- }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.TextInput, {
- style: {
- backgroundColor: '#000',
- color: '#eee',
- padding: 8
- },
- placeholder: \\"Type here to translate!\\" // not supported on iOS
- ,
- onChangeText: function onChangeText(text) {
- return _this2.setState({
- text: text
- });
- },
- value: this.state.text,
- dataSentryElement: \\"TextInput\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
- style: {
- padding: 10,
- fontSize: 42
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, this.state.text.split(' ').map(function (word) {
- return word && '🍕';
- }).join(' ')));
- }
- }]);
- return PizzaTranslator;
- }(_react.Component);
- function App() {
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ render() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: {
+ padding: 10
+ }
+ }, /*#__PURE__*/React.createElement(TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: text => this.setState({
+ text
+ }),
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
+ }
+ }
+ export default function App() {
+ return /*#__PURE__*/React.createElement(View, {
style: styles.container
- }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ }, /*#__PURE__*/React.createElement(Text, {
style: {
color: '#eee'
},
dataSentryElement: \\"Text\\",
dataSentrySourceFile: \\"filename-test.js\\"
- }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/_react[\\"default\\"].createElement(Bananas, {
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
dataSentryElement: \\"Bananas\\",
dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/_react[\\"default\\"].createElement(PizzaTranslator, {
+ }), /*#__PURE__*/React.createElement(PizzaTranslator, {
dataSentryElement: \\"PizzaTranslator\\",
dataSentrySourceFile: \\"filename-test.js\\"
}));
}
- var styles = _reactNative.StyleSheet.create({
- container: (_container = {
+ const styles = StyleSheet.create({
+ container: {
flex: 1,
justifyContent: 'center',
alignItems: 'stretch',
- backgroundColor: '#222'
- }, _defineProperty(_container, \\"alignItems\\", 'center'), _defineProperty(_container, \\"justifyContent\\", 'center'), _container)
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
});"
- `
- );
+ `);
});
it("Bananas/Pizza/App only Pizza dataSentrySourceFile=match dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
@@ -3201,140 +2770,93 @@ it("Bananas/Pizza/App only Pizza dataSentrySourceFile=match dataSentryComponent=
],
],
});
- expect(result?.code).toMatchInlineSnapshot(
- `
- "\\"use strict\\";
-
- function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
- Object.defineProperty(exports, \\"__esModule\\", {
- value: true
- });
- exports[\\"default\\"] = App;
- var _react = _interopRequireWildcard(require(\\"react\\"));
- var _reactNative = require(\\"react-native\\");
- var _container;
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
- function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
- function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
- function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
- _reactNative.UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
- var Bananas = /*#__PURE__*/function (_Component) {
- _inherits(Bananas, _Component);
- var _super = _createSuper(Bananas);
- function Bananas() {
- _classCallCheck(this, Bananas);
- return _super.apply(this, arguments);
+ expect(result?.code).toMatchInlineSnapshot(`
+ "import React, { Component } from 'react';
+ import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+ UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\"
+ });
}
- _createClass(Bananas, [{
- key: \\"render\\",
- value: function render() {
- var pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\"
- });
- }
- }]);
- return Bananas;
- }(_react.Component);
- var PizzaTranslator = /*#__PURE__*/function (_Component2) {
- _inherits(PizzaTranslator, _Component2);
- var _super2 = _createSuper(PizzaTranslator);
- function PizzaTranslator(props) {
- var _this;
- _classCallCheck(this, PizzaTranslator);
- _this = _super2.call(this, props);
- _this.state = {
+ }
+ class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
text: ''
};
- return _this;
}
- _createClass(PizzaTranslator, [{
- key: \\"render\\",
- value: function render() {
- var _this2 = this;
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
- style: {
- padding: 10
- },
- dataSentryElement: \\"View\\",
- dataSentryComponent: \\"PizzaTranslator\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.TextInput, {
- style: {
- backgroundColor: '#000',
- color: '#eee',
- padding: 8
- },
- placeholder: \\"Type here to translate!\\" // not supported on iOS
- ,
- onChangeText: function onChangeText(text) {
- return _this2.setState({
- text: text
- });
- },
- value: this.state.text,
- dataSentryElement: \\"TextInput\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
- style: {
- padding: 10,
- fontSize: 42
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, this.state.text.split(' ').map(function (word) {
- return word && '🍕';
- }).join(' ')));
- }
- }]);
- return PizzaTranslator;
- }(_react.Component);
- function App() {
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ render() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: {
+ padding: 10
+ },
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: text => this.setState({
+ text
+ }),
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
+ }
+ }
+ export default function App() {
+ return /*#__PURE__*/React.createElement(View, {
style: styles.container
- }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ }, /*#__PURE__*/React.createElement(Text, {
style: {
color: '#eee'
},
dataSentryElement: \\"Text\\",
dataSentrySourceFile: \\"filename-test.js\\"
- }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/_react[\\"default\\"].createElement(Bananas, {
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
dataSentryElement: \\"Bananas\\",
dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/_react[\\"default\\"].createElement(PizzaTranslator, {
+ }), /*#__PURE__*/React.createElement(PizzaTranslator, {
dataSentryElement: \\"PizzaTranslator\\",
dataSentrySourceFile: \\"filename-test.js\\"
}));
}
- var styles = _reactNative.StyleSheet.create({
- container: (_container = {
+ const styles = StyleSheet.create({
+ container: {
flex: 1,
justifyContent: 'center',
alignItems: 'stretch',
- backgroundColor: '#222'
- }, _defineProperty(_container, \\"alignItems\\", 'center'), _defineProperty(_container, \\"justifyContent\\", 'center'), _container)
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
});"
- `
- );
+ `);
});
it("Bananas/Pizza/App only App dataSentrySourceFile=match dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
@@ -3357,140 +2879,93 @@ it("Bananas/Pizza/App only App dataSentrySourceFile=match dataSentryComponent=ma
],
],
});
- expect(result?.code).toMatchInlineSnapshot(
- `
- "\\"use strict\\";
-
- function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
- Object.defineProperty(exports, \\"__esModule\\", {
- value: true
- });
- exports[\\"default\\"] = App;
- var _react = _interopRequireWildcard(require(\\"react\\"));
- var _reactNative = require(\\"react-native\\");
- var _container;
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
- function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
- function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
- function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
- _reactNative.UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
- var Bananas = /*#__PURE__*/function (_Component) {
- _inherits(Bananas, _Component);
- var _super = _createSuper(Bananas);
- function Bananas() {
- _classCallCheck(this, Bananas);
- return _super.apply(this, arguments);
+ expect(result?.code).toMatchInlineSnapshot(`
+ "import React, { Component } from 'react';
+ import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+ UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\"
+ });
}
- _createClass(Bananas, [{
- key: \\"render\\",
- value: function render() {
- var pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\"
- });
- }
- }]);
- return Bananas;
- }(_react.Component);
- var PizzaTranslator = /*#__PURE__*/function (_Component2) {
- _inherits(PizzaTranslator, _Component2);
- var _super2 = _createSuper(PizzaTranslator);
- function PizzaTranslator(props) {
- var _this;
- _classCallCheck(this, PizzaTranslator);
- _this = _super2.call(this, props);
- _this.state = {
+ }
+ class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
text: ''
};
- return _this;
}
- _createClass(PizzaTranslator, [{
- key: \\"render\\",
- value: function render() {
- var _this2 = this;
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
- style: {
- padding: 10
- }
- }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.TextInput, {
- style: {
- backgroundColor: '#000',
- color: '#eee',
- padding: 8
- },
- placeholder: \\"Type here to translate!\\" // not supported on iOS
- ,
- onChangeText: function onChangeText(text) {
- return _this2.setState({
- text: text
- });
- },
- value: this.state.text,
- dataSentryElement: \\"TextInput\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
- style: {
- padding: 10,
- fontSize: 42
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, this.state.text.split(' ').map(function (word) {
- return word && '🍕';
- }).join(' ')));
- }
- }]);
- return PizzaTranslator;
- }(_react.Component);
- function App() {
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ render() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: {
+ padding: 10
+ }
+ }, /*#__PURE__*/React.createElement(TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: text => this.setState({
+ text
+ }),
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
+ }
+ }
+ export default function App() {
+ return /*#__PURE__*/React.createElement(View, {
style: styles.container,
dataSentryElement: \\"View\\",
dataSentryComponent: \\"App\\",
dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ }, /*#__PURE__*/React.createElement(Text, {
style: {
color: '#eee'
},
dataSentryElement: \\"Text\\",
dataSentrySourceFile: \\"filename-test.js\\"
- }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/_react[\\"default\\"].createElement(Bananas, {
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
dataSentryElement: \\"Bananas\\",
dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/_react[\\"default\\"].createElement(PizzaTranslator, {
+ }), /*#__PURE__*/React.createElement(PizzaTranslator, {
dataSentryElement: \\"PizzaTranslator\\",
dataSentrySourceFile: \\"filename-test.js\\"
}));
}
- var styles = _reactNative.StyleSheet.create({
- container: (_container = {
+ const styles = StyleSheet.create({
+ container: {
flex: 1,
justifyContent: 'center',
alignItems: 'stretch',
- backgroundColor: '#222'
- }, _defineProperty(_container, \\"alignItems\\", 'center'), _defineProperty(_container, \\"justifyContent\\", 'center'), _container)
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
});"
- `
- );
+ `);
});
it("Bananas/Pizza/App No Pizza Elements dataSentrySourceFile=match dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
@@ -3511,143 +2986,96 @@ it("Bananas/Pizza/App No Pizza Elements dataSentrySourceFile=match dataSentryCom
],
],
});
- expect(result?.code).toMatchInlineSnapshot(
- `
- "\\"use strict\\";
-
- function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
- Object.defineProperty(exports, \\"__esModule\\", {
- value: true
- });
- exports[\\"default\\"] = App;
- var _react = _interopRequireWildcard(require(\\"react\\"));
- var _reactNative = require(\\"react-native\\");
- var _container;
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
- function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
- function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
- function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
- _reactNative.UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
- var Bananas = /*#__PURE__*/function (_Component) {
- _inherits(Bananas, _Component);
- var _super = _createSuper(Bananas);
- function Bananas() {
- _classCallCheck(this, Bananas);
- return _super.apply(this, arguments);
+ expect(result?.code).toMatchInlineSnapshot(`
+ "import React, { Component } from 'react';
+ import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+ UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
}
- _createClass(Bananas, [{
- key: \\"render\\",
- value: function render() {
- var pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
- }]);
- return Bananas;
- }(_react.Component);
- var PizzaTranslator = /*#__PURE__*/function (_Component2) {
- _inherits(PizzaTranslator, _Component2);
- var _super2 = _createSuper(PizzaTranslator);
- function PizzaTranslator(props) {
- var _this;
- _classCallCheck(this, PizzaTranslator);
- _this = _super2.call(this, props);
- _this.state = {
+ }
+ class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
text: ''
};
- return _this;
}
- _createClass(PizzaTranslator, [{
- key: \\"render\\",
- value: function render() {
- var _this2 = this;
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
- style: {
- padding: 10
- },
- dataSentryElement: \\"View\\",
- dataSentryComponent: \\"PizzaTranslator\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.TextInput, {
- style: {
- backgroundColor: '#000',
- color: '#eee',
- padding: 8
- },
- placeholder: \\"Type here to translate!\\" // not supported on iOS
- ,
- onChangeText: function onChangeText(text) {
- return _this2.setState({
- text: text
- });
- },
- value: this.state.text,
- dataSentryElement: \\"TextInput\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
- style: {
- padding: 10,
- fontSize: 42
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, this.state.text.split(' ').map(function (word) {
- return word && '🍕';
- }).join(' ')));
- }
- }]);
- return PizzaTranslator;
- }(_react.Component);
- function App() {
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ render() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: {
+ padding: 10
+ },
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: text => this.setState({
+ text
+ }),
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
+ }
+ }
+ export default function App() {
+ return /*#__PURE__*/React.createElement(View, {
style: styles.container,
dataSentryElement: \\"View\\",
dataSentryComponent: \\"App\\",
dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ }, /*#__PURE__*/React.createElement(Text, {
style: {
color: '#eee'
},
dataSentryElement: \\"Text\\",
dataSentrySourceFile: \\"filename-test.js\\"
- }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/_react[\\"default\\"].createElement(Bananas, {
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
dataSentryElement: \\"Bananas\\",
dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/_react[\\"default\\"].createElement(PizzaTranslator, null));
+ }), /*#__PURE__*/React.createElement(PizzaTranslator, null));
}
- var styles = _reactNative.StyleSheet.create({
- container: (_container = {
+ const styles = StyleSheet.create({
+ container: {
flex: 1,
justifyContent: 'center',
alignItems: 'stretch',
- backgroundColor: '#222'
- }, _defineProperty(_container, \\"alignItems\\", 'center'), _defineProperty(_container, \\"justifyContent\\", 'center'), _container)
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
});"
- `
- );
+ `);
});
it("Bananas/Pizza/App No Bananas Elements dataSentrySourceFile=match dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
@@ -3669,143 +3097,96 @@ it("Bananas/Pizza/App No Bananas Elements dataSentrySourceFile=match dataSentryC
],
});
- expect(result?.code).toMatchInlineSnapshot(
- `
- "\\"use strict\\";
-
- function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
- Object.defineProperty(exports, \\"__esModule\\", {
- value: true
- });
- exports[\\"default\\"] = App;
- var _react = _interopRequireWildcard(require(\\"react\\"));
- var _reactNative = require(\\"react-native\\");
- var _container;
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
- function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
- function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
- function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
- _reactNative.UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
- var Bananas = /*#__PURE__*/function (_Component) {
- _inherits(Bananas, _Component);
- var _super = _createSuper(Bananas);
- function Bananas() {
- _classCallCheck(this, Bananas);
- return _super.apply(this, arguments);
+ expect(result?.code).toMatchInlineSnapshot(`
+ "import React, { Component } from 'react';
+ import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+ UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
}
- _createClass(Bananas, [{
- key: \\"render\\",
- value: function render() {
- var pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
- }]);
- return Bananas;
- }(_react.Component);
- var PizzaTranslator = /*#__PURE__*/function (_Component2) {
- _inherits(PizzaTranslator, _Component2);
- var _super2 = _createSuper(PizzaTranslator);
- function PizzaTranslator(props) {
- var _this;
- _classCallCheck(this, PizzaTranslator);
- _this = _super2.call(this, props);
- _this.state = {
+ }
+ class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
text: ''
};
- return _this;
}
- _createClass(PizzaTranslator, [{
- key: \\"render\\",
- value: function render() {
- var _this2 = this;
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
- style: {
- padding: 10
- },
- dataSentryElement: \\"View\\",
- dataSentryComponent: \\"PizzaTranslator\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.TextInput, {
- style: {
- backgroundColor: '#000',
- color: '#eee',
- padding: 8
- },
- placeholder: \\"Type here to translate!\\" // not supported on iOS
- ,
- onChangeText: function onChangeText(text) {
- return _this2.setState({
- text: text
- });
- },
- value: this.state.text,
- dataSentryElement: \\"TextInput\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
- style: {
- padding: 10,
- fontSize: 42
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, this.state.text.split(' ').map(function (word) {
- return word && '🍕';
- }).join(' ')));
- }
- }]);
- return PizzaTranslator;
- }(_react.Component);
- function App() {
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ render() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: {
+ padding: 10
+ },
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: text => this.setState({
+ text
+ }),
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
+ }
+ }
+ export default function App() {
+ return /*#__PURE__*/React.createElement(View, {
style: styles.container,
dataSentryElement: \\"View\\",
dataSentryComponent: \\"App\\",
dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ }, /*#__PURE__*/React.createElement(Text, {
style: {
color: '#eee'
},
dataSentryElement: \\"Text\\",
dataSentrySourceFile: \\"filename-test.js\\"
- }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/_react[\\"default\\"].createElement(Bananas, null), /*#__PURE__*/_react[\\"default\\"].createElement(PizzaTranslator, {
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, null), /*#__PURE__*/React.createElement(PizzaTranslator, {
dataSentryElement: \\"PizzaTranslator\\",
dataSentrySourceFile: \\"filename-test.js\\"
}));
}
- var styles = _reactNative.StyleSheet.create({
- container: (_container = {
+ const styles = StyleSheet.create({
+ container: {
flex: 1,
justifyContent: 'center',
alignItems: 'stretch',
- backgroundColor: '#222'
- }, _defineProperty(_container, \\"alignItems\\", 'center'), _defineProperty(_container, \\"justifyContent\\", 'center'), _container)
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
});"
- `
- );
+ `);
});
it("Bananas/Pizza/App No Bananas/Pizza Elements dataSentrySourceFile=match dataSentryComponent=match dataSentryElement=match snapshot matches", () => {
@@ -3828,140 +3209,93 @@ it("Bananas/Pizza/App No Bananas/Pizza Elements dataSentrySourceFile=match dataS
],
],
});
- expect(result?.code).toMatchInlineSnapshot(
- `
- "\\"use strict\\";
-
- function _typeof(obj) { \\"@babel/helpers - typeof\\"; return _typeof = \\"function\\" == typeof Symbol && \\"symbol\\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \\"function\\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \\"symbol\\" : typeof obj; }, _typeof(obj); }
- Object.defineProperty(exports, \\"__esModule\\", {
- value: true
- });
- exports[\\"default\\"] = App;
- var _react = _interopRequireWildcard(require(\\"react\\"));
- var _reactNative = require(\\"react-native\\");
- var _container;
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== \\"function\\") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \\"object\\" && typeof obj !== \\"function\\") { return { \\"default\\": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== \\"default\\" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\\"default\\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\\"Cannot call a class as a function\\"); } }
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\\"value\\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \\"prototype\\", { writable: false }); return Constructor; }
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, \\"string\\"); return _typeof(key) === \\"symbol\\" ? key : String(key); }
- function _toPrimitive(input, hint) { if (_typeof(input) !== \\"object\\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \\"default\\"); if (_typeof(res) !== \\"object\\") return res; throw new TypeError(\\"@@toPrimitive must return a primitive value.\\"); } return (hint === \\"string\\" ? String : Number)(input); }
- function _inherits(subClass, superClass) { if (typeof superClass !== \\"function\\" && superClass !== null) { throw new TypeError(\\"Super expression must either be null or a function\\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, \\"prototype\\", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \\"object\\" || typeof call === \\"function\\")) { return call; } else if (call !== void 0) { throw new TypeError(\\"Derived constructors may only return object or undefined\\"); } return _assertThisInitialized(self); }
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\\"this hasn't been initialised - super() hasn't been called\\"); } return self; }
- function _isNativeReflectConstruct() { if (typeof Reflect === \\"undefined\\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \\"function\\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
- _reactNative.UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
- var Bananas = /*#__PURE__*/function (_Component) {
- _inherits(Bananas, _Component);
- var _super = _createSuper(Bananas);
- function Bananas() {
- _classCallCheck(this, Bananas);
- return _super.apply(this, arguments);
+ expect(result?.code).toMatchInlineSnapshot(`
+ "import React, { Component } from 'react';
+ import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+ UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+ class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
}
- _createClass(Bananas, [{
- key: \\"render\\",
- value: function render() {
- var pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
- }]);
- return Bananas;
- }(_react.Component);
- var PizzaTranslator = /*#__PURE__*/function (_Component2) {
- _inherits(PizzaTranslator, _Component2);
- var _super2 = _createSuper(PizzaTranslator);
- function PizzaTranslator(props) {
- var _this;
- _classCallCheck(this, PizzaTranslator);
- _this = _super2.call(this, props);
- _this.state = {
+ }
+ class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
text: ''
};
- return _this;
}
- _createClass(PizzaTranslator, [{
- key: \\"render\\",
- value: function render() {
- var _this2 = this;
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
- style: {
- padding: 10
- },
- dataSentryElement: \\"View\\",
- dataSentryComponent: \\"PizzaTranslator\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.TextInput, {
- style: {
- backgroundColor: '#000',
- color: '#eee',
- padding: 8
- },
- placeholder: \\"Type here to translate!\\" // not supported on iOS
- ,
- onChangeText: function onChangeText(text) {
- return _this2.setState({
- text: text
- });
- },
- value: this.state.text,
- dataSentryElement: \\"TextInput\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
- style: {
- padding: 10,
- fontSize: 42
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, this.state.text.split(' ').map(function (word) {
- return word && '🍕';
- }).join(' ')));
- }
- }]);
- return PizzaTranslator;
- }(_react.Component);
- function App() {
- return /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.View, {
+ render() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: {
+ padding: 10
+ },
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: text => this.setState({
+ text
+ }),
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
+ }
+ }
+ export default function App() {
+ return /*#__PURE__*/React.createElement(View, {
style: styles.container,
dataSentryElement: \\"View\\",
dataSentryComponent: \\"App\\",
dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/_react[\\"default\\"].createElement(_reactNative.Text, {
+ }, /*#__PURE__*/React.createElement(Text, {
style: {
color: '#eee'
},
dataSentryElement: \\"Text\\",
dataSentrySourceFile: \\"filename-test.js\\"
- }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/_react[\\"default\\"].createElement(Bananas, null), /*#__PURE__*/_react[\\"default\\"].createElement(PizzaTranslator, null));
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, null), /*#__PURE__*/React.createElement(PizzaTranslator, null));
}
- var styles = _reactNative.StyleSheet.create({
- container: (_container = {
+ const styles = StyleSheet.create({
+ container: {
flex: 1,
justifyContent: 'center',
alignItems: 'stretch',
- backgroundColor: '#222'
- }, _defineProperty(_container, \\"alignItems\\", 'center'), _defineProperty(_container, \\"justifyContent\\", 'center'), _container)
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
});"
- `
- );
+ `);
});
it("Bananas incompatible plugin @react-navigation source snapshot matches", () => {
@@ -3970,8 +3304,7 @@ it("Bananas incompatible plugin @react-navigation source snapshot matches", () =
presets: ["@babel/preset-react"],
plugins: [[plugin, { native: true }]],
});
- expect(result?.code).toMatchInlineSnapshot(
- `
+ expect(result?.code).toMatchInlineSnapshot(`
"import React, { Component } from 'react';
import { Image } from 'react-native';
class Bananas extends Component {
@@ -3990,6 +3323,5 @@ it("Bananas incompatible plugin @react-navigation source snapshot matches", () =
});
}
}"
- `
- );
+ `);
});
From 7fa8970d54834bea60f92217597255fe55f46208 Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 10:58:29 -0500
Subject: [PATCH 33/51] rename plugin and do not use default export
---
packages/component-annotate-plugin/src/index.ts | 2 +-
packages/component-annotate-plugin/test/test-plugin.test.ts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index 5422e6e7..7ccdcfab 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -55,7 +55,7 @@ type IgnoredComponent = [file: string, component: string, element: string];
type AnnotationPlugin = PluginObj;
-export default function reactAnnotate({ types: t }: typeof Babel): AnnotationPlugin {
+export function componentNameAnnotatePlugin({ types: t }: typeof Babel): AnnotationPlugin {
return {
visitor: {
FunctionDeclaration(path, state) {
diff --git a/packages/component-annotate-plugin/test/test-plugin.test.ts b/packages/component-annotate-plugin/test/test-plugin.test.ts
index 80110ed9..14b04347 100644
--- a/packages/component-annotate-plugin/test/test-plugin.test.ts
+++ b/packages/component-annotate-plugin/test/test-plugin.test.ts
@@ -24,7 +24,7 @@
*/
import { transform } from "@babel/core";
-import plugin from "../src/index";
+import { componentNameAnnotatePlugin as plugin } from "../src/index";
const BananasPizzaAppStandardInput = `import React, { Component } from 'react';
import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
From e6901fcf6e259b9953605aa2114a53cef2776000 Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 11:16:11 -0500
Subject: [PATCH 34/51] use full return statements
---
.../component-annotate-plugin/src/index.ts | 78 ++++++++++++++-----
1 file changed, 57 insertions(+), 21 deletions(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index 7ccdcfab..9c13d536 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -59,8 +59,12 @@ export function componentNameAnnotatePlugin({ types: t }: typeof Babel): Annotat
return {
visitor: {
FunctionDeclaration(path, state) {
- if (!path.node.id || !path.node.id.name) return;
- if (isKnownIncompatiblePluginFromState(state)) return;
+ if (!path.node.id || !path.node.id.name) {
+ return;
+ }
+ if (isKnownIncompatiblePluginFromState(state)) {
+ return;
+ }
functionBodyPushAttributes(
state.opts["annotate-fragments"] === true,
@@ -74,11 +78,15 @@ export function componentNameAnnotatePlugin({ types: t }: typeof Babel): Annotat
},
ArrowFunctionExpression(path, state) {
const parent = path.parent; // We're expecting a `VariableDeclarator` like `const MyComponent =`
- if (!parent) return;
- if (!("id" in parent)) return;
- if (!parent.id) return;
- if (!("name" in parent.id)) return;
- if (!parent.id.name) return;
+ if (
+ !parent ||
+ !("id" in parent) ||
+ !parent.id ||
+ !("name" in parent.id) ||
+ !parent.id.name
+ ) {
+ return;
+ }
if (isKnownIncompatiblePluginFromState(state)) return;
@@ -99,8 +107,9 @@ export function componentNameAnnotatePlugin({ types: t }: typeof Babel): Annotat
return prop.isClassMethod() && prop.get("key").isIdentifier({ name: "render" });
});
- if (!render || !render.traverse) return;
- if (isKnownIncompatiblePluginFromState(state)) return;
+ if (!render || !render.traverse || isKnownIncompatiblePluginFromState(state)) {
+ return;
+ }
const ignoredComponents = state.opts.ignoreComponents ?? [];
@@ -108,7 +117,10 @@ export function componentNameAnnotatePlugin({ types: t }: typeof Babel): Annotat
ReturnStatement(returnStatement) {
const arg = returnStatement.get("argument");
- if (!arg.isJSXElement() && !arg.isJSXFragment()) return;
+ if (!arg.isJSXElement() && !arg.isJSXFragment()) {
+ return;
+ }
+
processJSX(
state.opts["annotate-fragments"] === true,
t,
@@ -147,7 +159,9 @@ function functionBodyPushAttributes(
return c.type === "JSXElement" || c.type === "JSXFragment";
});
- if (!maybeJsxNode) return;
+ if (!maybeJsxNode) {
+ return;
+ }
jsxNode = maybeJsxNode;
} else {
@@ -174,7 +188,9 @@ function functionBodyPushAttributes(
jsxNode = arg;
}
- if (!jsxNode) return;
+ if (!jsxNode) {
+ return;
+ }
processJSX(
annotateFragments,
@@ -226,13 +242,18 @@ function processJSX(
let shouldSetComponentName = annotateFragments;
children.forEach((child) => {
- if (!child.node) return; // Happens for some node types like plain text
+ // Happens for some node types like plain text
+ if (!child.node) {
+ return;
+ }
// Children don't receive the data-component attribute so we pass null for componentName unless it's the first child of a Fragment with a node and `annotateFragments` is true
const openingElement = child.get("openingElement");
// TODO: Improve this. We never expect to have multiple opening elements
// but if it's possible, this should work
- if (Array.isArray(openingElement)) return;
+ if (Array.isArray(openingElement)) {
+ return;
+ }
if (shouldSetComponentName && openingElement && openingElement.node) {
shouldSetComponentName = false;
@@ -269,8 +290,13 @@ function applyAttributes(
) {
const [componentAttributeName, elementAttributeName, sourceFileAttributeName] = attributeNames;
- if (isReactFragment(t, openingElement)) return;
- if (!openingElement.node) return; // e.g., Raw JSX text like the `A` in `a
`
+ if (isReactFragment(t, openingElement)) {
+ return;
+ }
+ // e.g., Raw JSX text like the `A` in `a
`
+ if (!openingElement.node) {
+ return;
+ }
if (!openingElement.node.attributes) openingElement.node.attributes = [];
const elementName = getPathName(t, openingElement);
@@ -389,7 +415,9 @@ function isReactFragment(t: typeof Babel.types, openingElement: Babel.NodePath):
const elementName = getPathName(t, openingElement);
- if (elementName === "Fragment" || elementName === "React.Fragment") return true;
+ if (elementName === "Fragment" || elementName === "React.Fragment") {
+ return true;
+ }
// TODO: All these objects are typed as unknown, maybe an oversight in Babel types?
if (
@@ -400,7 +428,9 @@ function isReactFragment(t: typeof Babel.types, openingElement: Babel.NodePath):
"type" in openingElement.node.name &&
openingElement.node.name.type === "JSXMemberExpression"
) {
- if (!("name" in openingElement.node)) return false;
+ if (!("name" in openingElement.node)) {
+ return false;
+ }
const nodeName = openingElement.node.name;
if (typeof nodeName !== "object" || !nodeName) {
@@ -439,7 +469,9 @@ function hasAttributeWithName(
openingElement: Babel.NodePath,
name: string | undefined | null
): boolean {
- if (!name) return false;
+ if (!name) {
+ return false;
+ }
return openingElement.node.attributes.some((node) => {
if (node.type === "JSXAttribute") {
@@ -452,11 +484,15 @@ function hasAttributeWithName(
function getPathName(t: typeof Babel.types, path: Babel.NodePath): string {
if (!path.node) return UNKNOWN_ELEMENT_NAME;
- if (!("name" in path.node)) return UNKNOWN_ELEMENT_NAME;
+ if (!("name" in path.node)) {
+ return UNKNOWN_ELEMENT_NAME;
+ }
const name = path.node.name;
- if (typeof name === "string") return name;
+ if (typeof name === "string") {
+ return name;
+ }
if (t.isIdentifier(name) || t.isJSXIdentifier(name)) {
return name.name;
From 4c03eea7cbd2513357be34c0aadc673578b426c7 Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 11:20:28 -0500
Subject: [PATCH 35/51] template strings
---
packages/component-annotate-plugin/src/index.ts | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index 9c13d536..843414be 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -386,12 +386,14 @@ function fullSourceFileNameFromState(state: AnnotationPluginPass): string | null
function isKnownIncompatiblePluginFromState(state: AnnotationPluginPass) {
const fullSourceFileName = fullSourceFileNameFromState(state);
- if (!fullSourceFileName) return false;
+ if (!fullSourceFileName) {
+ return false;
+ }
return KNOWN_INCOMPATIBLE_PLUGINS.some((pluginName) => {
if (
- fullSourceFileName.includes("/node_modules/" + pluginName + "/") ||
- fullSourceFileName.includes("\\node_modules\\" + pluginName + "\\")
+ fullSourceFileName.includes(`/node_modules/${pluginName}/`) ||
+ fullSourceFileName.includes(`\\node_modules\\${pluginName}\\`)
) {
return true;
}
From ce85d88355424b2fa4706b5b117828790a9dbd45 Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 11:46:00 -0500
Subject: [PATCH 36/51] add snapshots
---
packages/component-annotate-plugin/.gitignore | 1 -
.../__snapshots__/test-plugin.test.ts.snap | 515 ++++++++++++++++++
2 files changed, 515 insertions(+), 1 deletion(-)
create mode 100644 packages/component-annotate-plugin/test/__snapshots__/test-plugin.test.ts.snap
diff --git a/packages/component-annotate-plugin/.gitignore b/packages/component-annotate-plugin/.gitignore
index 08c41e9a..57b8bee7 100644
--- a/packages/component-annotate-plugin/.gitignore
+++ b/packages/component-annotate-plugin/.gitignore
@@ -1,4 +1,3 @@
dist
README.md
.DS_Store
-test/__snapshots__
\ No newline at end of file
diff --git a/packages/component-annotate-plugin/test/__snapshots__/test-plugin.test.ts.snap b/packages/component-annotate-plugin/test/__snapshots__/test-plugin.test.ts.snap
new file mode 100644
index 00000000..a5c615e1
--- /dev/null
+++ b/packages/component-annotate-plugin/test/__snapshots__/test-plugin.test.ts.snap
@@ -0,0 +1,515 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`arrow snapshot matches 1`] = `
+"import React, { Component } from 'react';
+const componentName = () => {
+ return /*#__PURE__*/React.createElement(\\"div\\", {
+ \\"data-sentry-component\\": \\"componentName\\"
+ }, /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hello world\\"));
+};
+export default componentName;"
+`;
+
+exports[`arrow-anonymous-fragment snapshot matches 1`] = `
+"import React, { Component, Fragment } from 'react';
+const componentName = () => {
+ return (() => /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hello world\\")))();
+};
+export default componentName;"
+`;
+
+exports[`arrow-anonymous-react-fragment snapshot matches 1`] = `
+"import React, { Component } from 'react';
+const componentName = () => {
+ return (() => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hello world\\")))();
+};
+export default componentName;"
+`;
+
+exports[`arrow-anonymous-shorthand-fragment snapshot matches 1`] = `
+"import React, { Component } from 'react';
+const componentName = () => {
+ return (() => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hello world\\")))();
+};
+export default componentName;"
+`;
+
+exports[`arrow-fragment snapshot matches 1`] = `
+"import React, { Component, Fragment } from 'react';
+const componentName = () => {
+ return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hello world\\"));
+};
+export default componentName;"
+`;
+
+exports[`arrow-noreturn snapshot matches 1`] = `
+"import React, { Component } from 'react';
+const componentName = () => /*#__PURE__*/React.createElement(\\"div\\", {
+ \\"data-sentry-component\\": \\"componentName\\"
+}, /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hello world\\"));
+export default componentName;"
+`;
+
+exports[`arrow-noreturn-annotate-fragment snapshot matches 1`] = `
+"import React, { Component, Fragment } from 'react';
+const componentName = () => /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(\\"h1\\", {
+ \\"data-sentry-component\\": \\"componentName\\",
+ \\"data-sentry-source-file\\": \\"filename-test.js\\"
+}, \\"Hello world\\"));
+export default componentName;"
+`;
+
+exports[`arrow-noreturn-annotate-fragment-no-whitespace snapshot matches 1`] = `
+"import React, { Component, Fragment } from 'react';
+const componentName = () => /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(\\"h1\\", {
+ \\"data-sentry-component\\": \\"componentName\\",
+ \\"data-sentry-source-file\\": \\"filename-test.js\\"
+}, \\"Hello world\\"), /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hola Sol\\"));
+export default componentName;"
+`;
+
+exports[`arrow-noreturn-annotate-fragment-once snapshot matches 1`] = `
+"import React, { Component, Fragment } from 'react';
+const componentName = () => /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(\\"h1\\", {
+ \\"data-sentry-component\\": \\"componentName\\",
+ \\"data-sentry-source-file\\": \\"filename-test.js\\"
+}, \\"Hello world\\"), /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hola Sol\\"));
+export default componentName;"
+`;
+
+exports[`arrow-noreturn-annotate-react-fragment snapshot matches 1`] = `
+"import React, { Component } from 'react';
+const componentName = () => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(\\"h1\\", {
+ \\"data-sentry-component\\": \\"componentName\\",
+ \\"data-sentry-source-file\\": \\"filename-test.js\\"
+}, \\"Hello world\\"));
+export default componentName;"
+`;
+
+exports[`arrow-noreturn-annotate-shorthand-fragment snapshot matches 1`] = `
+"import React, { Component } from 'react';
+const componentName = () => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(\\"h1\\", {
+ \\"data-sentry-component\\": \\"componentName\\",
+ \\"data-sentry-source-file\\": \\"filename-test.js\\"
+}, \\"Hello world\\"));
+export default componentName;"
+`;
+
+exports[`arrow-noreturn-annotate-trivial-fragment snapshot matches 1`] = `
+"import React, { Component, Fragment } from 'react';
+const componentName = () => /*#__PURE__*/React.createElement(Fragment, null, \\"Hello world\\");
+export default componentName;"
+`;
+
+exports[`arrow-noreturn-fragment snapshot matches 1`] = `
+"import React, { Component, Fragment } from 'react';
+const componentName = () => /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hello world\\"));
+export default componentName;"
+`;
+
+exports[`arrow-noreturn-react-fragment snapshot matches 1`] = `
+"import React, { Component } from 'react';
+const componentName = () => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hello world\\"));
+export default componentName;"
+`;
+
+exports[`arrow-noreturn-shorthand-fragment snapshot matches 1`] = `
+"import React, { Component } from 'react';
+const componentName = () => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hello world\\"));
+export default componentName;"
+`;
+
+exports[`arrow-react-fragment snapshot matches 1`] = `
+"import React, { Component } from 'react';
+const componentName = () => {
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hello world\\"));
+};
+export default componentName;"
+`;
+
+exports[`arrow-shorthand-fragment snapshot matches 1`] = `
+"import React from 'react';
+const componentName = () => {
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hello world\\"));
+};
+export default componentName;"
+`;
+
+exports[`component snapshot matches 1`] = `
+"import React, { Component } from 'react';
+class componentName extends Component {
+ render() {
+ return /*#__PURE__*/React.createElement(\\"div\\", {
+ \\"data-sentry-component\\": \\"componentName\\"
+ }, /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hello world\\"));
+ }
+}
+export default componentName;"
+`;
+
+exports[`component-annotate-fragment snapshot matches 1`] = `
+"import React, { Component } from 'react';
+class componentName extends Component {
+ render() {
+ return /*#__PURE__*/React.createElement(React.Fragment, null, \\"A\\");
+ }
+}
+export default componentName;"
+`;
+
+exports[`component-annotate-react-fragment snapshot matches 1`] = `
+"import React, { Component } from 'react';
+class componentName extends Component {
+ render() {
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(\\"h1\\", {
+ \\"data-sentry-component\\": \\"componentName\\",
+ \\"data-sentry-source-file\\": \\"filename-test.js\\"
+ }, \\"Hello world\\"));
+ }
+}
+export default componentName;"
+`;
+
+exports[`component-annotate-shorthand-fragment snapshot matches 1`] = `
+"import React, { Component } from 'react';
+class componentName extends Component {
+ render() {
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(\\"h1\\", {
+ \\"data-sentry-component\\": \\"componentName\\",
+ \\"data-sentry-source-file\\": \\"filename-test.js\\"
+ }, \\"Hello world\\"));
+ }
+}
+export default componentName;"
+`;
+
+exports[`component-fragment snapshot matches 1`] = `
+"import React, { Component, Fragment } from 'react';
+class componentName extends Component {
+ render() {
+ return /*#__PURE__*/React.createElement(Fragment, null, \\"A\\");
+ }
+}
+export default componentName;"
+`;
+
+exports[`component-fragment-native snapshot matches 1`] = `
+"import React, { Component, Fragment } from 'react';
+class componentName extends Component {
+ render() {
+ return /*#__PURE__*/React.createElement(Fragment, null, \\"A\\");
+ }
+}
+export default componentName;"
+`;
+
+exports[`component-react-fragment snapshot matches 1`] = `
+"import React, { Component } from 'react';
+class componentName extends Component {
+ render() {
+ return /*#__PURE__*/React.createElement(React.Fragment, null, \\"A\\");
+ }
+}
+export default componentName;"
+`;
+
+exports[`component-shorthand-fragment snapshot matches 1`] = `
+"import React, { Component } from 'react';
+class componentName extends Component {
+ render() {
+ return /*#__PURE__*/React.createElement(React.Fragment, null, \\"A\\");
+ }
+}
+export default componentName;"
+`;
+
+exports[`nonJSX snapshot matches 1`] = `
+"import React, { Component } from 'react';
+class TestClass extends Component {
+ test() {
+ return true;
+ }
+}
+export default TestClass;"
+`;
+
+exports[`option-attribute snapshot matches 1`] = `
+"import React, { Component } from 'react';
+const componentName = () => {
+ return /*#__PURE__*/React.createElement(\\"div\\", {
+ \\"data-sentry-component\\": \\"componentName\\"
+ }, /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hello world\\"));
+};
+export default componentName;"
+`;
+
+exports[`option-format snapshot matches 1`] = `
+"import React, { Component } from 'react';
+const componentName = () => {
+ return /*#__PURE__*/React.createElement(\\"div\\", {
+ \\"data-sentry-component\\": \\"componentName\\"
+ }, /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hello world\\"));
+};
+export default componentName;"
+`;
+
+exports[`pure snapshot matches 1`] = `
+"import React from 'react';
+class PureComponentName extends React.PureComponent {
+ render() {
+ return /*#__PURE__*/React.createElement(\\"div\\", {
+ \\"data-sentry-component\\": \\"PureComponentName\\"
+ }, /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hello world\\"));
+ }
+}
+export default PureComponentName;"
+`;
+
+exports[`pure-native snapshot matches 1`] = `
+"import React from 'react';
+class PureComponentName extends React.PureComponent {
+ render() {
+ return /*#__PURE__*/React.createElement(\\"div\\", {
+ dataSentryComponent: \\"PureComponentName\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hello world\\"));
+ }
+}
+export default PureComponentName;"
+`;
+
+exports[`pureComponent-fragment snapshot matches 1`] = `
+"import React, { Fragment } from 'react';
+class PureComponentName extends React.PureComponent {
+ render() {
+ return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hello world\\"));
+ }
+}
+export default PureComponentName;"
+`;
+
+exports[`pureComponent-react-fragment snapshot matches 1`] = `
+"import React from 'react';
+class PureComponentName extends React.PureComponent {
+ render() {
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hello world\\"));
+ }
+}
+export default PureComponentName;"
+`;
+
+exports[`pureComponent-shorthand-fragment snapshot matches 1`] = `
+"import React from 'react';
+class PureComponentName extends React.PureComponent {
+ render() {
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(\\"h1\\", null, \\"Hello world\\"));
+ }
+}
+export default PureComponentName;"
+`;
+
+exports[`rawfunction snapshot matches 1`] = `
+"import React, { Component } from 'react';
+function SubComponent() {
+ return /*#__PURE__*/React.createElement(\\"div\\", {
+ \\"data-sentry-component\\": \\"SubComponent\\"
+ }, \\"Sub\\");
+}
+const componentName = () => {
+ return /*#__PURE__*/React.createElement(\\"div\\", {
+ \\"data-sentry-component\\": \\"componentName\\"
+ }, /*#__PURE__*/React.createElement(SubComponent, {
+ \\"data-sentry-element\\": \\"SubComponent\\"
+ }));
+};
+export default componentName;"
+`;
+
+exports[`rawfunction-annotate-fragment snapshot matches 1`] = `
+"import React, { Component, Fragment } from 'react';
+function SubComponent() {
+ return /*#__PURE__*/React.createElement(Fragment, null, \\"Sub\\");
+}
+const componentName = () => {
+ return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(SubComponent, {
+ \\"data-sentry-element\\": \\"SubComponent\\",
+ \\"data-sentry-component\\": \\"componentName\\"
+ }));
+};
+export default componentName;"
+`;
+
+exports[`rawfunction-annotate-react-fragment snapshot matches 1`] = `
+"import React, { Component } from 'react';
+function SubComponent() {
+ return /*#__PURE__*/React.createElement(React.Fragment, null, \\"Sub\\");
+}
+const componentName = () => {
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SubComponent, {
+ \\"data-sentry-element\\": \\"SubComponent\\",
+ \\"data-sentry-component\\": \\"componentName\\"
+ }));
+};
+export default componentName;"
+`;
+
+exports[`rawfunction-annotate-shorthand-fragment snapshot matches 1`] = `
+"import React, { Component } from 'react';
+function SubComponent() {
+ return /*#__PURE__*/React.createElement(React.Fragment, null, \\"Sub\\");
+}
+const componentName = () => {
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SubComponent, {
+ \\"data-sentry-element\\": \\"SubComponent\\",
+ \\"data-sentry-component\\": \\"componentName\\"
+ }));
+};
+export default componentName;"
+`;
+
+exports[`rawfunction-fragment snapshot matches 1`] = `
+"import React, { Component, Fragment } from 'react';
+function SubComponent() {
+ return /*#__PURE__*/React.createElement(Fragment, null, \\"Sub\\");
+}
+const componentName = () => {
+ return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(SubComponent, {
+ \\"data-sentry-element\\": \\"SubComponent\\"
+ }));
+};
+export default componentName;"
+`;
+
+exports[`rawfunction-react-fragment snapshot matches 1`] = `
+"import React, { Component } from 'react';
+function SubComponent() {
+ return /*#__PURE__*/React.createElement(React.Fragment, null, \\"Sub\\");
+}
+const componentName = () => {
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SubComponent, {
+ \\"data-sentry-element\\": \\"SubComponent\\"
+ }));
+};
+export default componentName;"
+`;
+
+exports[`rawfunction-shorthand-fragment snapshot matches 1`] = `
+"import React, { Component } from 'react';
+function SubComponent() {
+ return /*#__PURE__*/React.createElement(React.Fragment, null, \\"Sub\\");
+}
+const componentName = () => {
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SubComponent, {
+ \\"data-sentry-element\\": \\"SubComponent\\"
+ }));
+};
+export default componentName;"
+`;
+
+exports[`tags snapshot matches 1`] = `
+"import React, { Component } from 'react';
+import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
+UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
+class Bananas extends Component {
+ render() {
+ let pic = {
+ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
+ };
+ return /*#__PURE__*/React.createElement(Image, {
+ source: pic,
+ style: {
+ width: 193,
+ height: 110,
+ marginTop: 10
+ },
+ fsClass: \\"test-class\\",
+ dataSentryElement: \\"Image\\",
+ dataSentryComponent: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ });
+ }
+}
+class PizzaTranslator extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ text: ''
+ };
+ }
+ render() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: {
+ padding: 10
+ },
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(TextInput, {
+ style: {
+ backgroundColor: '#000',
+ color: '#eee',
+ padding: 8
+ },
+ placeholder: \\"Type here to translate!\\" // not supported on iOS
+ ,
+ onChangeText: text => this.setState({
+ text
+ }),
+ value: this.state.text,
+ dataSentryElement: \\"TextInput\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(Text, {
+ style: {
+ padding: 10,
+ fontSize: 42
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
+ }
+}
+export default function App() {
+ return /*#__PURE__*/React.createElement(View, {
+ style: styles.container,
+ dataSentryElement: \\"View\\",
+ dataSentryComponent: \\"App\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(Text, {
+ style: {
+ color: '#eee'
+ },
+ dataSentryElement: \\"Text\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
+ dataSentryElement: \\"Bananas\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }), /*#__PURE__*/React.createElement(PizzaTranslator, {
+ dataSentryElement: \\"PizzaTranslator\\",
+ dataSentrySourceFile: \\"filename-test.js\\"
+ }));
+}
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ backgroundColor: '#222',
+ alignItems: 'center',
+ justifyContent: 'center'
+ }
+});"
+`;
+
+exports[`unknown-element snapshot matches 1`] = `
+"import React, { Component } from 'react';
+class componentName extends Component {
+ render() {
+ return /*#__PURE__*/React.createElement(\\"bogus\\", {
+ \\"data-sentry-element\\": \\"bogus\\",
+ \\"data-sentry-component\\": \\"componentName\\",
+ \\"data-sentry-source-file\\": \\"filename-test.js\\"
+ }, /*#__PURE__*/React.createElement(\\"h1\\", null, \\"A\\"));
+ }
+}
+export default componentName;"
+`;
From 4e4017ae05559b23c375344c1800d8822e4a2f15 Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 12:12:24 -0500
Subject: [PATCH 37/51] remove unused variables
---
.../test/test-plugin.test.ts | 1089 -----------------
1 file changed, 1089 deletions(-)
diff --git a/packages/component-annotate-plugin/test/test-plugin.test.ts b/packages/component-annotate-plugin/test/test-plugin.test.ts
index 14b04347..5a9ff11c 100644
--- a/packages/component-annotate-plugin/test/test-plugin.test.ts
+++ b/packages/component-annotate-plugin/test/test-plugin.test.ts
@@ -80,1046 +80,6 @@ const styles = StyleSheet.create({
}
});`;
-const BananasPizzaAppStandardOutputNoAttributes = `
-"import React, { Component } from 'react';
-import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
-UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
-
-class Bananas extends Component {
- render() {
- let pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/React.createElement(Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\"
- });
- }
-
-}
-
-class PizzaTranslator extends Component {
- constructor(props) {
- super(props);
- this.state = {
- text: ''
- };
- }
-
- render() {
- return /*#__PURE__*/React.createElement(View, {
- style: {
- padding: 10
- }
- }, /*#__PURE__*/React.createElement(TextInput, {
- style: {
- backgroundColor: '#000',
- color: '#eee',
- padding: 8
- },
- placeholder: \\"Type here to translate!\\" // not supported on iOS
- ,
- onChangeText: text => this.setState({
- text
- }),
- value: this.state.text
- }), /*#__PURE__*/React.createElement(Text, {
- style: {
- padding: 10,
- fontSize: 42
- }
- }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
- }
-
-}
-
-export default function App() {
- return /*#__PURE__*/React.createElement(View, {
- style: styles.container
- }, /*#__PURE__*/React.createElement(Text, {
- style: {
- color: '#eee'
- }
- }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, null), /*#__PURE__*/React.createElement(PizzaTranslator, null));
-}
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'stretch',
- backgroundColor: '#222',
- alignItems: 'center',
- justifyContent: 'center'
- }
-});"
-`;
-
-const BananasPizzaAppStandardOutputBananasPizzaAppAttributesNoBananasElements = `
-"import React, { Component } from 'react';
-import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
-UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
-
-class Bananas extends Component {
- render() {
- let pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/React.createElement(Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
-
-}
-
-class PizzaTranslator extends Component {
- constructor(props) {
- super(props);
- this.state = {
- text: ''
- };
- }
-
- render() {
- return /*#__PURE__*/React.createElement(View, {
- style: {
- padding: 10
- },
- dataSentryElement: \\"View\\",
- dataSentryComponent: \\"PizzaTranslator\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/React.createElement(TextInput, {
- style: {
- backgroundColor: '#000',
- color: '#eee',
- padding: 8
- },
- placeholder: \\"Type here to translate!\\" // not supported on iOS
- ,
- onChangeText: text => this.setState({
- text
- }),
- value: this.state.text,
- dataSentryElement: \\"TextInput\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/React.createElement(Text, {
- style: {
- padding: 10,
- fontSize: 42
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
- }
-
-}
-
-export default function App() {
- return /*#__PURE__*/React.createElement(View, {
- style: styles.container,
- dataSentryElement: \\"View\\",
- dataSentryComponent: \\"App\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/React.createElement(Text, {
- style: {
- color: '#eee'
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, null), /*#__PURE__*/React.createElement(PizzaTranslator, {
- dataSentryElement: \\"PizzaTranslator\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }));
-}
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'stretch',
- backgroundColor: '#222',
- alignItems: 'center',
- justifyContent: 'center'
- }
-});"
-`;
-
-const BananasPizzaAppStandardOutputBananasPizzaAppAttributesNoPizzaElements = `
-"import React, { Component } from 'react';
-import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
-UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
-
-class Bananas extends Component {
- render() {
- let pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/React.createElement(Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
-
-}
-
-class PizzaTranslator extends Component {
- constructor(props) {
- super(props);
- this.state = {
- text: ''
- };
- }
-
- render() {
- return /*#__PURE__*/React.createElement(View, {
- style: {
- padding: 10
- },
- dataSentryElement: \\"View\\",
- dataSentryComponent: \\"PizzaTranslator\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/React.createElement(TextInput, {
- style: {
- backgroundColor: '#000',
- color: '#eee',
- padding: 8
- },
- placeholder: \\"Type here to translate!\\" // not supported on iOS
- ,
- onChangeText: text => this.setState({
- text
- }),
- value: this.state.text,
- dataSentryElement: \\"TextInput\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/React.createElement(Text, {
- style: {
- padding: 10,
- fontSize: 42
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
- }
-
-}
-
-export default function App() {
- return /*#__PURE__*/React.createElement(View, {
- style: styles.container,
- dataSentryElement: \\"View\\",
- dataSentryComponent: \\"App\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/React.createElement(Text, {
- style: {
- color: '#eee'
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
- dataSentryElement: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/React.createElement(PizzaTranslator, null));
-}
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'stretch',
- backgroundColor: '#222',
- alignItems: 'center',
- justifyContent: 'center'
- }
-});"
-`;
-
-const BananasPizzaAppStandardOutputBananasPizzaAppAttributesNoBananasPizzaElements = `
-"import React, { Component } from 'react';
-import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
-UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
-
-class Bananas extends Component {
- render() {
- let pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/React.createElement(Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
-
-}
-
-class PizzaTranslator extends Component {
- constructor(props) {
- super(props);
- this.state = {
- text: ''
- };
- }
-
- render() {
- return /*#__PURE__*/React.createElement(View, {
- style: {
- padding: 10
- },
- dataSentryElement: \\"View\\",
- dataSentryComponent: \\"PizzaTranslator\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/React.createElement(TextInput, {
- style: {
- backgroundColor: '#000',
- color: '#eee',
- padding: 8
- },
- placeholder: \\"Type here to translate!\\" // not supported on iOS
- ,
- onChangeText: text => this.setState({
- text
- }),
- value: this.state.text,
- dataSentryElement: \\"TextInput\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/React.createElement(Text, {
- style: {
- padding: 10,
- fontSize: 42
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
- }
-
-}
-
-export default function App() {
- return /*#__PURE__*/React.createElement(View, {
- style: styles.container,
- dataSentryElement: \\"View\\",
- dataSentryComponent: \\"App\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/React.createElement(Text, {
- style: {
- color: '#eee'
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, null), /*#__PURE__*/React.createElement(PizzaTranslator, null));
-}
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'stretch',
- backgroundColor: '#222',
- alignItems: 'center',
- justifyContent: 'center'
- }
-});"
-`;
-
-const BananasPizzaAppStandardOutputBananasPizzaAppAttributes = `
-"import React, { Component } from 'react';
-import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
-UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
-
-class Bananas extends Component {
- render() {
- let pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/React.createElement(Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
-
-}
-
-class PizzaTranslator extends Component {
- constructor(props) {
- super(props);
- this.state = {
- text: ''
- };
- }
-
- render() {
- return /*#__PURE__*/React.createElement(View, {
- style: {
- padding: 10
- },
- dataSentryElement: \\"View\\",
- dataSentryComponent: \\"PizzaTranslator\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/React.createElement(TextInput, {
- style: {
- backgroundColor: '#000',
- color: '#eee',
- padding: 8
- },
- placeholder: \\"Type here to translate!\\" // not supported on iOS
- ,
- onChangeText: text => this.setState({
- text
- }),
- value: this.state.text,
- dataSentryElement: \\"TextInput\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/React.createElement(Text, {
- style: {
- padding: 10,
- fontSize: 42
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
- }
-
-}
-
-export default function App() {
- return /*#__PURE__*/React.createElement(View, {
- style: styles.container,
- dataSentryElement: \\"View\\",
- dataSentryComponent: \\"App\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/React.createElement(Text, {
- style: {
- color: '#eee'
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
- dataSentryElement: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/React.createElement(PizzaTranslator, {
- dataSentryElement: \\"PizzaTranslator\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }));
-}
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'stretch',
- backgroundColor: '#222',
- alignItems: 'center',
- justifyContent: 'center'
- }
-});"
-`;
-
-const BananasPizzaAppStandardOutputBananasAttributes = `
-"import React, { Component } from 'react';
-import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
-UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
-
-class Bananas extends Component {
- render() {
- let pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/React.createElement(Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
-
-}
-
-class PizzaTranslator extends Component {
- constructor(props) {
- super(props);
- this.state = {
- text: ''
- };
- }
-
- render() {
- return /*#__PURE__*/React.createElement(View, {
- style: {
- padding: 10
- }
- }, /*#__PURE__*/React.createElement(TextInput, {
- style: {
- backgroundColor: '#000',
- color: '#eee',
- padding: 8
- },
- placeholder: \\"Type here to translate!\\" // not supported on iOS
- ,
- onChangeText: text => this.setState({
- text
- }),
- value: this.state.text,
- dataSentryElement: \\"TextInput\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/React.createElement(Text, {
- style: {
- padding: 10,
- fontSize: 42
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
- }
-
-}
-
-export default function App() {
- return /*#__PURE__*/React.createElement(View, {
- style: styles.container
- }, /*#__PURE__*/React.createElement(Text, {
- style: {
- color: '#eee'
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
- dataSentryElement: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/React.createElement(PizzaTranslator, {
- dataSentryElement: \\"PizzaTranslator\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }));
-}
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'stretch',
- backgroundColor: '#222',
- alignItems: 'center',
- justifyContent: 'center'
- }
-});"
-`;
-
-const BananasPizzaAppStandardOutputPizzaAttributes = `
-"import React, { Component } from 'react';
-import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
-UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
-
-class Bananas extends Component {
- render() {
- let pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/React.createElement(Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\"
- });
- }
-
-}
-
-class PizzaTranslator extends Component {
- constructor(props) {
- super(props);
- this.state = {
- text: ''
- };
- }
-
- render() {
- return /*#__PURE__*/React.createElement(View, {
- style: {
- padding: 10
- },
- dataSentryElement: \\"View\\",
- dataSentryComponent: \\"PizzaTranslator\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/React.createElement(TextInput, {
- style: {
- backgroundColor: '#000',
- color: '#eee',
- padding: 8
- },
- placeholder: \\"Type here to translate!\\" // not supported on iOS
- ,
- onChangeText: text => this.setState({
- text
- }),
- value: this.state.text,
- dataSentryElement: \\"TextInput\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/React.createElement(Text, {
- style: {
- padding: 10,
- fontSize: 42
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
- }
-
-}
-
-export default function App() {
- return /*#__PURE__*/React.createElement(View, {
- style: styles.container
- }, /*#__PURE__*/React.createElement(Text, {
- style: {
- color: '#eee'
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
- dataSentryElement: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/React.createElement(PizzaTranslator, {
- dataSentryElement: \\"PizzaTranslator\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }));
-}
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'stretch',
- backgroundColor: '#222',
- alignItems: 'center',
- justifyContent: 'center'
- }
-});"
-`;
-
-const BananasPizzaAppStandardOutputAppAttributes = `
-"import React, { Component } from 'react';
-import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
-UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
-
-class Bananas extends Component {
- render() {
- let pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/React.createElement(Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\"
- });
- }
-
-}
-
-class PizzaTranslator extends Component {
- constructor(props) {
- super(props);
- this.state = {
- text: ''
- };
- }
-
- render() {
- return /*#__PURE__*/React.createElement(View, {
- style: {
- padding: 10
- }
- }, /*#__PURE__*/React.createElement(TextInput, {
- style: {
- backgroundColor: '#000',
- color: '#eee',
- padding: 8
- },
- placeholder: \\"Type here to translate!\\" // not supported on iOS
- ,
- onChangeText: text => this.setState({
- text
- }),
- value: this.state.text,
- dataSentryElement: \\"TextInput\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/React.createElement(Text, {
- style: {
- padding: 10,
- fontSize: 42
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
- }
-
-}
-
-export default function App() {
- return /*#__PURE__*/React.createElement(View, {
- style: styles.container,
- dataSentryElement: \\"View\\",
- dataSentryComponent: \\"App\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/React.createElement(Text, {
- style: {
- color: '#eee'
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
- dataSentryElement: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/React.createElement(PizzaTranslator, {
- dataSentryElement: \\"PizzaTranslator\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }));
-}
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'stretch',
- backgroundColor: '#222',
- alignItems: 'center',
- justifyContent: 'center'
- }
-});"
-`;
-
-const BananasPizzaAppStandardOutputBananasPizzaAttributes = `
-"import React, { Component } from 'react';
-import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
-UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
-
-class Bananas extends Component {
- render() {
- let pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/React.createElement(Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
-
-}
-
-class PizzaTranslator extends Component {
- constructor(props) {
- super(props);
- this.state = {
- text: ''
- };
- }
-
- render() {
- return /*#__PURE__*/React.createElement(View, {
- style: {
- padding: 10
- },
- dataSentryElement: \\"View\\",
- dataSentryComponent: \\"PizzaTranslator\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/React.createElement(TextInput, {
- style: {
- backgroundColor: '#000',
- color: '#eee',
- padding: 8
- },
- placeholder: \\"Type here to translate!\\" // not supported on iOS
- ,
- onChangeText: text => this.setState({
- text
- }),
- value: this.state.text,
- dataSentryElement: \\"TextInput\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/React.createElement(Text, {
- style: {
- padding: 10,
- fontSize: 42
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
- }
-
-}
-
-export default function App() {
- return /*#__PURE__*/React.createElement(View, {
- style: styles.container
- }, /*#__PURE__*/React.createElement(Text, {
- style: {
- color: '#eee'
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
- dataSentryElement: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/React.createElement(PizzaTranslator, {
- dataSentryElement: \\"PizzaTranslator\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }));
-}
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'stretch',
- backgroundColor: '#222',
- alignItems: 'center',
- justifyContent: 'center'
- }
-});"
-`;
-
-const BananasPizzaAppStandardOutputBananasAppAttributes = `
-"import React, { Component } from 'react';
-import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
-UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
-
-class Bananas extends Component {
- render() {
- let pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/React.createElement(Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
-
-}
-
-class PizzaTranslator extends Component {
- constructor(props) {
- super(props);
- this.state = {
- text: ''
- };
- }
-
- render() {
- return /*#__PURE__*/React.createElement(View, {
- style: {
- padding: 10
- }
- }, /*#__PURE__*/React.createElement(TextInput, {
- style: {
- backgroundColor: '#000',
- color: '#eee',
- padding: 8
- },
- placeholder: \\"Type here to translate!\\" // not supported on iOS
- ,
- onChangeText: text => this.setState({
- text
- }),
- value: this.state.text,
- dataSentryElement: \\"TextInput\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/React.createElement(Text, {
- style: {
- padding: 10,
- fontSize: 42
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
- }
-
-}
-
-export default function App() {
- return /*#__PURE__*/React.createElement(View, {
- style: styles.container,
- dataSentryElement: \\"View\\",
- dataSentryComponent: \\"App\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/React.createElement(Text, {
- style: {
- color: '#eee'
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
- dataSentryElement: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/React.createElement(PizzaTranslator, {
- dataSentryElement: \\"PizzaTranslator\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }));
-}
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'stretch',
- backgroundColor: '#222',
- alignItems: 'center',
- justifyContent: 'center'
- }
-});"
-`;
-
-const BananasPizzaAppStandardOutputPizzaAppAttributes = `
-"import React, { Component } from 'react';
-import { StyleSheet, Text, TextInput, View, Image, UIManager } from 'react-native';
-UIManager.getViewManagerConfig('RCTView').NativeProps.fsClass = \\"String\\";
-
-class Bananas extends Component {
- render() {
- let pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/React.createElement(Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\"
- });
- }
-
-}
-
-class PizzaTranslator extends Component {
- constructor(props) {
- super(props);
- this.state = {
- text: ''
- };
- }
-
- render() {
- return /*#__PURE__*/React.createElement(View, {
- style: {
- padding: 10
- },
- dataSentryElement: \\"View\\",
- dataSentryComponent: \\"PizzaTranslator\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/React.createElement(TextInput, {
- style: {
- backgroundColor: '#000',
- color: '#eee',
- padding: 8
- },
- placeholder: \\"Type here to translate!\\" // not supported on iOS
- ,
- onChangeText: text => this.setState({
- text
- }),
- value: this.state.text,
- dataSentryElement: \\"TextInput\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/React.createElement(Text, {
- style: {
- padding: 10,
- fontSize: 42
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, this.state.text.split(' ').map(word => word && '🍕').join(' ')));
- }
-
-}
-
-export default function App() {
- return /*#__PURE__*/React.createElement(View, {
- style: styles.container,
- dataSentryElement: \\"View\\",
- dataSentryComponent: \\"App\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, /*#__PURE__*/React.createElement(Text, {
- style: {
- color: '#eee'
- },
- dataSentryElement: \\"Text\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }, \\"FullStory ReactNative testing app\\"), /*#__PURE__*/React.createElement(Bananas, {
- dataSentryElement: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }), /*#__PURE__*/React.createElement(PizzaTranslator, {
- dataSentryElement: \\"PizzaTranslator\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- }));
-}
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'stretch',
- backgroundColor: '#222',
- alignItems: 'center',
- justifyContent: 'center'
- }
-});"
-`;
-
const BananasStandardInput = `import React, { Component } from 'react';
import { Image } from 'react-native';
@@ -1132,55 +92,6 @@ class Bananas extends Component {
}
}`;
-const BananasStandardOutputNoAttributes = `
-"import React, { Component } from 'react';
-import { Image } from 'react-native';
-
-class Bananas extends Component {
- render() {
- let pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/React.createElement(Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\"
- });
- }
-
-}"
-`;
-
-const BananasStandardOutputWithAttributes = `
-"import React, { Component } from 'react';
-import { Image } from 'react-native';
-
-class Bananas extends Component {
- render() {
- let pic = {
- uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
- };
- return /*#__PURE__*/React.createElement(Image, {
- source: pic,
- style: {
- width: 193,
- height: 110,
- marginTop: 10
- },
- fsClass: \\"test-class\\",
- dataSentryElement: \\"Image\\",
- dataSentryComponent: \\"Bananas\\",
- dataSentrySourceFile: \\"filename-test.js\\"
- });
- }
-
-}"
-`;
-
it("unknown-element snapshot matches", () => {
const result = transform(
`import React, { Component } from 'react';
From c2ab09be190d01089d415ee805b3cc314ba51e4f Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 12:26:27 -0500
Subject: [PATCH 38/51] Add notes on what changed in vendored code
---
packages/component-annotate-plugin/src/index.ts | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index 843414be..2880cc1b 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -25,7 +25,11 @@
/**
* The following code is based on the FullStory Babel plugin, but has been modified to work
- * with Sentry products
+ * with Sentry products:
+ *
+ * - Added `sentry` to data properties, i.e `data-sentry-component`
+ * - Converted to TypeScript
+ * - Code cleanups
*/
import type * as Babel from "@babel/core";
From 968e07e5cea5329384d1bc8c7fc6399822bd8637 Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 12:27:09 -0500
Subject: [PATCH 39/51] Add license to constants
---
.../src/constants.ts | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/packages/component-annotate-plugin/src/constants.ts b/packages/component-annotate-plugin/src/constants.ts
index 127a9301..51eac57d 100644
--- a/packages/component-annotate-plugin/src/constants.ts
+++ b/packages/component-annotate-plugin/src/constants.ts
@@ -1,3 +1,28 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2020 Engineering at FullStory
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
export const KNOWN_INCOMPATIBLE_PLUGINS = [
// This module might be causing an issue preventing clicks. For safety, we won't run on this module.
"react-native-testfairy",
From 9b39f13903366c25392a2e284a83a21fc371d974 Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 12:28:41 -0500
Subject: [PATCH 40/51] move comment
---
packages/component-annotate-plugin/src/index.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index 2880cc1b..57a0705d 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -81,7 +81,8 @@ export function componentNameAnnotatePlugin({ types: t }: typeof Babel): Annotat
);
},
ArrowFunctionExpression(path, state) {
- const parent = path.parent; // We're expecting a `VariableDeclarator` like `const MyComponent =`
+ // We're expecting a `VariableDeclarator` like `const MyComponent =`
+ const parent = path.parent;
if (
!parent ||
!("id" in parent) ||
From 0c9f610f91489a4c3428c21dc502a1e35062ae9a Mon Sep 17 00:00:00 2001
From: Ash <0Calories@users.noreply.github.com>
Date: Wed, 31 Jan 2024 12:29:43 -0500
Subject: [PATCH 41/51] Update packages/component-annotate-plugin/src/index.ts
Co-authored-by: Abhijeet Prasad
---
packages/component-annotate-plugin/src/index.ts | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/packages/component-annotate-plugin/src/index.ts b/packages/component-annotate-plugin/src/index.ts
index 57a0705d..894155c0 100644
--- a/packages/component-annotate-plugin/src/index.ts
+++ b/packages/component-annotate-plugin/src/index.ts
@@ -93,7 +93,9 @@ export function componentNameAnnotatePlugin({ types: t }: typeof Babel): Annotat
return;
}
- if (isKnownIncompatiblePluginFromState(state)) return;
+ if (isKnownIncompatiblePluginFromState(state)) {
+ return;
+ }
functionBodyPushAttributes(
state.opts["annotate-fragments"] === true,
From b97d05dacc7efc7a64921c4ab196d8c8de079237 Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 12:58:49 -0500
Subject: [PATCH 42/51] Add package to Craft `requireNames`
---
.craft.yml | 1 +
packages/component-annotate-plugin/.babelrc.json | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/.craft.yml b/.craft.yml
index 85179f1c..e3db425c 100644
--- a/.craft.yml
+++ b/.craft.yml
@@ -9,6 +9,7 @@ requireNames:
- /^sentry-rollup-plugin-.*\.tgz$/
- /^sentry-vite-plugin-.*\.tgz$/
- /^sentry-webpack-plugin-.*\.tgz$/
+ - /^sentry-component-annotate-plugin-.*\.tgz$/
targets:
- name: github
includeNames: /^sentry-.*.tgz$/
diff --git a/packages/component-annotate-plugin/.babelrc.json b/packages/component-annotate-plugin/.babelrc.json
index f878e8f9..0c20c06e 100644
--- a/packages/component-annotate-plugin/.babelrc.json
+++ b/packages/component-annotate-plugin/.babelrc.json
@@ -1,3 +1,3 @@
{
- "presets": ["@babel/typescript"]
+ "presets": ["@babel/env", "@babel/typescript"]
}
From 21d3fd81b038381cb91c92a07845f56ecb9c8ccd Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 15:22:03 -0500
Subject: [PATCH 43/51] Add readme content
---
.../README_TEMPLATE.md | 82 +++++++++++++++++++
1 file changed, 82 insertions(+)
diff --git a/packages/component-annotate-plugin/README_TEMPLATE.md b/packages/component-annotate-plugin/README_TEMPLATE.md
index e69de29b..bfff4632 100644
--- a/packages/component-annotate-plugin/README_TEMPLATE.md
+++ b/packages/component-annotate-plugin/README_TEMPLATE.md
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+# Sentry Component Annotate Plugin
+
+[](https://www.npmjs.com/package/@sentry/component-annotate-plugin)
+[](https://www.npmjs.com/package/@sentry/component-annotate-plugin)
+[](https://www.npmjs.com/package/@component-annotate-plugin)
+
+A Babel plugin that automatically annotates your output DOM with their respective frontend component names.
+This will unlock the capability to search for Replays in Sentry by component name, as well as see component names in breadcrumbs and performance monitoring.
+Currently, this plugin only works with React, and will exclusively parse `.jsx` and `.tsx` files.
+
+### Note
+
+This plugin comes included in Sentry's bundler plugins, alongside many other features to improve your Sentry workflow.
+This plugin may be downloaded individually, but it is recommended that you install the bundler plugins for your respective bundler, and enable this feature through the config object.
+
+Check out the supported bundler plugin packages for installation instructions:
+
+- [Rollup](https://www.npmjs.com/package/@sentry/rollup-plugin)
+- [Vite](https://www.npmjs.com/package/@sentry/vite-plugin)
+- [Webpack](https://www.npmjs.com/package/@sentry/webpack-plugin)
+
+## Installation
+
+Using npm:
+
+```bash
+npm install @sentry/component-annotate-plugin --save-dev
+```
+
+Using yarn:
+
+```bash
+yarn add @sentry/component-annotate-plugin --dev
+```
+
+Using pnpm:
+
+```bash
+pnpm install @sentry/component-annotate-plugin --dev
+```
+
+## Example
+
+```js
+// babel.config.js
+
+{
+ // ... other config above ...
+
+ plugins: [
+ ['@sentry/component-annotate-plugin']
+ ],
+}
+```
+
+Or alternatively, configure the plugin by directly importing it:
+
+```js
+// babel.config.js
+
+import {componentNameAnnotatePlugin} from '@sentry/component-annotate-plugin';
+
+{
+ // ... other config above ...
+
+ plugins: [
+ [componentNameAnnotatePlugin]
+ ],
+}
+```
+
+## More information
+
+- [Sentry Documentation](https://docs.sentry.io/quickstart/)
+- [Sentry Discord](https://discord.gg/Ww9hbqr)
+- [Sentry Stackoverflow](http://stackoverflow.com/questions/tagged/sentry)
From 6b3fd7bfda3a3c60291e744adf236d54cfd7649c Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 15:51:09 -0500
Subject: [PATCH 44/51] Add beta notice
---
packages/component-annotate-plugin/README_TEMPLATE.md | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/packages/component-annotate-plugin/README_TEMPLATE.md b/packages/component-annotate-plugin/README_TEMPLATE.md
index bfff4632..14006fac 100644
--- a/packages/component-annotate-plugin/README_TEMPLATE.md
+++ b/packages/component-annotate-plugin/README_TEMPLATE.md
@@ -4,12 +4,14 @@
-# Sentry Component Annotate Plugin
+# Sentry Component Annotate Plugin (Beta)
[](https://www.npmjs.com/package/@sentry/component-annotate-plugin)
[](https://www.npmjs.com/package/@sentry/component-annotate-plugin)
[](https://www.npmjs.com/package/@component-annotate-plugin)
+This plugin is currently in beta. Please help us improve by [reporting any issues or giving us feedback](https://github.com/getsentry/sentry-javascript-bundler-plugins/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
+
A Babel plugin that automatically annotates your output DOM with their respective frontend component names.
This will unlock the capability to search for Replays in Sentry by component name, as well as see component names in breadcrumbs and performance monitoring.
Currently, this plugin only works with React, and will exclusively parse `.jsx` and `.tsx` files.
From 900aedd1e00fb9c6861e058fd69b38274daa81d6 Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 15:51:23 -0500
Subject: [PATCH 45/51] Add minimum JS SDK version notice
---
packages/component-annotate-plugin/README_TEMPLATE.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/packages/component-annotate-plugin/README_TEMPLATE.md b/packages/component-annotate-plugin/README_TEMPLATE.md
index 14006fac..f72cbcbf 100644
--- a/packages/component-annotate-plugin/README_TEMPLATE.md
+++ b/packages/component-annotate-plugin/README_TEMPLATE.md
@@ -14,6 +14,7 @@ This plugin is currently in beta. Please help us improve by [reporting any issue
A Babel plugin that automatically annotates your output DOM with their respective frontend component names.
This will unlock the capability to search for Replays in Sentry by component name, as well as see component names in breadcrumbs and performance monitoring.
+Please note that your Sentry JavaScript SDK version must be at least `7.91.0` to take advantage of these features.
Currently, this plugin only works with React, and will exclusively parse `.jsx` and `.tsx` files.
### Note
From 89d82916073cca2c3af4c9e2d3f5edf6d46a1062 Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 15:52:43 -0500
Subject: [PATCH 46/51] change version to align with other packages
---
packages/component-annotate-plugin/package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/component-annotate-plugin/package.json b/packages/component-annotate-plugin/package.json
index 1b82dfd6..a995e46a 100644
--- a/packages/component-annotate-plugin/package.json
+++ b/packages/component-annotate-plugin/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/component-annotate-plugin",
- "version": "1.0.0",
+ "version": "2.10.3",
"description": "A Babel plugin that annotates frontend components with additional data to enrich the experience in Sentry",
"repository": "git://github.com/getsentry/sentry-javascript-bundler-plugins.git",
"homepage": "https://github.com/getsentry/sentry-javascript-bundler-plugins/tree/main/packages/component-annotate-plugin",
From 7111b5f8db71f7eb4ceacd1be8b322f9a587efc9 Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 15:57:13 -0500
Subject: [PATCH 47/51] add plugin ordering note
---
packages/component-annotate-plugin/README_TEMPLATE.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/packages/component-annotate-plugin/README_TEMPLATE.md b/packages/component-annotate-plugin/README_TEMPLATE.md
index f72cbcbf..55991ce9 100644
--- a/packages/component-annotate-plugin/README_TEMPLATE.md
+++ b/packages/component-annotate-plugin/README_TEMPLATE.md
@@ -57,6 +57,7 @@ pnpm install @sentry/component-annotate-plugin --dev
// ... other config above ...
plugins: [
+ // Put this plugin before any other plugins you have that transform JSX code
['@sentry/component-annotate-plugin']
],
}
@@ -73,6 +74,7 @@ import {componentNameAnnotatePlugin} from '@sentry/component-annotate-plugin';
// ... other config above ...
plugins: [
+ // Put this plugin before any other plugins you have that transform JSX code
[componentNameAnnotatePlugin]
],
}
From bc50479b2ebbd3da03905d6d1f7f8fbc0daea79a Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 16:03:19 -0500
Subject: [PATCH 48/51] Add note that it is not supported by esbuild
---
packages/component-annotate-plugin/README_TEMPLATE.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/packages/component-annotate-plugin/README_TEMPLATE.md b/packages/component-annotate-plugin/README_TEMPLATE.md
index 55991ce9..77f1d522 100644
--- a/packages/component-annotate-plugin/README_TEMPLATE.md
+++ b/packages/component-annotate-plugin/README_TEMPLATE.md
@@ -27,6 +27,7 @@ Check out the supported bundler plugin packages for installation instructions:
- [Rollup](https://www.npmjs.com/package/@sentry/rollup-plugin)
- [Vite](https://www.npmjs.com/package/@sentry/vite-plugin)
- [Webpack](https://www.npmjs.com/package/@sentry/webpack-plugin)
+- esbuild: Not currently supported
## Installation
From 384aa0a4d241d54b0c4941fb788742ea01cf20a5 Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 16:07:28 -0500
Subject: [PATCH 49/51] i said bundler too much
---
packages/component-annotate-plugin/README_TEMPLATE.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/component-annotate-plugin/README_TEMPLATE.md b/packages/component-annotate-plugin/README_TEMPLATE.md
index 77f1d522..562b656c 100644
--- a/packages/component-annotate-plugin/README_TEMPLATE.md
+++ b/packages/component-annotate-plugin/README_TEMPLATE.md
@@ -20,7 +20,7 @@ Currently, this plugin only works with React, and will exclusively parse `.jsx`
### Note
This plugin comes included in Sentry's bundler plugins, alongside many other features to improve your Sentry workflow.
-This plugin may be downloaded individually, but it is recommended that you install the bundler plugins for your respective bundler, and enable this feature through the config object.
+It can be downloaded individually, but it is recommended that you install the bundler plugins for your respective bundler, and enable this feature through the config object.
Check out the supported bundler plugin packages for installation instructions:
From 9f3d22392230f932e3027134a73babbd060a14d4 Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 16:11:54 -0500
Subject: [PATCH 50/51] Rename to README and remove prepack file
---
.../README_TEMPLATE.md | 88 -------------------
.../component-annotate-plugin/src/prepack.ts | 7 --
2 files changed, 95 deletions(-)
delete mode 100644 packages/component-annotate-plugin/README_TEMPLATE.md
delete mode 100644 packages/component-annotate-plugin/src/prepack.ts
diff --git a/packages/component-annotate-plugin/README_TEMPLATE.md b/packages/component-annotate-plugin/README_TEMPLATE.md
deleted file mode 100644
index 562b656c..00000000
--- a/packages/component-annotate-plugin/README_TEMPLATE.md
+++ /dev/null
@@ -1,88 +0,0 @@
-
-
-
-
-
-
-# Sentry Component Annotate Plugin (Beta)
-
-[](https://www.npmjs.com/package/@sentry/component-annotate-plugin)
-[](https://www.npmjs.com/package/@sentry/component-annotate-plugin)
-[](https://www.npmjs.com/package/@component-annotate-plugin)
-
-This plugin is currently in beta. Please help us improve by [reporting any issues or giving us feedback](https://github.com/getsentry/sentry-javascript-bundler-plugins/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
-
-A Babel plugin that automatically annotates your output DOM with their respective frontend component names.
-This will unlock the capability to search for Replays in Sentry by component name, as well as see component names in breadcrumbs and performance monitoring.
-Please note that your Sentry JavaScript SDK version must be at least `7.91.0` to take advantage of these features.
-Currently, this plugin only works with React, and will exclusively parse `.jsx` and `.tsx` files.
-
-### Note
-
-This plugin comes included in Sentry's bundler plugins, alongside many other features to improve your Sentry workflow.
-It can be downloaded individually, but it is recommended that you install the bundler plugins for your respective bundler, and enable this feature through the config object.
-
-Check out the supported bundler plugin packages for installation instructions:
-
-- [Rollup](https://www.npmjs.com/package/@sentry/rollup-plugin)
-- [Vite](https://www.npmjs.com/package/@sentry/vite-plugin)
-- [Webpack](https://www.npmjs.com/package/@sentry/webpack-plugin)
-- esbuild: Not currently supported
-
-## Installation
-
-Using npm:
-
-```bash
-npm install @sentry/component-annotate-plugin --save-dev
-```
-
-Using yarn:
-
-```bash
-yarn add @sentry/component-annotate-plugin --dev
-```
-
-Using pnpm:
-
-```bash
-pnpm install @sentry/component-annotate-plugin --dev
-```
-
-## Example
-
-```js
-// babel.config.js
-
-{
- // ... other config above ...
-
- plugins: [
- // Put this plugin before any other plugins you have that transform JSX code
- ['@sentry/component-annotate-plugin']
- ],
-}
-```
-
-Or alternatively, configure the plugin by directly importing it:
-
-```js
-// babel.config.js
-
-import {componentNameAnnotatePlugin} from '@sentry/component-annotate-plugin';
-
-{
- // ... other config above ...
-
- plugins: [
- // Put this plugin before any other plugins you have that transform JSX code
- [componentNameAnnotatePlugin]
- ],
-}
-```
-
-## More information
-
-- [Sentry Documentation](https://docs.sentry.io/quickstart/)
-- [Sentry Discord](https://discord.gg/Ww9hbqr)
-- [Sentry Stackoverflow](http://stackoverflow.com/questions/tagged/sentry)
diff --git a/packages/component-annotate-plugin/src/prepack.ts b/packages/component-annotate-plugin/src/prepack.ts
deleted file mode 100644
index 55793e25..00000000
--- a/packages/component-annotate-plugin/src/prepack.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { generateOptionsDocumentation } from "@sentry-internal/dev-utils";
-import * as fs from "fs";
-import * as path from "path";
-
-const readmeTemplate = fs.readFileSync(path.join(__dirname, "..", "README_TEMPLATE.md"), "utf-8");
-const readme = readmeTemplate.replace(/#OPTIONS_SECTION_INSERT#/, generateOptionsDocumentation());
-fs.writeFileSync(path.join(__dirname, "..", "README.md"), readme, "utf-8");
From e6b052bd55463764aaa41212ccc14b3c434903ff Mon Sep 17 00:00:00 2001
From: Ash Anand
Date: Wed, 31 Jan 2024 17:00:28 -0500
Subject: [PATCH 51/51] dont gitignore the readme!"
---
packages/component-annotate-plugin/.gitignore | 1 -
packages/component-annotate-plugin/README.md | 88 +++++++++++++++++++
2 files changed, 88 insertions(+), 1 deletion(-)
create mode 100644 packages/component-annotate-plugin/README.md
diff --git a/packages/component-annotate-plugin/.gitignore b/packages/component-annotate-plugin/.gitignore
index 57b8bee7..36d3a9c3 100644
--- a/packages/component-annotate-plugin/.gitignore
+++ b/packages/component-annotate-plugin/.gitignore
@@ -1,3 +1,2 @@
dist
-README.md
.DS_Store
diff --git a/packages/component-annotate-plugin/README.md b/packages/component-annotate-plugin/README.md
new file mode 100644
index 00000000..562b656c
--- /dev/null
+++ b/packages/component-annotate-plugin/README.md
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+# Sentry Component Annotate Plugin (Beta)
+
+[](https://www.npmjs.com/package/@sentry/component-annotate-plugin)
+[](https://www.npmjs.com/package/@sentry/component-annotate-plugin)
+[](https://www.npmjs.com/package/@component-annotate-plugin)
+
+This plugin is currently in beta. Please help us improve by [reporting any issues or giving us feedback](https://github.com/getsentry/sentry-javascript-bundler-plugins/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
+
+A Babel plugin that automatically annotates your output DOM with their respective frontend component names.
+This will unlock the capability to search for Replays in Sentry by component name, as well as see component names in breadcrumbs and performance monitoring.
+Please note that your Sentry JavaScript SDK version must be at least `7.91.0` to take advantage of these features.
+Currently, this plugin only works with React, and will exclusively parse `.jsx` and `.tsx` files.
+
+### Note
+
+This plugin comes included in Sentry's bundler plugins, alongside many other features to improve your Sentry workflow.
+It can be downloaded individually, but it is recommended that you install the bundler plugins for your respective bundler, and enable this feature through the config object.
+
+Check out the supported bundler plugin packages for installation instructions:
+
+- [Rollup](https://www.npmjs.com/package/@sentry/rollup-plugin)
+- [Vite](https://www.npmjs.com/package/@sentry/vite-plugin)
+- [Webpack](https://www.npmjs.com/package/@sentry/webpack-plugin)
+- esbuild: Not currently supported
+
+## Installation
+
+Using npm:
+
+```bash
+npm install @sentry/component-annotate-plugin --save-dev
+```
+
+Using yarn:
+
+```bash
+yarn add @sentry/component-annotate-plugin --dev
+```
+
+Using pnpm:
+
+```bash
+pnpm install @sentry/component-annotate-plugin --dev
+```
+
+## Example
+
+```js
+// babel.config.js
+
+{
+ // ... other config above ...
+
+ plugins: [
+ // Put this plugin before any other plugins you have that transform JSX code
+ ['@sentry/component-annotate-plugin']
+ ],
+}
+```
+
+Or alternatively, configure the plugin by directly importing it:
+
+```js
+// babel.config.js
+
+import {componentNameAnnotatePlugin} from '@sentry/component-annotate-plugin';
+
+{
+ // ... other config above ...
+
+ plugins: [
+ // Put this plugin before any other plugins you have that transform JSX code
+ [componentNameAnnotatePlugin]
+ ],
+}
+```
+
+## More information
+
+- [Sentry Documentation](https://docs.sentry.io/quickstart/)
+- [Sentry Discord](https://discord.gg/Ww9hbqr)
+- [Sentry Stackoverflow](http://stackoverflow.com/questions/tagged/sentry)