-
Notifications
You must be signed in to change notification settings - Fork 984
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
(iOS) Added Semver to version comparison checks. #695
Conversation
This should allow more varients on the semver spec to pass.
Missed out a .
if (ret !== 0) return ret; | ||
|
||
// if versions are equivalent, return 0; | ||
if (cleanV1 === cleanV2) { |
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.
semver.coerce
drops labels.
When cleanV1
and cleanV2
is equal, do you think it's worth checking the original version
variables and determine if one has a prerelease label, then return the appropriate integer?
e.g.
var version1 = "1.0.0";
var version2 = "1.0.0-beta.0";
var cleanV1 = semver.valid(semver.coerce(version1));
var cleanV2 = semver.valid(semver.coerce(version2));
if (cleanV1 === cleanV2) {
if (version1.indexOf('-') > -1 && version2.indexOf('-') === -1) {
// version1 is prerelease, favour version2 instead.
}
else if (version2.indexOf('-') > -1 && version1.indexOf('-') === -1) {
//version 2 is prelease, favour version 1
}
else {
return 0;
}
}
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.
Makes a lot of sense to do that actually. I've used .includes
as a formality to make the code easier to read, as the performance loss is minimal in comparison to indexOf
. However, if we need backwards compatibility with < IE 11 (As it's a CLI tool i'm assuming this isn't necessary), i'll go with the indexOf
instead!
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 can use .includes
, as long as it's supported in Node 6. If not, then this patch needs to wait until we drop support for node 6, which will likely come in next major release.
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.
Our JSDocs say "Compares two semver-notated version strings". So in my opinion, this whole function could (and should) be implemented as follows:
exports.compareVersions = semver.compare
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 didn't realize this but semver
actually does handling comparing prerelease labels, so my suggestion is just doing the work over again.
We also don't need to use coerce
.
semver.valid("1.0.0.0"); // null
semver.valid("1.0.0"): // "1.0.0"
semver.valid("1.0.0-beta.0"); // "1.0.0-beta.0"
Exporting semver.compare
directly will change what compareVersions
will return as an error, if it does receive an invalid semver, which will need to refactored in the unit tests but I think that's fine.
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.
Yes, the expectation in the unit test will have to be adapted for the new error
Based on @breautek's feedback.
Looks like there is a couple of tests failing. This is a unit test that you can find here: cordova-ios/tests/spec/unit/lib/check_reqs.spec.js Lines 59 to 74 in be68c9f
This particular error is stating that a function isn't resolving in a meaningful time, perhaps a This particular test is to test for completely invalid semver, and it's using
These are eslint errors, at the following line/column nunmbers there are extra whitespaces that need to be removed. |
Hi @breautek, Apologies for the lack of understanding, I haven't done much with unit testing before (something I probably need to look further into). Do I need to modify and push up a more appropriate unit test in order for the checks to pass? The ES lint errors will be my VS Code, i'll remove those and re-push the version.js file. Thanks! |
No problem, we all start somewhere. I've only began unit testing my code earlier this year, and it's an important piece of knowledge when working on larger projects. I'll walk you through this one, please keep notes ;) you can run Unit test primarily focus is to ensure that given a certain input, you expect a certain output. We use jasmine for unit testing, so you can find the documentation for jasmine at https://jasmine.github.io/pages/docs_home.html Use the appropriate API version, not all platforms/plugins use a consistent jasmine version sometimes. Generally speaking, a unit test tests a function, or something, and when given a certain set of inputs, it tests the output and expect it to be a certain value. e.g.: var add = function(a,b) {
return a + b;
}
it("should add two numbers", function() {
var result = add(2, 5);
expect(result).toBe(7);
}); This is a very simple example, the unit tests in cordova are obviously a bit more complex, but take your time, they'll have a pattern and should be pretty understandable. If a unit test fails, it generally means that function output or behaviour has changed. Perhaps it is throwing an error, or it's output is returning something completely different than expected (which could signal a breaking change). So ideally, the code should pass the tests without modifying the existing tests. However sometimes, modifying the tests is necessary, depending on the situation. In your case, the test is failing because it is using asynchronous function, and the
You're PR makes it so it can handle version string |
Updates unit tests for version checking to create a fail case on a non-semver version type.
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.
Good job 👍
I don't have easy access to give things a quick local test so, I'll like to add a couple more reviewers.
Thank you for an elaborate explanation on unit testing and how it works, I gave the Jasmine docs enough of a read to get this unit test working, but I will read more into them later and hopefully even implement them in my Cordova project that I'm working on at the moment, as they seem exceptionally useful. I'm out for the rest of the evening now but will keep monitoring if any additional reviewer has any feedback. 👍 |
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.
Thanks for taking the time to work on this @devleaf-matt, and thanks for providing guidance @breautek!
I think we should do this as simple as possible. See my comment about that.
if (ret !== 0) return ret; | ||
|
||
// if versions are equivalent, return 0; | ||
if (cleanV1 === cleanV2) { |
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.
Our JSDocs say "Compares two semver-notated version strings". So in my opinion, this whole function could (and should) be implemented as follows:
exports.compareVersions = semver.compare
Codecov Report
@@ Coverage Diff @@
## master #695 +/- ##
==========================================
- Coverage 74.24% 74.19% -0.06%
==========================================
Files 11 11
Lines 1833 1829 -4
==========================================
- Hits 1361 1357 -4
Misses 472 472
Continue to review full report at Codecov.
|
Based on @raphinesse's feedback
I didn't know the comparison method would do everything, I guess I overlooked the simple step haha! I've rewritten the unit test and method to work as per your feedback and got a clean |
OK, so apparently we haven't only been passing valid semver versions into that function. Surprise! 😒 We use it to check requirements of native dependencies like Xcode too. But the Xcode versions we pass into that function are not valid semver (e.g. So what I did is keep the original version if it is a valid semver and only coerce it if it isn't. That way, valid semver versions keep their pre-release identifers and we can still just use |
There's always a breaking exception haha! |
Everything passing now. Are you guys OK with my changes? |
Looking good to me. |
LGTM! |
let's go boiii |
this PR would be added to 5.0.2 version, right? |
@sanyashvets The fact that I added this to the |
I needed this fix for using a beta version if ios-deploy@beta on Catalina. So I just installed from master. Is there a good way to get notified when the fix is published on a release so I can update accordingly then? (Will you update this PR?) |
@ambroselittle We usually don't update PRs if they get released. You can watch our blog where we announce all releases (has an RSS feed too). Alternatively, it seems you can setup an E-Mail notification on new versions of In any case, this change will be in the next release. |
@raphinesse, that'll work. Thanks! |
Platforms affected
iOS
Motivation and Context
Fixes apache/cordova#165
Description
Adds semver NPM to package.json and updates the compareVersions method to allow semver based plugins to be read and compared.
Testing
Tested using runkit. https://runkit.com/devleaf-matt/cordova-version-comparison
Checklist
(platform)
if this change only applies to one platform (e.g.(android)
)