Skip to content

Commit

Permalink
move DetoxAssertion to generated code
Browse files Browse the repository at this point in the history
Closes #726
  • Loading branch information
Daniel Schmidt committed Aug 8, 2018
1 parent c81147c commit bd95938
Show file tree
Hide file tree
Showing 6 changed files with 266 additions and 56 deletions.
128 changes: 128 additions & 0 deletions detox/src/android/espressoapi/DetoxAssertion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/**
This code is generated.
For more information see generation/README.md.
*/


function sanitize_matcher(matcher) {
const originalMatcher = typeof matcher._call === 'function' ? matcher._call() : matcher._call;
return originalMatcher.type ? originalMatcher.value : originalMatcher;
}
class DetoxAssertion {
static assertMatcher(i, m) {
if (typeof m !== 'object' || typeof m.constructor !== 'function' || m.constructor.name.indexOf('Matcher') === -1) {
const isObject = typeof m === 'object';
const additionalErrorInfo = isObject ? typeof m.constructor === 'object' ? 'the constructor is no object' : 'it has a wrong class name: "' + m.constructor.name + '"' : 'it is no object';
throw new Error('m should be an instance of Matcher, got "' + m + '", it appears that ' + additionalErrorInfo);
}

return {
target: {
type: "Class",
value: "com.wix.detox.espresso.DetoxAssertion"
},
method: "assertMatcher",
args: [{
type: "ViewInteraction",
value: i
}, {
type: "Invocation",
value: sanitize_matcher(m)
}]
};
}

static assertNotVisible(i) {
return {
target: {
type: "Class",
value: "com.wix.detox.espresso.DetoxAssertion"
},
method: "assertNotVisible",
args: [{
type: "ViewInteraction",
value: i
}]
};
}

static assertNotExists(i) {
return {
target: {
type: "Class",
value: "com.wix.detox.espresso.DetoxAssertion"
},
method: "assertNotExists",
args: [{
type: "ViewInteraction",
value: i
}]
};
}

static waitForAssertMatcher(i, m, timeoutSeconds) {
if (typeof m !== 'object' || typeof m.constructor !== 'function' || m.constructor.name.indexOf('Matcher') === -1) {
const isObject = typeof m === 'object';
const additionalErrorInfo = isObject ? typeof m.constructor === 'object' ? 'the constructor is no object' : 'it has a wrong class name: "' + m.constructor.name + '"' : 'it is no object';
throw new Error('m should be an instance of Matcher, got "' + m + '", it appears that ' + additionalErrorInfo);
}

if (typeof timeoutSeconds !== "number") throw new Error("timeoutSeconds should be a number, but got " + (timeoutSeconds + (" (" + (typeof timeoutSeconds + ")"))));
return {
target: {
type: "Class",
value: "com.wix.detox.espresso.DetoxAssertion"
},
method: "waitForAssertMatcher",
args: [{
type: "ViewInteraction",
value: i
}, {
type: "Invocation",
value: sanitize_matcher(m)
}, {
type: "Double",
value: timeoutSeconds
}]
};
}

static waitForAssertMatcherWithSearchAction(i, m, searchAction, searchMatcher) {
if (typeof m !== 'object' || typeof m.constructor !== 'function' || m.constructor.name.indexOf('Matcher') === -1) {
const isObject = typeof m === 'object';
const additionalErrorInfo = isObject ? typeof m.constructor === 'object' ? 'the constructor is no object' : 'it has a wrong class name: "' + m.constructor.name + '"' : 'it is no object';
throw new Error('m should be an instance of Matcher, got "' + m + '", it appears that ' + additionalErrorInfo);
}

if (typeof searchMatcher !== 'object' || typeof searchMatcher.constructor !== 'function' || searchMatcher.constructor.name.indexOf('Matcher') === -1) {
const isObject = typeof searchMatcher === 'object';
const additionalErrorInfo = isObject ? typeof searchMatcher.constructor === 'object' ? 'the constructor is no object' : 'it has a wrong class name: "' + searchMatcher.constructor.name + '"' : 'it is no object';
throw new Error('searchMatcher should be an instance of Matcher, got "' + searchMatcher + '", it appears that ' + additionalErrorInfo);
}

return {
target: {
type: "Class",
value: "com.wix.detox.espresso.DetoxAssertion"
},
method: "waitForAssertMatcherWithSearchAction",
args: [{
type: "ViewInteraction",
value: i
}, {
type: "Invocation",
value: sanitize_matcher(m)
}, {
type: "ViewAction",
value: searchAction
}, {
type: "Invocation",
value: sanitize_matcher(searchMatcher)
}]
};
}

}

