-
-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Reduce unnecessary condition determination #4197
Conversation
@@ -84,8 +84,7 @@ function createRunnerFunction(runStr, ifStr1, ifStr2, ifStr3, arg1, arg2) { | |||
return function(event, callback) { | |||
if (event === ifStr1) { | |||
callback(); | |||
} | |||
if (event === ifStr2) { | |||
} else if (event === ifStr2) { |
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.
These changes don't make sense to me.
The function signature shows three different parameters (ifstr1
, ifstr2
, ifstr3
). If this design was chosen intentionally, then your changes are incorrect.
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.
@juergba
Thank you very much for reviewing my PR.
With your advice, I reviewed the intentions of the original code writer.
-
I checked out the history of
helpers.js
.According to Refactor Reporter tests #3272,
helpers.js
was created in the process of refactoring the duplicated code of the test files intest/reporters
.createRunnerFunction
inhelpers.js
is composed entirely ofswitch-case
statements. Depending on whatrunStr
is, the functions to return are defined one by one. This means thatcreateRunnerFunction
is not meant to be reused, just a collection of similarly structured code for refactoring purposes.So I could conclude: the code I modified will not affect what I didn't expect, and it will work independently of each other. This is supported by the fact that when I ran the test with my code, it all passed.
-
Nevertheless, as you said, I thought more about the possibilities of the intended design.
Compare the two cases below.
(1) If only using
if
separately in successionif (event === ifStr1) { callback(a); } if (event === ifStr2) { callback(b); }
(2) If using
if else
if (event === ifStr1) { callback(a); } else if (event === ifStr2) { callback(b); }
Since the
event
does not change during this process, in most cases the codes mentioned above will do the same. It works differently only in one case thatifStr1
andifStr2
are same. WhenifStr1
andifStr2
are same to each other,(1)
executes bothcallback(a);
andcallback(b);
while(2)
only executescallback(a);
.If the original author had intentionally designed something like this, it was probably because there were some situations where both
callback(a);
andcallback(b);
have to run, that is,ifStr1
andifStr2
are equal.I've looked through every case using the
createMockRunner
intest/reporters/*.spec.js
to see if those situations really exist.In most cases, the logic inside the
case
statement was just forevent === ifStr1
.Only five
case
s in thehelpers.js
deal withevent === ifStr2
, so I've looked at those five:- case 'start test'
- case 'suite suite end'
- case 'pass end'
- case 'test end fail'
- case 'fail end pass'.
When I checked the use cases of
createMockRunner
for these five mentioned above, I found 17 times as below.case 'start test'
// 1 time var runner = createMockRunner( 'start test', EVENT_RUN_BEGIN, EVENT_TEST_BEGIN, null, test );
// 2 times var runner = createMockRunner( 'start test', EVENT_TEST_END, EVENT_TEST_PENDING, null, test );
// 2 times var runner = createMockRunner( 'start test', EVENT_TEST_END, EVENT_TEST_PASS, null, test );
case 'suite suite end'
// 1 time var runner = createMockRunner( 'suite suite end', EVENT_SUITE_BEGIN, EVENT_SUITE_END, EVENT_RUN_END, expectedSuite );
case 'pass end'
// 1 time var runner = createMockRunner( 'pass end', EVENT_TEST_PASS, EVENT_RUN_END, null, expectedTest );
case 'test end fail'
// 8 times var runner = createMockRunner( 'test end fail', EVENT_TEST_END, EVENT_TEST_FAIL, null, test, error );
case 'fail end pass'
// 2 times var runner = createMockRunner( 'fail end pass', EVENT_TEST_FAIL, EVENT_RUN_END, EVENT_TEST_PASS, test );
But as you can see, the case that
ifStr1
is the same asifStr2
never appeared.Therefore, it can be assumed that the original author did not expect anything by writing
if
separately. That's why I think the original author didn't design it intentionally.
Now, you know that changing if, if
to if, if else
is no problem.
Once event === ifStr1
is satisfied, you don't have to check anymore for event === ifStr2
or event === ifStr3
. By modifying it to if else
, you can expect some efficiency.
- If a match was found before the third
if
, then at least the thirdif
statement will be skipped. - If a match was found in first, it will skip both second and third statements.
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.
@HyunSangHan I can see you have put quite an effort in this PR, but I'm not convinced of its correctness.
- following your argumentation,
createRunnerFunction
's signature has been declared without intention and is therefore just a bad design. But with your changes - stopping at half way - the result is IMO even worse and more confusing. - the last few months I made some changes to the uncaught exception handling. There are cases were
ifStr1 === ifStr2
, eg. the same test failing twice. So we have real szenarios where this signature may make sense. If our CI tests don't cover those szenarios, doesn't mean we should change this factory function.
@HyunSangHan I'm closing this PR, as explained in my review. |
@juergba |
Description of the Change
In
test/reporters/helpers.js
,if
toelse if
for code efficiency.||
for code readability.Benefits
event
isifStr1
, we no longer need to determine ifevent
isifStr2
orifStr3
. But whenhelpers.js
is executed, it goes through all ofif
statements, because they exist independently of each other. By usingelse if
, once the preceding callback function is executed, the execution of the latter callback function will be passed unconditionally.Possible Drawbacks
I think it will not make any side effects.