Skip to content
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

Semantic version compare #524

Merged
merged 2 commits into from Apr 9, 2020
Merged
Changes from all commits
Commits
File filter
Filter file types
Jump to
Jump to file
Failed to load files.

Always

Just for now

@@ -91,6 +91,7 @@
"eslint-plugin-react": "^7.18.3",
"fs-extra": "^8.1.0",
"jest": "^25.1.0",
"jest-fetch-mock": "^3.0.3",
"jest-when": "^2.7.0",
"jsdoc": "^3.6.3",
"jsonfile": "^5.0.0",
@@ -1472,7 +1472,7 @@ function initializeVersioning() {
log('THIS IS AN UPGRADE');
conf.previous_version = globals.EXTENSION_VERSION;
const { version_history } = conf;
const earliestVersion = version_history[0].split('.');
const versions = [...version_history].sort(utils.semverCompare);
const prevVersion = PREVIOUS_EXTENSION_VERSION.split('.');
const currentVersion = globals.EXTENSION_VERSION.split('.');

@@ -1490,7 +1490,7 @@ function initializeVersioning() {
}

// Check if the earliest version is < 8.4.2
if (earliestVersion[0] <= 8 && earliestVersion[1] <= 4 && earliestVersion[2] < 2) {
if (versions.length && utils.semverCompare(versions[0], '8.4.2') === -1) {
globals.REQUIRE_LEGACY_OPT_IN = true;
}

@@ -617,3 +617,23 @@ export function injectNotifications(tab_id, importExport = false) {
export function isCliqzOffer(offer) {
return (offer && offer.origin === 'cliqz' && offer.type === 'offers' && offer.data);
}

/**
* Compare semantic version strings
* @param {string} a semantic version (x.x.x)
* @param {string} b semantic version (x.x.x)
* @return {int} (a > b) = 1, (a < b) = -1, (a == b) = 0
*/
export function semverCompare(a, b) {
const pa = a.split('.');
const pb = b.split('.');
for (let i = 0; i < 3; i++) {
const na = Number(pa[i]);
const nb = Number(pb[i]);
if (na > nb) return 1;
if (nb > na) return -1;
if (!Number.isNaN(na) && Number.isNaN(nb)) return 1;
if (Number.isNaN(na) && !Number.isNaN(nb)) return -1;
}
return 0;
}
@@ -32,7 +32,7 @@ chrome.runtime.getManifest.returns({
debug: true
});

// Create Mock for for Cliqz modules
// Create Mock for Cliqz modules
jest.mock('../src/classes/Cliqz', () => ({
modules: {
adblocker: {
@@ -11,70 +11,119 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/

import sinon from 'sinon';
import 'whatwg-fetch';
import { getJson, defineLazyProperty } from '../../src/utils/utils';
import { enableFetchMocks } from 'jest-fetch-mock'
import { getJson, defineLazyProperty, semverCompare } from '../../src/utils/utils';

describe('tests for getJson()', () => {
// Setup getJson() by initializing fetch()
beforeEach(() => {
sinon.stub(global, 'fetch');
});

// Reset fetch()
afterEach(() => {
global.fetch.restore();
});
// Mock fetch calls
enableFetchMocks()

// Helper function to fake XHR requests
function setFetchStubResponse (responseCode, responseData) {
const res = new global.Response(responseData, {
describe('tests for getJson()', () => {
// Helper function to fake Fetch response
function mockFetchResponse (responseCode, responseData) {
fetch.mockReturnValue(Promise.resolve(new Response(responseData, {
status: responseCode,
headers: {
'Content-type': 'application/json'
}
});
global.fetch.returns(Promise.resolve(res));
})));
}

// Tests for getJson()
test('returns a 200 response', () => {
setFetchStubResponse(200, JSON.stringify({ hello: 'world' }));
return expect(getJson('testurl')).resolves.toEqual({ hello: 'world' });
mockFetchResponse(200, JSON.stringify({ hello: 'world' }));
expect(getJson('https://www.ghostery.com/')).resolves.toEqual({ hello: 'world' });
});

test('returns a 404 response', () => {
setFetchStubResponse(404, 'Not Found');
return expect(getJson('testurl')).rejects.toThrow(/404/);
mockFetchResponse(404, 'Not Found');
expect(getJson('https://www.ghostery.com/')).rejects.toThrow(/404/);
});
});

describe('tests for defineLazyProperty()', () => {
let o = {},
expensiveComputation = sinon.spy(() => 'hello'),
shouldNeverGetCalled = sinon.spy(() => 'hello again');
const testObject = {
expensiveComputation() {
return 'hello';
},
shouldNeverGetCalled() {
return 'hello again';
}
};
const expensiveSpy = jest.spyOn(testObject, 'expensiveComputation');
const neverCalledSpy = jest.spyOn(testObject, 'shouldNeverGetCalled');

// Tests for defineLazyProperty()
test('property function is lazy', () => {
defineLazyProperty(o, 'lazy', expensiveComputation);
return expect(expensiveComputation.callCount).toBe(0);
defineLazyProperty(testObject, 'lazy', testObject.expensiveComputation);
expect(expensiveSpy).not.toHaveBeenCalled();
});

test('property function is defined', () => expect(o.lazy).toBe('hello'));
test('property function was called', () => expect(expensiveComputation.callCount).toBe(1));
test('property function is defined', () => expect(testObject.lazy).toBe('hello'));
test('property function was called', () => expect(expensiveSpy).toHaveBeenCalledTimes(1));

test('property function is still defined', () => expect(o.lazy).toBe('hello'));
test('repeated access do not call property function again', () => expect(expensiveComputation.callCount).toBe(1));
test('property function is still defined', () => expect(testObject.lazy).toBe('hello'));
test('repeated access do not call property function again', () => expect(expensiveSpy).toHaveBeenCalledTimes(1));

test('reassignment works', () => {
o.lazy = 'something else';
expect(o.lazy).toBe('something else');
testObject.lazy = 'something else';
expect(testObject.lazy).toBe('something else');
});

test('reassignment before access works', () => {
defineLazyProperty(o, 'lazy2', shouldNeverGetCalled);
o.lazy2 = 'nope';
return expect(o.lazy2).toBe('nope');
defineLazyProperty(testObject, 'lazy2', testObject.shouldNeverGetCalled);
testObject.lazy2 = 'nope';
expect(testObject.lazy2).toBe('nope');
});
test('property function is still lazy', () => expect(neverCalledSpy).not.toHaveBeenCalled());
});

describe('tests for semverCompare()', () => {
const versions = [
'1.2.1',
'3.12.6',
'3.2.0',
'1.4.11',
'0.5.7',
'8.1.3',
'2.1.1',
'11.4.1',
'10.7.4',
];

test('Sort version history', () => {
expect(versions.sort(semverCompare)).toEqual([
'0.5.7',
'1.2.1',
'1.4.11',
'2.1.1',
'3.2.0',
'3.12.6',
'8.1.3',
'10.7.4',
'11.4.1'
]);
});

test('Version comparisons', () => {
// Less Than
expect(semverCompare("7.7.10", "8.7.10")).toBe(-1);
expect(semverCompare("8.6.10", "8.7.10")).toBe(-1);
expect(semverCompare("8.7.1", "8.7.10")).toBe(-1);
expect(semverCompare("7.100.100", "8.7.10")).toBe(-1);
expect(semverCompare("8.3.3", "8.4.2")).toBe(-1);
expect(semverCompare("8.7", "8.7.0")).toBe(-1);
expect(semverCompare("8.7", "8.8.0")).toBe(-1);

// Greater Than
expect(semverCompare("8.7.10", "7.7.10")).toBe(1);
expect(semverCompare("8.7.10", "8.6.10")).toBe(1);
expect(semverCompare("8.7.10", "8.7.1")).toBe(1);
expect(semverCompare("8.7.10", "7.100.100")).toBe(1);
expect(semverCompare("8.4.2", "8.3.3")).toBe(1);
expect(semverCompare("8.7.0", "8.7")).toBe(1);
expect(semverCompare("8.8.0", "8.7")).toBe(1);

// Equal To
expect(semverCompare("8.7.10", "8.7.10")).toBe(0);
expect(semverCompare("8.7", "8.7")).toBe(0);
});
test('property function is still lazy', () => expect(shouldNeverGetCalled.callCount).toBe(0));
});
@@ -29,6 +29,38 @@ if [ ! -d $CLIQZ_SOURCE_DIR ]; then
unzip $CLIQZ_SOURCE_ZIP
fi

#### REQUIREMENTS ####
# Check for yarn
if ! type yarn > /dev/null; then
echo "Please install yarn: https://yarnpkg.com/lang/en/docs/install/"
exit 1
fi

# Check for jq
if ! type jq > /dev/null; then
echo "Please install jq: https://stedolan.github.io/jq/download/"
exit 1
fi

# Source nvm.sh
if [[ -f /usr/local/opt/nvm/nvm.sh ]]; then
# Homebrew
source /usr/local/opt/nvm/nvm.sh
else
# Default dir
source ${NVM_DIR}/nvm.sh
fi

# Check for nvm
if ! command -v nvm | grep -q 'nvm'; then
echo "Please install nvm: https://github.com/nvm-sh/nvm"
exit 1
fi

# Set node version
nvm install lts/dubnium
nvm use

#### BROWSER CORE ####
cd $CLIQZ_SOURCE_DIR

@@ -60,43 +92,12 @@ BUILD_DIR=build
ZIP_FILE="$BUILD_DIR/ghostery-extension-v$VERSION.zip"
TMP_FILE=$(mktemp)

# Check for yarn
if ! type yarn > /dev/null; then
echo "Please install yarn: https://yarnpkg.com/lang/en/docs/install/"
exit 1
fi

# Check for jq
if ! type jq > /dev/null; then
echo "Please install jq: https://stedolan.github.io/jq/download/"
exit 1
fi

# Source nvm.sh
if [[ -f /usr/local/opt/nvm/nvm.sh ]]; then
# Homebrew
source /usr/local/opt/nvm/nvm.sh
else
# Default dir
source ${NVM_DIR}/nvm.sh
fi

# Check for nvm
if ! command -v nvm | grep -q 'nvm'; then
echo "Please install nvm: https://github.com/nvm-sh/nvm"
exit 1
fi

# Clean any previous builds
rm -rf build

# Clean all the exiting node_modules for a more reproducible build
rm -rf node_modules

# Set node version
nvm install lts/dubnium
nvm use

# Install local npm packages
yarn install --frozen-lockfile

@@ -109,10 +110,10 @@ cat ${TMP_FILE} > $VERSION_FILE # copy into manifest.json
rm -f ${TMP_FILE}

# Download databases
curl "https://cdn.ghostery.com/update/v3/bugs" -o $DB_DIR/bugs.json --compress --fail
curl "https://cdn.ghostery.com/update/click2play" -o $DB_DIR/click2play.json --compress --fail
curl "https://cdn.ghostery.com/update/compatibility" -o $DB_DIR/compatibility.json --compress --fail
curl "https://cdn.ghostery.com/update/surrogates" -o $DB_DIR/surrogates.json --compress --fail
curl "https://cdn.ghostery.com/update/v3/bugs" -o $DB_DIR/bugs.json --compressed --fail
curl "https://cdn.ghostery.com/update/click2play" -o $DB_DIR/click2play.json --compressed --fail
curl "https://cdn.ghostery.com/update/compatibility" -o $DB_DIR/compatibility.json --compressed --fail
curl "https://cdn.ghostery.com/update/surrogates" -o $DB_DIR/surrogates.json --compressed --fail

# Zip final build files
echo "Zipping to $(pwd)/$BUILD_DIR/"
@@ -2166,6 +2166,14 @@ cross-env@^7.0.0:
dependencies:
cross-spawn "^7.0.1"

cross-fetch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.0.4.tgz#7bef7020207e684a7638ef5f2f698e24d9eb283c"
integrity sha512-MSHgpjQqgbT/94D4CyADeNoYh52zMkCX4pcJvPP5WqPsLFMKjr2TCMg381ox5qI0ii2dPwaLx/00477knXqXVw==
dependencies:
node-fetch "2.6.0"
whatwg-fetch "3.0.0"

cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5:
version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
@@ -4799,6 +4807,14 @@ jest-environment-node@^25.1.0:
jest-mock "^25.1.0"
jest-util "^25.1.0"

jest-fetch-mock@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/jest-fetch-mock/-/jest-fetch-mock-3.0.3.tgz#31749c456ae27b8919d69824f1c2bd85fe0a1f3b"
integrity sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw==
dependencies:
cross-fetch "^3.0.4"
promise-polyfill "^8.1.3"

jest-get-type@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e"
@@ -5946,6 +5962,11 @@ nise@^3.0.1:
lolex "^5.0.1"
path-to-regexp "^1.7.0"

node-fetch@2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==

node-fetch@^1.0.1, node-fetch@^1.7.1:
version "1.7.3"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
@@ -6768,6 +6789,11 @@ promise-inflight@^1.0.1:
resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=

promise-polyfill@^8.1.3:
version "8.1.3"
resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.1.3.tgz#8c99b3cf53f3a91c68226ffde7bde81d7f904116"
integrity sha512-MG5r82wBzh7pSKDRa9y+vllNHz3e3d4CNj1PQE4BQYxLme0gKYYBm9YENq+UkEikyZ0XbiGWxYlVw3Rl9O/U8g==

promise@^7.1.1:
version "7.3.1"
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
@@ -9103,7 +9129,7 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.5:
dependencies:
iconv-lite "0.4.24"

whatwg-fetch@>=0.10.0, whatwg-fetch@^3.0.0:
whatwg-fetch@3.0.0, whatwg-fetch@>=0.10.0, whatwg-fetch@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb"
integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==
ProTip! Use n and p to navigate between commits in a pull request.