module.exports = DetoxAssertion;
17 changes: 17 additions & 0 deletions detox/src/android/espressoapi/EspressoDetox.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@


class EspressoDetox {
static perform(interaction, action) {
return {
target: {
type: "Class",
value: "com.wix.detox.espresso.EspressoDetox"
},
method: "perform",
args: [{
type: "ViewInteraction",
value: interaction
}, {
type: "ViewAction",
value: action
}]
};
}

static changeOrientation(orientation) {
if (typeof orientation !== "number") throw new Error("orientation should be a number, but got " + (orientation + (" (" + (typeof orientation + ")"))));
return {
Expand Down
60 changes: 59 additions & 1 deletion detox/src/android/espressoapi/ViewActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
*/



function sanitize_matcher(matcher) {
const originalMatcher = typeof matcher._call === 'function' ? matcher._call() : matcher._call;
return originalMatcher.type ? originalMatcher.value : originalMatcher;
}
class ViewActions {
static clearGlobalAssertions() {
return {
Expand All @@ -18,6 +21,20 @@ class ViewActions {
};
}

static actionWithAssertions(viewAction) {
return {
target: {
type: "Class",
value: "android.support.test.espresso.action.ViewActions"
},
method: "actionWithAssertions",
args: [{
type: "ViewAction",
value: viewAction
}]
};
}

static clearText() {
return {
target: {
Expand All @@ -40,6 +57,20 @@ class ViewActions {
};
}

static click(rollbackAction) {
return {
target: {
type: "Class",
value: "android.support.test.espresso.action.ViewActions"
},
method: "click",
args: [{
type: "ViewAction",
value: rollbackAction
}]
};
}

static swipeLeft() {
return {
target: {
Expand Down Expand Up @@ -236,6 +267,33 @@ class ViewActions {
};
}

static repeatedlyUntil(action, desiredStateMatcher, maxAttempts) {
if (typeof desiredStateMatcher !== 'object' || typeof desiredStateMatcher.constructor !== 'function' || desiredStateMatcher.constructor.name.indexOf('Matcher') === -1) {
const isObject = typeof desiredStateMatcher === 'object';
const additionalErrorInfo = isObject ? typeof desiredStateMatcher.constructor === 'object' ? 'the constructor is no object' : 'it has a wrong class name: "' + desiredStateMatcher.constructor.name + '"' : 'it is no object';
throw new Error('desiredStateMatcher should be an instance of Matcher, got "' + desiredStateMatcher + '", it appears that ' + additionalErrorInfo);
}

if (typeof maxAttempts !== "number") throw new Error("maxAttempts should be a number, but got " + (maxAttempts + (" (" + (typeof maxAttempts + ")"))));
return {
target: {
type: "Class",
value: "android.support.test.espresso.action.ViewActions"
},
method: "repeatedlyUntil",
args: [{
type: "ViewAction",
value: action
}, {
type: "Invocation",
value: sanitize_matcher(desiredStateMatcher)
}, {
type: "Integer",
value: maxAttempts
}]
};
}

}

module.exports = ViewActions;
18 changes: 12 additions & 6 deletions detox/src/android/expect.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const invoke = require('../invoke');
const matchers = require('./matcher');
const DetoxActionApi = require('./espressoapi/DetoxAction');
const ViewActionsApi = require('./espressoapi/ViewActions');
const DetoxAssertionApi = require('./espressoapi/DetoxAssertion');
const Matcher = matchers.Matcher;
const LabelMatcher = matchers.LabelMatcher;
const IdMatcher = matchers.IdMatcher;
Expand Down Expand Up @@ -121,7 +122,7 @@ class ActionInteraction extends Interaction {
class MatcherAssertionInteraction extends Interaction {
constructor(element, matcher) {
super();
this._call = invoke.call(invoke.Android.Class(DetoxAssertion), 'assertMatcher', element._call, matcher._call);
this._call = invoke.callDirectly(DetoxAssertionApi.assertMatcher(element._call,matcher._call));
// TODO: move this.execute() here from the caller
}
}
Expand All @@ -139,7 +140,7 @@ class WaitForInteraction extends Interaction {
if (typeof timeout !== 'number') throw new Error(`WaitForInteraction withTimeout argument must be a number, got ${typeof timeout}`);
if (timeout < 0) throw new Error('timeout must be larger than 0');

this._call = invoke.call(invoke.Android.Class(DetoxAssertion), 'waitForAssertMatcher', this._element._call, this._originalMatcher._call, invoke.Android.Double(timeout/1000));
this._call = invoke.callDirectly(DetoxAssertionApi.waitForAssertMatcher(this._element._call, this._originalMatcher._call, timeout/1000))
await this.execute();
}

Expand All @@ -160,8 +161,13 @@ class WaitForActionInteraction extends Interaction {
}
async _execute(searchAction) {
//if (!searchAction instanceof Action) throw new Error(`WaitForActionInteraction _execute argument must be a valid Action, got ${typeof searchAction}`);
this._call = invoke.call(invoke.Android.Class(DetoxAssertion), 'waitForAssertMatcherWithSearchAction',
this._element._call, this._originalMatcher._call, searchAction._call, this._searchMatcher._call);

this._call = invoke.callDirectly(DetoxAssertionApi.waitForAssertMatcherWithSearchAction(
this._element._call,
this._originalMatcher._call,
searchAction._call,
this._searchMatcher._call
));
await this.execute();
}
async scroll(amount, direction = 'down') {
Expand Down Expand Up @@ -234,13 +240,13 @@ class ExpectElement extends Expect {
return await new MatcherAssertionInteraction(this._element, new VisibleMatcher()).execute();
}
async toBeNotVisible() {
return await invocationManager.execute(invoke.call(invoke.Android.Class(DetoxAssertion), 'assertNotVisible', this._element._call));
return await invocationManager.execute(invoke.callDirectly(DetoxAssertionApi.assertNotVisible(this._element._call)));
}
async toExist() {
return await new MatcherAssertionInteraction(this._element, new ExistsMatcher()).execute();
}
async toNotExist() {
return await invocationManager.execute(invoke.call(invoke.Android.Class(DetoxAssertion), 'assertNotExists', this._element._call));
return await invocationManager.execute(invoke.callDirectly(DetoxAssertionApi.assertNotExists(this._element._call)));
}
async toHaveText(value) {
return await new MatcherAssertionInteraction(this._element, new TextMatcher(value)).execute();
Expand Down
25 changes: 19 additions & 6 deletions generation/adapters/android.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ const t = require('babel-types');
const generator = require('../core/generator');
const { callGlobal } = require('../helpers');

const { isNumber, isString, isBoolean, isOfClass, isArray } = require('../core/type-checks');
const { isNumber, isString, isBoolean, isOfClass, isArray, isDefined } = require('../core/type-checks');

const typeCheckInterfaces = {
Integer: isNumber,
'ArrayList<String>': isArray,
'Matcher<View>': isOfClass('Matcher'),
boolean: isBoolean,
Double: isNumber,
Integer: isNumber,
String: isString,
boolean: isBoolean,
'Matcher<View>': isOfClass('Matcher'),
'ArrayList<String>': isArray
ViewAction: isDefined,
ViewInteraction: isDefined
};

const contentSanitizersForFunction = {
Expand Down Expand Up @@ -51,7 +53,18 @@ module.exports = generator({
typeCheckInterfaces,
contentSanitizersForFunction,
contentSanitizersForType,
supportedTypes: ['Integer', 'int', 'double', 'Double', 'boolean', 'String', 'Matcher<View>', 'ArrayList<String>'],
supportedTypes: [
'ArrayList<String>',
'boolean',
'double',
'Double',
'int',
'Integer',
'Matcher<View>',
'String',
'ViewAction',
'ViewInteraction'
],
renameTypesMap: {
int: 'Integer', // TODO: add test
double: 'Double'
Expand Down
Loading

0 comments on commit bd95938

Please sign in to comment.