Skip to content

Commit

Permalink
Move detoxAction invocations to generated code
Browse files Browse the repository at this point in the history
To do this I had to add some mechanisms to allow
sanitizers to work with function names and arguments
instead of only with types as before.

Also some more types were enabled.
  • Loading branch information
DanielMSchmidt committed Jan 6, 2018
1 parent 259a903 commit e803911
Show file tree
Hide file tree
Showing 10 changed files with 259 additions and 62 deletions.
62 changes: 56 additions & 6 deletions detox/src/android/espressoapi/DetoxAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,38 @@
*/



function sanitize_android_edge(edge) {
switch (edge) {
case "left":
return 1;
case "right":
return 2;
case "top":
return 3;
case "bottom":
return 4;
default:
throw new Error(
`edge must be a 'left'/'right'/'top'/'bottom', got ${edge}`
);
}
}
function sanitize_android_direction(direction) {
switch (direction) {
case "left":
return 1;
case "right":
return 2;
case "up":
return 3;
case "down":
return 4;
default:
throw new Error(
`direction must be a 'left'/'right'/'up'/'down', got ${direction}`
);
}
}
class DetoxAction {
static multiClick(times) {
if (typeof times !== "number") throw new Error("times should be a number, but got " + (times + (" (" + (typeof times + ")"))));
Expand Down Expand Up @@ -42,7 +73,7 @@ class DetoxAction {
}

static scrollToEdge(edge) {
if (typeof edge !== "number") throw new Error("edge should be a number, but got " + (edge + (" (" + (typeof edge + ")"))));
if (typeof edge !== "string") throw new Error("edge should be a string, but got " + (edge + (" (" + (typeof edge + ")"))));
return {
target: {
type: "Class",
Expand All @@ -51,13 +82,13 @@ class DetoxAction {
method: "scrollToEdge",
args: [{
type: "Integer",
value: edge
value: sanitize_android_edge(edge)
}]
};
}

static scrollInDirection(direction, amountInDP) {
if (typeof direction !== "number") throw new Error("direction should be a number, but got " + (direction + (" (" + (typeof direction + ")"))));
if (typeof direction !== "string") throw new Error("direction should be a string, but got " + (direction + (" (" + (typeof direction + ")"))));
if (typeof amountInDP !== "number") throw new Error("amountInDP should be a number, but got " + (amountInDP + (" (" + (typeof amountInDP + ")"))));
return {
target: {
Expand All @@ -67,14 +98,33 @@ class DetoxAction {
method: "scrollInDirection",
args: [{
type: "Integer",
value: direction
value: sanitize_android_direction(direction)
}, {
type: "double",
type: "Double",
value: amountInDP
}]
};
}

static swipeInDirection(direction, fast) {
if (typeof direction !== "string") throw new Error("direction should be a string, but got " + (direction + (" (" + (typeof direction + ")"))));
if (typeof fast !== "boolean") throw new Error("fast should be a boolean, but got " + (fast + (" (" + (typeof fast + ")"))));
return {
target: {
type: "Class",
value: "com.wix.detox.espresso.DetoxAction"
},
method: "swipeInDirection",
args: [{
type: "Integer",
value: sanitize_android_direction(direction)
}, {
type: "boolean",
value: fast
}]
};
}

}

module.exports = DetoxAction;
36 changes: 5 additions & 31 deletions detox/src/android/expect.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ function setInvocationManager(im) {
const ViewActions = 'android.support.test.espresso.action.ViewActions';
const ViewAssertions = 'android.support.test.espresso.assertion.ViewAssertions';
const DetoxMatcher = 'com.wix.detox.espresso.DetoxMatcher';
const DetoxAction = 'com.wix.detox.espresso.DetoxAction';
const DetoxAssertion = 'com.wix.detox.espresso.DetoxAssertion';
const EspressoDetox = 'com.wix.detox.espresso.EspressoDetox';

Expand Down Expand Up @@ -82,51 +81,26 @@ class ClearTextAction extends Action {
class ScrollAmountAction extends Action {
constructor(direction, amount) {
super();
if (typeof direction !== 'string') throw new Error(`ScrollAmountAction ctor 1st argument must be a string, got ${typeof direction}`);
switch (direction) {
case 'left': direction = 1; break;
case 'right': direction = 2; break;
case 'up': direction = 3; break;
case 'down': direction = 4; break;
default: throw new Error(`ScrollAmountAction direction must be a 'left'/'right'/'up'/'down', got ${direction}`);
}
if (typeof amount !== 'number') throw new Error(`ScrollAmountAction ctor 2nd argument must be a number, got ${typeof amount}`);
this._call = invoke.call(invoke.Android.Class(DetoxAction), 'scrollInDirection', invoke.Android.Integer(direction), invoke.Android.Double(amount));
this._call = invoke.callDirectly(DetoxActionApi.scrollInDirection(direction, amount));
}
}

class ScrollEdgeAction extends Action {
constructor(edge) {
super();
if (typeof edge !== 'string') throw new Error(`ScrollEdgeAction ctor 1st argument must be a string, got ${typeof edge}`);
switch (edge) {
case 'left': edge = 1; break;
case 'right': edge = 2; break;
case 'top': edge = 3; break;
case 'bottom': edge = 4; break;
default: throw new Error(`ScrollEdgeAction edge must be a 'left'/'right'/'top'/'bottom', got ${edge}`);
}
this._call = invoke.call(invoke.Android.Class(DetoxAction), 'scrollToEdge', invoke.Android.Integer(edge));

this._call = invoke.callDirectly(DetoxActionApi.scrollToEdge(edge));
}
}

class SwipeAction extends Action {
// This implementation ignores the percentage parameter
constructor(direction, speed, percentage) {
super();
if (typeof direction !== 'string') throw new Error(`SwipeAction ctor 1st argument must be a string, got ${typeof direction}`);
if (typeof speed !== 'string') throw new Error(`SwipeAction ctor 2nd argument must be a string, got ${typeof speed}`);
switch (direction) {
case 'left': direction = 1; break;
case 'right': direction = 2; break;
case 'up': direction = 3; break;
case 'down': direction = 4; break;
default: throw new Error(`SwipeAction direction must be a 'left'/'right'/'up'/'down', got ${direction}`);
}
if (speed === 'fast') {
this._call = invoke.call(invoke.Android.Class(DetoxAction), 'swipeInDirection', invoke.Android.Integer(direction), invoke.Android.Boolean(true));
this._call = invoke.callDirectly(DetoxActionApi.swipeInDirection(direction, true));
} else if (speed === 'slow') {
this._call = invoke.call(invoke.Android.Class(DetoxAction), 'swipeInDirection', invoke.Android.Integer(direction), invoke.Android.Boolean(false));
this._call = invoke.callDirectly(DetoxActionApi.swipeInDirection(direction, false));
} else {
throw new Error(`SwipeAction speed must be a 'fast'/'slow', got ${speed}`);
}
Expand Down
20 changes: 20 additions & 0 deletions generation/__tests__/__snapshots__/android.js.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Android generation methods should add a sanitizer for the function with the correct name 1`] = `
Object {
"args": Array [
Object {
"type": "Integer",
"value": 4,
},
Object {
"type": "Double",
"value": 42,
},
],
"method": "scrollInDirection",
"target": Object {
"type": "Class",
"value": "com.wix.detox.espresso.DetoxAction",
},
}
`;

exports[`Android generation methods should generate type checks 1`] = `"times should be a number, but got FOO (string)"`;

exports[`Android generation methods should return adapter calls 1`] = `
Expand Down
4 changes: 4 additions & 0 deletions generation/__tests__/__snapshots__/global-functions.js.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`globals sanitize_android_direction should fail with unknown value 1`] = `"direction must be a 'left'/'right'/'up'/'down', got kittens"`;

exports[`globals sanitize_android_edge should fail with unknown value 1`] = `"edge must be a 'left'/'right'/'top'/'bottom', got kittens"`;

exports[`globals sanitize_greyContentEdge should fail with unknown value 1`] = `"GREYAction.GREYContentEdge must be a 'left'/'right'/'top'/'bottom', got kittens"`;

exports[`globals sanitize_greyDirection should fail with unknown value 1`] = `"GREYAction.GREYDirection must be a 'left'/'right'/'up'/'down', got kittens"`;
Expand Down
14 changes: 14 additions & 0 deletions generation/__tests__/android.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,19 @@ describe("Android generation", () => {

expect(result).toMatchSnapshot();
});

it("should add a sanitizer for the function with the correct name", () => {
const fn = ExampleClass.scrollInDirection;

expect(() => {
fn(3, 42);
}).toThrowError();

expect(() => {
fn("down", 42);
}).not.toThrowError();

expect(fn("down", 42)).toMatchSnapshot();
});
});
});
59 changes: 56 additions & 3 deletions generation/__tests__/global-functions.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
const globals = require("../core/global-functions");

describe("globals", () => {
describe("sanitize_android_direction", () => {
it("should return numbers for strings", () => {
expect(globals.sanitize_android_direction("left")).toBe(1);
expect(globals.sanitize_android_direction("right")).toBe(2);
expect(globals.sanitize_android_direction("up")).toBe(3);
expect(globals.sanitize_android_direction("down")).toBe(4);
});

it("should fail with unknown value", () => {
expect(() => {
globals.sanitize_android_direction("kittens");
}).toThrowErrorMatchingSnapshot();
});
});

describe("sanitize_android_edge", () => {
it("should return numbers for strings", () => {
expect(globals.sanitize_android_edge("left")).toBe(1);
expect(globals.sanitize_android_edge("right")).toBe(2);
expect(globals.sanitize_android_edge("top")).toBe(3);
expect(globals.sanitize_android_edge("bottom")).toBe(4);
});

it("should fail with unknown value", () => {
expect(() => {
globals.sanitize_android_edge("kittens");
}).toThrowErrorMatchingSnapshot();
});
});

describe("sanitize_greyDirection", () => {
it("should return numbers for strings", () => {
expect(globals.sanitize_greyDirection("left")).toBe(1);
Expand Down Expand Up @@ -33,9 +63,32 @@ describe("globals", () => {

describe("sanitize_uiAccessibilityTraits", () => {
it("should return numbers for traits", () => {
expect(globals.sanitize_uiAccessibilityTraits(["button", "link"])).toBe(
3
);
expect(globals.sanitize_uiAccessibilityTraits(["button"])).toBe(1);

[
"button",
"link",
"header",
"search",
"image",
"selected",
"plays",
"key",
"text",
"summary",
"disabled",
"frequentUpdates",
"startsMedia",
"adjustable",
"allowsDirectInteraction",
"pageTurn"
].forEach(trait => {
expect(typeof globals.sanitize_uiAccessibilityTraits([trait])).toBe(
"number"
);
});
});
it("should combine the traits", () => {
expect(
globals.sanitize_uiAccessibilityTraits([
"summary",
Expand Down
36 changes: 31 additions & 5 deletions generation/adapters/android.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,45 @@
const t = require("babel-types");
const generator = require("../core/generator");

const { isNumber } = require("../core/type-checks");
const { isNumber, isString, isBoolean } = require("../core/type-checks");
const { callGlobal } = require("../helpers");

const typeCheckInterfaces = {
Integer: isNumber,
double: isNumber
Double: isNumber,
String: isString,
boolean: isBoolean
};

const contentSanitizersForFunction = {
scrollInDirection: {
argumentName: "direction",
newType: "String",
name: "sanitize_android_direction",
value: callGlobal("sanitize_android_direction")
},
swipeInDirection: {
argumentName: "direction",
newType: "String",
name: "sanitize_android_direction",
value: callGlobal("sanitize_android_direction")
},
scrollToEdge: {
argumentName: "edge",
newType: "String",
name: "sanitize_android_edge",
value: callGlobal("sanitize_android_edge")
}
};

module.exports = generator({
typeCheckInterfaces,
supportedContentSanitizersMap: {},
supportedTypes: ["Integer", "int", "double"],
contentSanitizersForFunction,
contentSanitizersForType: {},
supportedTypes: ["Integer", "int", "double", "Double", "boolean"],
renameTypesMap: {
int: "Integer" // TODO: add test
int: "Integer", // TODO: add test
double: "Double"
},
classValue: ({ package: pkg, name }) => `${pkg}.${name}`
});
5 changes: 3 additions & 2 deletions generation/adapters/ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const typeCheckInterfaces = {
UIAccessibilityTraits: isArray
};

const supportedContentSanitizersMap = {
const contentSanitizersForType = {
GREYDirection: {
type: "NSInteger",
name: "sanitize_greyDirection",
Expand All @@ -48,7 +48,8 @@ const supportedContentSanitizersMap = {

module.exports = generator({
typeCheckInterfaces,
supportedContentSanitizersMap,
contentSanitizersForFunction: {},
contentSanitizersForType,
supportedTypes: [
"CGFloat",
"CGPoint",
Expand Down
Loading

0 comments on commit e803911

Please sign in to comment.