-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add generation for GREYInteraction #564
Conversation
138e75a
to
b206d1a
Compare
Is this still a WIP? |
Yes, but close to being finished |
I now rebased this PR. The original goal was more ambitious, but I think incremental steps forward are a nicer way to work together 🙈 I think this might help with #618 maybe only by us having a conversation about what these instance methods mean for us in detox 👍 |
b206d1a
to
b8b2f2e
Compare
@@ -333,6 +333,28 @@ describe("iOS generation", () => { | |||
}); | |||
}); | |||
|
|||
describe("instance methods", () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those tabs look awful in github :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They look great. Don’t switch to spaces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛒- i
generation/core/generator.js
Outdated
@@ -7,13 +7,14 @@ const fs = require("fs"); | |||
|
|||
const { methodNameToSnakeCase } = require("../helpers"); | |||
let globalFunctionUsage = {}; | |||
module.exports = function({ | |||
module.exports = function ({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please make it a bit more readable by creating a named function and exporting it, instead of exporting an anonymous one. Sorry for nitpicking, I just can't get used to this javascript jungle magic. :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, what would be a good name for a function that returns a code generator?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getGenerator ?
generation/core/generator.js
Outdated
@@ -81,13 +89,22 @@ module.exports = function({ | |||
} | |||
|
|||
function createMethod(classJson, json) { | |||
// For us this means that we don't set the class type, but let it be set from the outside | |||
// This is an assumption based on our current experience with EarlGrey, we might need to rework this at some point | |||
const isTranslucent = !json.static; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does translucent
mean in this context ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It means that we don't wrap the content as a class but add another argument called element
to the function list, which is taken as the element to work on. From the return statements perspective the translucent naming makes sense, but we could also call it isInstanceMethod
, might make more sense in this context
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I got it, can you elaborate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, pressed enter too early, does this make more sense?
generation/core/generator.js
Outdated
@@ -112,7 +129,7 @@ module.exports = function({ | |||
return json; | |||
} | |||
|
|||
function createMethodBody(classJson, json) { | |||
function createMethodBody(classJson, json, isTranslucent) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
try not to pass booleans in function params, it's very confusing.
https://martinfowler.com/bliki/FlagArgument.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead, just create two functions with clear naming
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved this part down into the functions
generation/core/generator.js
Outdated
t.identifier("type"), | ||
t.stringLiteral(addArgumentTypeSanitizer(arg)) | ||
), | ||
t.objectProperty( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prettier being prettier 🤷♂️
generation/core/generator.js
Outdated
@@ -215,7 +243,7 @@ module.exports = function({ | |||
: typeCheckCreator(json); | |||
} | |||
|
|||
return function(files) { | |||
return function (files) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, javascript voodoo. I'm too old for this magic. ;(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is going on here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The generator is returning a function to be invoked with files to generate the source code. The problem was that iOS and Android have a similar abstraction, so the easiest way to solve this without having to rewrite a lot was to wrap it into an anonymous functions with all the static values previously set being configurable and returning the old main logic as a function.
generation/package.json
Outdated
@@ -23,7 +23,6 @@ | |||
"jest": "^20.0.4", | |||
"lerna": "2.0.0-rc.4", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need lerna here, it can be safely deleted
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure 👍
Of course this needs to pass e2e before merge (from travis log)
|
a9f2559
to
eeba8fa
Compare
@rotemmiz I refactored the things you mentioned and got a working version up (let's see if CI agrees). I could only finish one of the calls, but left TODO items on the others. They "only" need a bit of fine tuning, but I thought this progress might already be helpful for you, especially in regards of #618 |
Awesome! Will we be able to generate non static invocations now ? Can't see an example in the new generated code, can you please point me to it ? |
this._call = invoke.call(element._call, 'performAction:', action._call); | ||
// TODO: move this.execute() here from the caller | ||
|
||
this._call = GreyInteraction.performAction(callThunk(element), callThunk(action)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rotemmiz this is currently the only successful invocation of an instance method, I need to find out why the others fail, but I guess it's a call side problem
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this resolved ?
eeba8fa
to
ba5df91
Compare
Hey @DanielMSchmidt , anything to be done on your side ? |
Not yet, trying to get to it next weekend |
ba5df91
to
4d35bcc
Compare
4d35bcc
to
8b6d9d9
Compare
@rotemmiz This is done now 👍 Let's get it into master ;) |
@rotemmiz ping, could you review this PR? 🙏 😇 |
t.blockStatement(createMethodBody(classJson, json)), | ||
false, | ||
json.static | ||
true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will this mean every method is static now ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then why passing this boolean anyway ? why not get rid of it ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a method of babel-types
, I could write a wrapper like createStaticClassMethod
, would that be more readable for you?
Every method is static, I choose to deal with instance methods a little different, I just let the target be passed in as the first argument. My point for this is that we have the class-like behavior more on the caller-side of this function and I don't want to duplicate it in any way. Also, the calls are more similar now than they would have been otherwise. If we want to change this somewhen I would propose we rethink this at a point in time when we get rid of these wrapper classes and access the generated code "directly", like in this proposal: #563
generation/core/generator.js
Outdated
@@ -189,10 +214,12 @@ module.exports = function({ | |||
t.objectProperty( | |||
t.identifier("target"), | |||
t.objectExpression([ | |||
t.objectProperty(t.identifier("type"), t.stringLiteral("Class")), | |||
t.objectProperty(t.identifier("type"), t.stringLiteral(json.static ? "Class" : "Invocation")), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, got it
generation/core/type-checks.js
Outdated
}); | ||
ARG: t.identifier(name) | ||
}); | ||
const isGreyAction = ({ name }) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about just defining functions instead of assigning functions to variables ?
function isGreyAction({name}) {
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea 👍
@rotemmiz Addressed your comments / replied. Thank you for taking the time to review <3 |
Fun fact: This PR moves us from 47 to 40 open |
💪 |
@DanielMSchmidt , I'm getting a weird behaviour when running ci.ios.sh locally. |
I now get it, I switched to EarlGrey 1.13, there is some breakage, not sure what. |
@LeoNatan, NS_REFINED_FOR_SWIFT macro was added to a few of EarlGrey's functions. |
Refined means there is a better alternative for Swift. It has no influence on ObjC. |
So right? |
Yes, of course. It's an attribute. |
This PR moves most iOS calls over to generated code (
detox_selectElementWithMatcher
is the only missing one and it's a bit of a special case.