mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Merge branch 'release-2.5' into feature/passwordless-ui
This commit is contained in:
@@ -8,7 +8,6 @@ cache:
|
||||
- ".meteor"
|
||||
- ".babel-cache"
|
||||
script:
|
||||
- export TEST_PACKAGES_EXCLUDE="less"
|
||||
- export phantom=false
|
||||
# to skip Downloading Chromium on every run
|
||||
# https://github.com/dfernandez79/puppeteer/blob/main/README.md#q-chromium-gets-downloaded-on-every-npm-ci-run-how-can-i-cache-the-download
|
||||
|
||||
47
History.md
47
History.md
@@ -54,6 +54,7 @@
|
||||
- Update `cordova-plugin-meteor-webapp` to v2
|
||||
- Removed dependency on `cordova-plugin-whitelist` as it is now included in core
|
||||
- Cordova Meteor plugin is now using AndroidX
|
||||
- Added new settings option `Meteor.settings.packages.webapp.alwaysReturnContent` that will always return content on requests like `POST`, essentially enabling behavior prior to Meteor 2.3.1.
|
||||
|
||||
#### Independent Releases
|
||||
|
||||
@@ -75,6 +76,16 @@
|
||||
* `ecmascript-runtime-client@0.12.1`
|
||||
- Revert `core-js` to v3.15.2 due to issues in legacy build with arrays, [see issue for more details](https://github.com/meteor/meteor/issues/11662)
|
||||
|
||||
* `modern-browsers@0.1.7`
|
||||
- Added `firefoxMobile` as an alias for `firefox`
|
||||
|
||||
## v2.4.1, 2021-10-12
|
||||
|
||||
#### Meteor Version Release
|
||||
|
||||
* `meteor-tool@2.4.1`
|
||||
- Patch to make 2.4.1 compatible with Push to Deploy feature in Galaxy (Meteor Cloud)
|
||||
|
||||
## v2.4, 2021-09-15
|
||||
|
||||
#### Highlights
|
||||
@@ -187,6 +198,13 @@
|
||||
|
||||
* `callback-hook@1.4.0`
|
||||
- Added `forEach` iterator to be more in-line with the ES use for iterations. `each` is now deprecated, but will remain supported.
|
||||
|
||||
## v2.3.7, 2021-10-12
|
||||
|
||||
#### Meteor Version Release
|
||||
|
||||
* `meteor-tool@2.3.7`
|
||||
- Patch to make 2.3.7 compatible with Push to Deploy feature in Galaxy (Meteor Cloud)
|
||||
|
||||
## v2.3.6, 2021-09-02
|
||||
|
||||
@@ -541,6 +559,13 @@
|
||||
|
||||
* `react-fast-refresh@0.1.1`
|
||||
- Fixed the package to work in IE11
|
||||
|
||||
## v2.2.4, 2021-10-12
|
||||
|
||||
#### Meteor Version Release
|
||||
|
||||
* `meteor-tool@2.2.4`
|
||||
- Patch to make 2.2.4 compatible with Push to Deploy feature in Galaxy (Meteor Cloud)
|
||||
|
||||
## v2.2.3, 2021-08-12
|
||||
|
||||
@@ -643,6 +668,14 @@
|
||||
* `webapp@1.10.1`
|
||||
- Fix for UNIX sockets with node cluster. [#11369](https://github.com/meteor/meteor/pull/11369)
|
||||
|
||||
|
||||
## v2.1.2, 2021-10-12
|
||||
|
||||
#### Meteor Version Release
|
||||
|
||||
* `meteor-tool@2.1.2`
|
||||
- Patch to make 2.1.2 compatible with Push to Deploy feature in Galaxy (Meteor Cloud)
|
||||
|
||||
## v2.1.1, 2021-04-06
|
||||
|
||||
### Changes
|
||||
@@ -687,6 +720,13 @@
|
||||
|
||||
* N/A
|
||||
|
||||
## v2.0.1, 2021-10-12
|
||||
|
||||
#### Meteor Version Release
|
||||
|
||||
* `meteor-tool@2.0.1`
|
||||
- Patch to make 2.0.1 compatible with Push to Deploy feature in Galaxy (Meteor Cloud)
|
||||
|
||||
## v2.0, 2021-01-20
|
||||
|
||||
### Changes
|
||||
@@ -753,6 +793,13 @@ Simple run `meteor update` in your app.
|
||||
|
||||
Great new features and no breaking changes (except one package deprecation). You can always check our [Roadmap](./Roadmap.md) to understand what is next.
|
||||
|
||||
## v1.12.2, 2021-10-12
|
||||
|
||||
#### Meteor Version Release
|
||||
|
||||
* `meteor-tool@1.12.2`
|
||||
- Patch to make 1.12.2 compatible with Push to Deploy feature in Galaxy (Meteor Cloud)
|
||||
|
||||
## v1.12.1, 2021-01-06
|
||||
|
||||
### Breaking changes
|
||||
|
||||
@@ -249,7 +249,7 @@ Here is a list of the Babel transformers that are currently enabled:
|
||||
|
||||
The ECMAScript 2015 standard library has grown to include new APIs and
|
||||
data structures, some of which can be implemented ("polyfilled") using
|
||||
JavaScript that runs in all engines and browsers today. Here are three new
|
||||
JavaScript that runs in all engines and browsers today. Here are four new
|
||||
constructors that are guaranteed to be available when the `ecmascript`
|
||||
package is installed:
|
||||
|
||||
|
||||
@@ -40,4 +40,5 @@ Package.onTest(function(api) {
|
||||
api.addFiles('bare-test-file.js', ['client', 'server'], {
|
||||
bare: true,
|
||||
});
|
||||
api.addFiles('runtime-tests-client.js', ['client', 'web.browser.legacy']);
|
||||
});
|
||||
|
||||
22
packages/ecmascript/runtime-tests-client.js
Normal file
22
packages/ecmascript/runtime-tests-client.js
Normal file
@@ -0,0 +1,22 @@
|
||||
// Regression test for web.browser.legacy - see https://github.com/meteor/meteor/issues/11662
|
||||
Tinytest.add('ecmascript - runtime - NodeList spread', test => {
|
||||
const div = document.createElement('div');
|
||||
document.body.appendChild(div);
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const child = document.createElement('div');
|
||||
child.innerText = `child ${i}`;
|
||||
div.appendChild(child);
|
||||
}
|
||||
|
||||
try {
|
||||
test.equal(div.childNodes?.length, 5);
|
||||
const arr = [...div.childNodes];
|
||||
|
||||
arr.forEach((el, i) => {
|
||||
test.equal(el.innerText, `child ${i}`);
|
||||
});
|
||||
} finally {
|
||||
document.body.removeChild(div);
|
||||
}
|
||||
});
|
||||
@@ -1,28 +1,28 @@
|
||||
const isNode8OrLater = Meteor.isServer &&
|
||||
parseInt(process.versions.node) >= 8;
|
||||
const isNode8OrLater = Meteor.isServer && parseInt(process.versions.node) >= 8;
|
||||
|
||||
Tinytest.add("ecmascript - runtime - template literals", (test) => {
|
||||
Tinytest.add('ecmascript - runtime - template literals', test => {
|
||||
function dump(strings, ...expressions) {
|
||||
const copy = Object.create(null);
|
||||
Object.assign(copy, strings);
|
||||
copy.raw = strings.raw;
|
||||
return [copy, expressions];
|
||||
};
|
||||
}
|
||||
|
||||
const foo = "B";
|
||||
const foo = 'B';
|
||||
|
||||
test.equal(`\u0041${foo}C`, "ABC");
|
||||
test.equal(`\u0041${foo}C`, 'ABC');
|
||||
|
||||
test.equal(dump`\u0041${foo}C`, [{
|
||||
0: "A",
|
||||
1: "C",
|
||||
raw: ["\\u0041", "C"]
|
||||
}, [
|
||||
"B"
|
||||
]]);
|
||||
test.equal(dump`\u0041${foo}C`, [
|
||||
{
|
||||
0: 'A',
|
||||
1: 'C',
|
||||
raw: ['\\u0041', 'C'],
|
||||
},
|
||||
['B'],
|
||||
]);
|
||||
});
|
||||
|
||||
Tinytest.add("ecmascript - runtime - classes - basic", (test) => {
|
||||
Tinytest.add('ecmascript - runtime - classes - basic', test => {
|
||||
{
|
||||
class Foo {
|
||||
constructor(x) {
|
||||
@@ -35,7 +35,7 @@ Tinytest.add("ecmascript - runtime - classes - basic", (test) => {
|
||||
// Foo(); // called without `new`
|
||||
// });
|
||||
|
||||
test.equal((new Foo(3)).x, 3);
|
||||
test.equal(new Foo(3).x, 3);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -51,9 +51,9 @@ Tinytest.add("ecmascript - runtime - classes - basic", (test) => {
|
||||
// Foo(); // called without `new`
|
||||
// });
|
||||
|
||||
test.equal((new Foo(3)).x, 3);
|
||||
test.isTrue((new Foo(3)) instanceof Foo);
|
||||
test.isTrue((new Foo(3)) instanceof Bar);
|
||||
test.equal(new Foo(3).x, 3);
|
||||
test.isTrue(new Foo(3) instanceof Foo);
|
||||
test.isTrue(new Foo(3) instanceof Bar);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -68,11 +68,11 @@ Tinytest.add("ecmascript - runtime - classes - basic", (test) => {
|
||||
}
|
||||
|
||||
test.equal(Foo.staticMethod(), 'classy');
|
||||
test.equal((new Foo).prototypeMethod(), 'prototypical');
|
||||
test.equal(new Foo().prototypeMethod(), 'prototypical');
|
||||
}
|
||||
});
|
||||
|
||||
Tinytest.add("ecmascript - runtime - classes - use before declare", (test) => {
|
||||
Tinytest.add('ecmascript - runtime - classes - use before declare', test => {
|
||||
const x = function asdf() {};
|
||||
if (typeof asdf === 'function') {
|
||||
// We seem to be in IE 8, where function names leak into the enclosing
|
||||
@@ -88,9 +88,7 @@ Tinytest.add("ecmascript - runtime - classes - use before declare", (test) => {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Tinytest.add("ecmascript - runtime - classes - inheritance", (test) => {
|
||||
|
||||
Tinytest.add('ecmascript - runtime - classes - inheritance', test => {
|
||||
// uses `babelHelpers.inherits`
|
||||
{
|
||||
class Foo {
|
||||
@@ -98,7 +96,7 @@ Tinytest.add("ecmascript - runtime - classes - inheritance", (test) => {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Foo.static2 = function () {
|
||||
Foo.static2 = function() {
|
||||
return 2;
|
||||
};
|
||||
|
||||
@@ -128,12 +126,14 @@ Tinytest.add("ecmascript - runtime - classes - inheritance", (test) => {
|
||||
}
|
||||
});
|
||||
|
||||
Tinytest.add("ecmascript - runtime - classes - computed props", (test) => {
|
||||
Tinytest.add('ecmascript - runtime - classes - computed props', test => {
|
||||
{
|
||||
const frob = "inc";
|
||||
const frob = 'inc';
|
||||
|
||||
class Foo {
|
||||
static [frob](n) { return n+1; }
|
||||
static [frob](n) {
|
||||
return n + 1;
|
||||
}
|
||||
}
|
||||
|
||||
test.equal(Foo.inc(3), 4);
|
||||
@@ -145,35 +145,39 @@ if (Meteor.isServer) {
|
||||
// in classes on browsers that support them in the first place, and on
|
||||
// the server. (Technically they just need a working
|
||||
// Object.defineProperty, found in IE9+ and all modern environments.)
|
||||
Tinytest.add("ecmascript - runtime - classes - getters/setters", (test) => {
|
||||
Tinytest.add('ecmascript - runtime - classes - getters/setters', test => {
|
||||
// uses `babelHelpers.createClass`
|
||||
class Foo {
|
||||
get two() { return 1+1; }
|
||||
static get three() { return 1+1+1; }
|
||||
get two() {
|
||||
return 1 + 1;
|
||||
}
|
||||
static get three() {
|
||||
return 1 + 1 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
test.equal((new Foo).two, 2);
|
||||
test.equal(new Foo().two, 2);
|
||||
test.equal(Foo.three, 3);
|
||||
});
|
||||
}
|
||||
|
||||
export const testExport = "oyez";
|
||||
export const testExport = 'oyez';
|
||||
|
||||
Tinytest.add("ecmascript - runtime - classes - properties", (test) => {
|
||||
Tinytest.add('ecmascript - runtime - classes - properties', test => {
|
||||
class ClassWithProperties {
|
||||
property = ["prop", "rty"].join("e");
|
||||
property = ['prop', 'rty'].join('e');
|
||||
static staticProp = 1234;
|
||||
|
||||
check = (self) => {
|
||||
import { testExport as oyez } from "./runtime-tests.js";
|
||||
test.equal(oyez, "oyez");
|
||||
check = self => {
|
||||
import { testExport as oyez } from './runtime-tests.js';
|
||||
test.equal(oyez, 'oyez');
|
||||
test.isTrue(self === this);
|
||||
test.equal(this.property, "property");
|
||||
test.equal(this.property, 'property');
|
||||
};
|
||||
|
||||
method() {
|
||||
import { testExport as oyez } from "./runtime-tests.js";
|
||||
test.equal(oyez, "oyez");
|
||||
import { testExport as oyez } from './runtime-tests.js';
|
||||
test.equal(oyez, 'oyez');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,16 +193,16 @@ Tinytest.add("ecmascript - runtime - classes - properties", (test) => {
|
||||
cwp.method();
|
||||
});
|
||||
|
||||
Tinytest.add("ecmascript - runtime - block scope", (test) => {
|
||||
Tinytest.add('ecmascript - runtime - block scope', test => {
|
||||
{
|
||||
const buf = [];
|
||||
const thunks = [];
|
||||
function print(x) {
|
||||
buf.push(x);
|
||||
};
|
||||
}
|
||||
function doLater(f) {
|
||||
thunks.push(f);
|
||||
};
|
||||
}
|
||||
|
||||
for (let i = 0; i < 3; i++) {
|
||||
print(i);
|
||||
@@ -217,11 +221,15 @@ Tinytest.add("ecmascript - runtime - block scope", (test) => {
|
||||
}
|
||||
});
|
||||
|
||||
Tinytest.add("ecmascript - runtime - classes - super", (test) => {
|
||||
Tinytest.add('ecmascript - runtime - classes - super', test => {
|
||||
{
|
||||
class Class1 {
|
||||
foo() { return 123; }
|
||||
static bar() { return 1; }
|
||||
foo() {
|
||||
return 123;
|
||||
}
|
||||
static bar() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
class Class2 extends Class1 {}
|
||||
class Class3 extends Class2 {
|
||||
@@ -230,34 +238,41 @@ Tinytest.add("ecmascript - runtime - classes - super", (test) => {
|
||||
}
|
||||
}
|
||||
|
||||
test.equal((new Class3).foo(), 124);
|
||||
test.equal(new Class3().foo(), 124);
|
||||
}
|
||||
|
||||
{
|
||||
class Foo {
|
||||
constructor(value) { this.value = value; }
|
||||
x() { return this.value; }
|
||||
constructor(value) {
|
||||
this.value = value;
|
||||
}
|
||||
x() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
class Bar extends Foo {
|
||||
constructor() { super(123); }
|
||||
x() { return super.x(); }
|
||||
constructor() {
|
||||
super(123);
|
||||
}
|
||||
x() {
|
||||
return super.x();
|
||||
}
|
||||
}
|
||||
|
||||
test.equal((new Bar).x(), 123);
|
||||
test.equal(new Bar().x(), 123);
|
||||
}
|
||||
});
|
||||
|
||||
Tinytest.add("ecmascript - runtime - object rest/spread", (test) => {
|
||||
const middle = {b:2, c:3};
|
||||
Tinytest.add('ecmascript - runtime - object rest/spread', test => {
|
||||
const middle = { b: 2, c: 3 };
|
||||
// uses `babelHelpers._extends`
|
||||
const full = {a:1, ...middle, d:4};
|
||||
test.equal(full, {a:1, b:2, c:3, d:4});
|
||||
const full = { a: 1, ...middle, d: 4 };
|
||||
test.equal(full, { a: 1, b: 2, c: 3, d: 4 });
|
||||
});
|
||||
|
||||
Tinytest.add("ecmascript - runtime - spread args to new", (test) => {
|
||||
|
||||
const Foo = function (one, two, three) {
|
||||
Tinytest.add('ecmascript - runtime - spread args to new', test => {
|
||||
const Foo = function(one, two, three) {
|
||||
test.isTrue(this instanceof Foo);
|
||||
test.equal(one, 1);
|
||||
test.equal(two, 2);
|
||||
@@ -272,35 +287,38 @@ Tinytest.add("ecmascript - runtime - spread args to new", (test) => {
|
||||
test.isTrue(foo.created);
|
||||
});
|
||||
|
||||
Tinytest.add("ecmascript - runtime - Map spread", (test) => {
|
||||
const map = new Map;
|
||||
Tinytest.add('ecmascript - runtime - Map spread', test => {
|
||||
const map = new Map();
|
||||
|
||||
map.set(0, 1);
|
||||
map.set(1, 2);
|
||||
map.set(2, 3);
|
||||
|
||||
test.equal([...map], [
|
||||
[0, 1],
|
||||
[1, 2],
|
||||
[2, 3]
|
||||
]);
|
||||
test.equal(
|
||||
[...map],
|
||||
[
|
||||
[0, 1],
|
||||
[1, 2],
|
||||
[2, 3],
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
Tinytest.add("ecmascript - runtime - Set spread", (test) => {
|
||||
const set = new Set;
|
||||
Tinytest.add('ecmascript - runtime - Set spread', test => {
|
||||
const set = new Set();
|
||||
|
||||
set.add("a");
|
||||
set.add('a');
|
||||
set.add(1);
|
||||
set.add(false);
|
||||
|
||||
test.equal([...set], ["a", 1, false]);
|
||||
test.equal([...set], ['a', 1, false]);
|
||||
});
|
||||
|
||||
Tinytest.add("ecmascript - runtime - destructuring", (test) => {
|
||||
const obj = {a:1, b:2};
|
||||
const {a, ...rest} = obj;
|
||||
Tinytest.add('ecmascript - runtime - destructuring', test => {
|
||||
const obj = { a: 1, b: 2 };
|
||||
const { a, ...rest } = obj;
|
||||
test.equal(a, 1);
|
||||
test.equal(rest, {b:2});
|
||||
test.equal(rest, { b: 2 });
|
||||
|
||||
const {} = {};
|
||||
|
||||
@@ -308,33 +326,33 @@ Tinytest.add("ecmascript - runtime - destructuring", (test) => {
|
||||
const {} = null;
|
||||
});
|
||||
|
||||
const [x, y, z] = function*() {
|
||||
const [x, y, z] = (function*() {
|
||||
let n = 1;
|
||||
while (true) {
|
||||
yield n++;
|
||||
}
|
||||
}();
|
||||
})();
|
||||
|
||||
test.equal(x, 1);
|
||||
test.equal(y, 2);
|
||||
test.equal(z, 3);
|
||||
});
|
||||
|
||||
Tinytest.addAsync("ecmascript - runtime - misc support", (test, done) => {
|
||||
Tinytest.addAsync('ecmascript - runtime - misc support', (test, done) => {
|
||||
// Verify that the runtime was installed.
|
||||
if (Meteor.isLegacy) {
|
||||
test.equal(typeof meteorBabelHelpers, "object");
|
||||
test.equal(typeof meteorBabelHelpers.sanitizeForInObject, "function");
|
||||
test.equal(typeof meteorBabelHelpers, 'object');
|
||||
test.equal(typeof meteorBabelHelpers.sanitizeForInObject, 'function');
|
||||
}
|
||||
|
||||
class Base {
|
||||
constructor(...args) {
|
||||
this.sum = 0;
|
||||
args.forEach(arg => this.sum += arg);
|
||||
args.forEach(arg => (this.sum += arg));
|
||||
}
|
||||
|
||||
static inherited() {
|
||||
return "inherited";
|
||||
return 'inherited';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,32 +363,35 @@ Tinytest.addAsync("ecmascript - runtime - misc support", (test, done) => {
|
||||
}
|
||||
|
||||
// Check that static methods are inherited.
|
||||
test.equal(Derived.inherited(), "inherited");
|
||||
test.equal(Derived.inherited(), 'inherited');
|
||||
|
||||
const d = new Derived();
|
||||
test.equal(d.sum, 6);
|
||||
|
||||
const expectedError = new Error("expected");
|
||||
const expectedError = new Error('expected');
|
||||
|
||||
Promise.resolve("working").then(result => {
|
||||
test.equal(result, "working");
|
||||
throw expectedError;
|
||||
}).catch(error => {
|
||||
test.equal(error, expectedError);
|
||||
if (Meteor.isServer) {
|
||||
const Fiber = Npm.require("fibers");
|
||||
// Make sure the Promise polyfill runs callbacks in a Fiber.
|
||||
test.instanceOf(Fiber.current, Fiber);
|
||||
}
|
||||
}).then(done, error => test.exception(error));
|
||||
Promise.resolve('working')
|
||||
.then(result => {
|
||||
test.equal(result, 'working');
|
||||
throw expectedError;
|
||||
})
|
||||
.catch(error => {
|
||||
test.equal(error, expectedError);
|
||||
if (Meteor.isServer) {
|
||||
const Fiber = Npm.require('fibers');
|
||||
// Make sure the Promise polyfill runs callbacks in a Fiber.
|
||||
test.instanceOf(Fiber.current, Fiber);
|
||||
}
|
||||
})
|
||||
.then(done, error => test.exception(error));
|
||||
});
|
||||
|
||||
Tinytest.addAsync("ecmascript - runtime - async fibers", (test, done) => {
|
||||
if (! Meteor.isServer) {
|
||||
Tinytest.addAsync('ecmascript - runtime - async fibers', (test, done) => {
|
||||
if (!Meteor.isServer) {
|
||||
return done();
|
||||
}
|
||||
|
||||
const Fiber = Npm.require("fibers");
|
||||
const Fiber = Npm.require('fibers');
|
||||
|
||||
function wait() {
|
||||
return new Promise(resolve => setTimeout(resolve, 10));
|
||||
|
||||
@@ -6,9 +6,9 @@ const hasOwn = Object.prototype.hasOwnProperty;
|
||||
const browserAliases = {
|
||||
chrome: [
|
||||
// chromeMobile*, per https://github.com/meteor/meteor/pull/9793,
|
||||
"chromeMobile",
|
||||
"chromeMobileIOS",
|
||||
"chromeMobileWebView",
|
||||
'chromeMobile',
|
||||
'chromeMobileIOS',
|
||||
'chromeMobileWebView',
|
||||
|
||||
// The major version number of Chromium and Headless Chrome track with the
|
||||
// releases of Chrome Dev, Canary and Stable, so we should be okay to
|
||||
@@ -18,19 +18,21 @@ const browserAliases = {
|
||||
// Chromium is particularly important to list here since, unlike macOS
|
||||
// builds, Linux builds list Chromium in the userAgent along with Chrome:
|
||||
// e.g. Chromium/70.0.3538.77 Chrome/70.0.3538.77
|
||||
"chromium",
|
||||
"headlesschrome",
|
||||
'chromium',
|
||||
'headlesschrome',
|
||||
],
|
||||
|
||||
// If a call to setMinimumBrowserVersions specifies Edge 12 as a minimum
|
||||
// version, that means no version of Internet Explorer pre-Edge should
|
||||
// be classified as modern. This edge:["ie"] alias effectively enforces
|
||||
// that logic, because there is no IE12. #9818 #9839
|
||||
edge: ["ie"],
|
||||
edge: ['ie'],
|
||||
|
||||
firefox: ['firefoxMobile'],
|
||||
|
||||
// The webapp package converts browser names to camel case, so
|
||||
// mobile_safari and mobileSafari should be synonymous.
|
||||
mobile_safari: ["mobileSafari", "mobileSafariUI", "mobileSafariUI/WKWebView"],
|
||||
mobile_safari: ['mobileSafari', 'mobileSafariUI', 'mobileSafariUI/WKWebView'],
|
||||
};
|
||||
|
||||
// Expand the given minimum versions by reusing chrome versions for
|
||||
@@ -49,7 +51,7 @@ function applyAliases(versions) {
|
||||
if (hasOwn.call(lowerCaseVersions, original)) {
|
||||
aliases.forEach(alias => {
|
||||
alias = alias.toLowerCase();
|
||||
if (! hasOwn.call(lowerCaseVersions, alias)) {
|
||||
if (!hasOwn.call(lowerCaseVersions, alias)) {
|
||||
lowerCaseVersions[alias] = lowerCaseVersions[original];
|
||||
}
|
||||
});
|
||||
@@ -66,17 +68,17 @@ function applyAliases(versions) {
|
||||
// webapp via request.browser, return true if that browser qualifies as
|
||||
// "modern" according to all requested version constraints.
|
||||
function isModern(browser) {
|
||||
const lowerCaseName = browser &&
|
||||
typeof browser.name === "string" &&
|
||||
browser.name.toLowerCase();
|
||||
const lowerCaseName =
|
||||
browser && typeof browser.name === 'string' && browser.name.toLowerCase();
|
||||
|
||||
return !!lowerCaseName &&
|
||||
return (
|
||||
!!lowerCaseName &&
|
||||
hasOwn.call(minimumVersions, lowerCaseName) &&
|
||||
greaterThanOrEqualTo([
|
||||
~~browser.major,
|
||||
~~browser.minor,
|
||||
~~browser.patch,
|
||||
], minimumVersions[lowerCaseName].version);
|
||||
greaterThanOrEqualTo(
|
||||
[~~browser.major, ~~browser.minor, ~~browser.patch],
|
||||
minimumVersions[lowerCaseName].version
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Any package that depends on the modern-browsers package can call this
|
||||
@@ -90,22 +92,24 @@ function setMinimumBrowserVersions(versions, source) {
|
||||
Object.keys(lowerCaseVersions).forEach(lowerCaseName => {
|
||||
const version = lowerCaseVersions[lowerCaseName];
|
||||
|
||||
if (hasOwn.call(minimumVersions, lowerCaseName) &&
|
||||
! greaterThan(version, minimumVersions[lowerCaseName].version)) {
|
||||
if (
|
||||
hasOwn.call(minimumVersions, lowerCaseName) &&
|
||||
!greaterThan(version, minimumVersions[lowerCaseName].version)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
minimumVersions[lowerCaseName] = {
|
||||
version: copy(version),
|
||||
source: source || getCaller("setMinimumBrowserVersions")
|
||||
source: source || getCaller('setMinimumBrowserVersions'),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function getCaller(calleeName) {
|
||||
const error = new Error;
|
||||
const error = new Error();
|
||||
Error.captureStackTrace(error);
|
||||
const lines = error.stack.split("\n");
|
||||
const lines = error.stack.split('\n');
|
||||
let caller;
|
||||
lines.some((line, i) => {
|
||||
if (line.indexOf(calleeName) >= 0) {
|
||||
@@ -120,17 +124,17 @@ Object.assign(exports, {
|
||||
isModern,
|
||||
setMinimumBrowserVersions,
|
||||
calculateHashOfMinimumVersions() {
|
||||
const { createHash } = require("crypto");
|
||||
return createHash("sha1").update(
|
||||
JSON.stringify(minimumVersions)
|
||||
).digest("hex");
|
||||
}
|
||||
const { createHash } = require('crypto');
|
||||
return createHash('sha1')
|
||||
.update(JSON.stringify(minimumVersions))
|
||||
.digest('hex');
|
||||
},
|
||||
});
|
||||
|
||||
// For making defensive copies of [major, minor, ...] version arrays, so
|
||||
// they don't change unexpectedly.
|
||||
function copy(version) {
|
||||
if (typeof version === "number") {
|
||||
if (typeof version === 'number') {
|
||||
return version;
|
||||
}
|
||||
|
||||
@@ -142,17 +146,17 @@ function copy(version) {
|
||||
}
|
||||
|
||||
function greaterThanOrEqualTo(a, b) {
|
||||
return ! greaterThan(b, a);
|
||||
return !greaterThan(b, a);
|
||||
}
|
||||
|
||||
function greaterThan(a, b) {
|
||||
const as = (typeof a === "number") ? [a] : a;
|
||||
const bs = (typeof b === "number") ? [b] : b;
|
||||
const as = typeof a === 'number' ? [a] : a;
|
||||
const bs = typeof b === 'number' ? [b] : b;
|
||||
const maxLen = Math.max(as.length, bs.length);
|
||||
|
||||
for (let i = 0; i < maxLen; ++i) {
|
||||
a = (i < as.length) ? as[i] : 0;
|
||||
b = (i < bs.length) ? bs[i] : 0;
|
||||
a = i < as.length ? as[i] : 0;
|
||||
b = i < bs.length ? bs[i] : 0;
|
||||
|
||||
if (a > b) {
|
||||
return true;
|
||||
@@ -167,49 +171,61 @@ function greaterThan(a, b) {
|
||||
}
|
||||
|
||||
function makeSource(feature) {
|
||||
return module.id + " (" + feature + ")";
|
||||
return module.id + ' (' + feature + ')';
|
||||
}
|
||||
|
||||
setMinimumBrowserVersions({
|
||||
chrome: 49,
|
||||
edge: 12,
|
||||
firefox: 45,
|
||||
mobileSafari: [9, 2],
|
||||
opera: 36,
|
||||
safari: 9,
|
||||
// Electron 1.0.0+ matches Chromium 49, per
|
||||
// https://github.com/Kilian/electron-to-chromium/blob/master/full-versions.js
|
||||
electron: 1,
|
||||
}, makeSource("classes"));
|
||||
setMinimumBrowserVersions(
|
||||
{
|
||||
chrome: 49,
|
||||
edge: 12,
|
||||
firefox: 45,
|
||||
mobileSafari: [9, 2],
|
||||
opera: 36,
|
||||
safari: 9,
|
||||
// Electron 1.0.0+ matches Chromium 49, per
|
||||
// https://github.com/Kilian/electron-to-chromium/blob/master/full-versions.js
|
||||
electron: 1,
|
||||
},
|
||||
makeSource('classes')
|
||||
);
|
||||
|
||||
setMinimumBrowserVersions({
|
||||
chrome: 39,
|
||||
edge: 13,
|
||||
firefox: 26,
|
||||
mobileSafari: 10,
|
||||
opera: 26,
|
||||
safari: 10,
|
||||
// Disallow any version of PhantomJS.
|
||||
phantomjs: Infinity,
|
||||
electron: [0, 20],
|
||||
}, makeSource("generator functions"));
|
||||
setMinimumBrowserVersions(
|
||||
{
|
||||
chrome: 39,
|
||||
edge: 13,
|
||||
firefox: 26,
|
||||
mobileSafari: 10,
|
||||
opera: 26,
|
||||
safari: 10,
|
||||
// Disallow any version of PhantomJS.
|
||||
phantomjs: Infinity,
|
||||
electron: [0, 20],
|
||||
},
|
||||
makeSource('generator functions')
|
||||
);
|
||||
|
||||
setMinimumBrowserVersions({
|
||||
chrome: 41,
|
||||
edge: 13,
|
||||
firefox: 34,
|
||||
mobileSafari: [9, 2],
|
||||
opera: 29,
|
||||
safari: [9, 1],
|
||||
electron: [0, 24],
|
||||
}, makeSource("template literals"));
|
||||
setMinimumBrowserVersions(
|
||||
{
|
||||
chrome: 41,
|
||||
edge: 13,
|
||||
firefox: 34,
|
||||
mobileSafari: [9, 2],
|
||||
opera: 29,
|
||||
safari: [9, 1],
|
||||
electron: [0, 24],
|
||||
},
|
||||
makeSource('template literals')
|
||||
);
|
||||
|
||||
setMinimumBrowserVersions({
|
||||
chrome: 38,
|
||||
edge: 12,
|
||||
firefox: 36,
|
||||
mobileSafari: 9,
|
||||
opera: 25,
|
||||
safari: 9,
|
||||
electron: [0, 20],
|
||||
}, makeSource("symbols"));
|
||||
setMinimumBrowserVersions(
|
||||
{
|
||||
chrome: 38,
|
||||
edge: 12,
|
||||
firefox: 36,
|
||||
mobileSafari: 9,
|
||||
opera: 25,
|
||||
safari: 9,
|
||||
electron: [0, 20],
|
||||
},
|
||||
makeSource('symbols')
|
||||
);
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
Package.describe({
|
||||
name: "modern-browsers",
|
||||
version: "0.1.6",
|
||||
summary: "API for defining the boundary between modern and legacy " +
|
||||
"JavaScript clients",
|
||||
documentation: "README.md"
|
||||
name: 'modern-browsers',
|
||||
version: '0.1.7',
|
||||
summary:
|
||||
'API for defining the boundary between modern and legacy ' +
|
||||
'JavaScript clients',
|
||||
documentation: 'README.md',
|
||||
});
|
||||
|
||||
Package.onUse(function(api) {
|
||||
api.use("modules");
|
||||
api.mainModule("modern.js", "server");
|
||||
api.use('modules');
|
||||
api.mainModule('modern.js', 'server');
|
||||
});
|
||||
|
||||
Package.onTest(function(api) {
|
||||
api.use("ecmascript");
|
||||
api.use("tinytest");
|
||||
api.use("modern-browsers");
|
||||
api.mainModule("modern-tests.js", "server");
|
||||
api.use('ecmascript');
|
||||
api.use('tinytest');
|
||||
api.use('modern-browsers');
|
||||
api.mainModule('modern-tests.js', 'server');
|
||||
});
|
||||
|
||||
@@ -25,16 +25,19 @@ The default id generation technique is `'STRING'`.
|
||||
* @param {Boolean} options.defineMutationMethods Set to `false` to skip setting up the mutation methods that enable insert/update/remove from client code. Default `true`.
|
||||
*/
|
||||
Mongo.Collection = function Collection(name, options) {
|
||||
if (!name && (name !== null)) {
|
||||
Meteor._debug("Warning: creating anonymous collection. It will not be " +
|
||||
"saved or synchronized over the network. (Pass null for " +
|
||||
"the collection name to turn off this warning.)");
|
||||
if (!name && name !== null) {
|
||||
Meteor._debug(
|
||||
'Warning: creating anonymous collection. It will not be ' +
|
||||
'saved or synchronized over the network. (Pass null for ' +
|
||||
'the collection name to turn off this warning.)'
|
||||
);
|
||||
name = null;
|
||||
}
|
||||
|
||||
if (name !== null && typeof name !== "string") {
|
||||
if (name !== null && typeof name !== 'string') {
|
||||
throw new Error(
|
||||
"First argument to new Mongo.Collection must be a string or null");
|
||||
'First argument to new Mongo.Collection must be a string or null'
|
||||
);
|
||||
}
|
||||
|
||||
if (options && options.methods) {
|
||||
@@ -42,7 +45,7 @@ Mongo.Collection = function Collection(name, options) {
|
||||
// "connection" directly instead of in options. (Connections must have a "methods"
|
||||
// method.)
|
||||
// XXX remove before 1.0
|
||||
options = {connection: options};
|
||||
options = { connection: options };
|
||||
}
|
||||
// Backwards compatibility: "connection" used to be called "manager".
|
||||
if (options && options.manager && !options.connection) {
|
||||
@@ -55,49 +58,52 @@ Mongo.Collection = function Collection(name, options) {
|
||||
transform: null,
|
||||
_driver: undefined,
|
||||
_preventAutopublish: false,
|
||||
...options,
|
||||
...options,
|
||||
};
|
||||
|
||||
switch (options.idGeneration) {
|
||||
case 'MONGO':
|
||||
this._makeNewID = function () {
|
||||
var src = name ? DDP.randomStream('/collection/' + name) : Random.insecure;
|
||||
return new Mongo.ObjectID(src.hexString(24));
|
||||
};
|
||||
break;
|
||||
case 'STRING':
|
||||
default:
|
||||
this._makeNewID = function () {
|
||||
var src = name ? DDP.randomStream('/collection/' + name) : Random.insecure;
|
||||
return src.id();
|
||||
};
|
||||
break;
|
||||
case 'MONGO':
|
||||
this._makeNewID = function() {
|
||||
var src = name
|
||||
? DDP.randomStream('/collection/' + name)
|
||||
: Random.insecure;
|
||||
return new Mongo.ObjectID(src.hexString(24));
|
||||
};
|
||||
break;
|
||||
case 'STRING':
|
||||
default:
|
||||
this._makeNewID = function() {
|
||||
var src = name
|
||||
? DDP.randomStream('/collection/' + name)
|
||||
: Random.insecure;
|
||||
return src.id();
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
this._transform = LocalCollection.wrapTransform(options.transform);
|
||||
|
||||
if (! name || options.connection === null)
|
||||
if (!name || options.connection === null)
|
||||
// note: nameless collections never have a connection
|
||||
this._connection = null;
|
||||
else if (options.connection)
|
||||
this._connection = options.connection;
|
||||
else if (Meteor.isClient)
|
||||
this._connection = Meteor.connection;
|
||||
else
|
||||
this._connection = Meteor.server;
|
||||
else if (options.connection) this._connection = options.connection;
|
||||
else if (Meteor.isClient) this._connection = Meteor.connection;
|
||||
else this._connection = Meteor.server;
|
||||
|
||||
if (!options._driver) {
|
||||
// XXX This check assumes that webapp is loaded so that Meteor.server !==
|
||||
// null. We should fully support the case of "want to use a Mongo-backed
|
||||
// collection from Node code without webapp", but we don't yet.
|
||||
// #MeteorServerNull
|
||||
if (name && this._connection === Meteor.server &&
|
||||
typeof MongoInternals !== "undefined" &&
|
||||
MongoInternals.defaultRemoteCollectionDriver) {
|
||||
if (
|
||||
name &&
|
||||
this._connection === Meteor.server &&
|
||||
typeof MongoInternals !== 'undefined' &&
|
||||
MongoInternals.defaultRemoteCollectionDriver
|
||||
) {
|
||||
options._driver = MongoInternals.defaultRemoteCollectionDriver();
|
||||
} else {
|
||||
const { LocalCollectionDriver } =
|
||||
require("./local_collection_driver.js");
|
||||
const { LocalCollectionDriver } = require('./local_collection_driver.js');
|
||||
options._driver = LocalCollectionDriver;
|
||||
}
|
||||
}
|
||||
@@ -114,21 +120,25 @@ Mongo.Collection = function Collection(name, options) {
|
||||
if (options.defineMutationMethods !== false) {
|
||||
try {
|
||||
this._defineMutationMethods({
|
||||
useExisting: options._suppressSameNameError === true
|
||||
useExisting: options._suppressSameNameError === true,
|
||||
});
|
||||
} catch (error) {
|
||||
// Throw a more understandable error on the server for same collection name
|
||||
if (error.message === `A method named '/${name}/insert' is already defined`)
|
||||
if (
|
||||
error.message === `A method named '/${name}/insert' is already defined`
|
||||
)
|
||||
throw new Error(`There is already a collection named "${name}"`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// autopublish
|
||||
if (Package.autopublish &&
|
||||
! options._preventAutopublish &&
|
||||
this._connection &&
|
||||
this._connection.publish) {
|
||||
if (
|
||||
Package.autopublish &&
|
||||
!options._preventAutopublish &&
|
||||
this._connection &&
|
||||
this._connection.publish
|
||||
) {
|
||||
this._connection.publish(null, () => this.find(), {
|
||||
is_auto: true,
|
||||
});
|
||||
@@ -136,12 +146,9 @@ Mongo.Collection = function Collection(name, options) {
|
||||
};
|
||||
|
||||
Object.assign(Mongo.Collection.prototype, {
|
||||
_maybeSetUpReplication(name, {
|
||||
_suppressSameNameError = false
|
||||
}) {
|
||||
_maybeSetUpReplication(name, { _suppressSameNameError = false }) {
|
||||
const self = this;
|
||||
if (! (self._connection &&
|
||||
self._connection.registerStore)) {
|
||||
if (!(self._connection && self._connection.registerStore)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -165,11 +172,9 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
// stage), and so that a re-sorting of a query can take advantage of the
|
||||
// full _diffQuery moved calculation instead of applying change one at a
|
||||
// time.
|
||||
if (batchSize > 1 || reset)
|
||||
self._collection.pauseObservers();
|
||||
if (batchSize > 1 || reset) self._collection.pauseObservers();
|
||||
|
||||
if (reset)
|
||||
self._collection.remove({});
|
||||
if (reset) self._collection.remove({});
|
||||
},
|
||||
|
||||
// Apply an update.
|
||||
@@ -211,8 +216,7 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
if (msg.msg === 'replace') {
|
||||
var replace = msg.replace;
|
||||
if (!replace) {
|
||||
if (doc)
|
||||
self._collection.remove(mongoId);
|
||||
if (doc) self._collection.remove(mongoId);
|
||||
} else if (!doc) {
|
||||
self._collection.insert(replace);
|
||||
} else {
|
||||
@@ -222,16 +226,19 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
return;
|
||||
} else if (msg.msg === 'added') {
|
||||
if (doc) {
|
||||
throw new Error("Expected not to find a document already present for an add");
|
||||
throw new Error(
|
||||
'Expected not to find a document already present for an add'
|
||||
);
|
||||
}
|
||||
self._collection.insert({ _id: mongoId, ...msg.fields });
|
||||
} else if (msg.msg === 'removed') {
|
||||
if (!doc)
|
||||
throw new Error("Expected to find a document already present for removed");
|
||||
throw new Error(
|
||||
'Expected to find a document already present for removed'
|
||||
);
|
||||
self._collection.remove(mongoId);
|
||||
} else if (msg.msg === 'changed') {
|
||||
if (!doc)
|
||||
throw new Error("Expected to find a document to change");
|
||||
if (!doc) throw new Error('Expected to find a document to change');
|
||||
const keys = Object.keys(msg.fields);
|
||||
if (keys.length > 0) {
|
||||
var modifier = {};
|
||||
@@ -240,7 +247,7 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
if (EJSON.equals(doc[key], value)) {
|
||||
return;
|
||||
}
|
||||
if (typeof value === "undefined") {
|
||||
if (typeof value === 'undefined') {
|
||||
if (!modifier.$unset) {
|
||||
modifier.$unset = {};
|
||||
}
|
||||
@@ -283,10 +290,10 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
// To be able to get back to the collection from the store.
|
||||
_getCollection() {
|
||||
return self;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
if (! ok) {
|
||||
if (!ok) {
|
||||
const message = `There is already a collection named "${name}"`;
|
||||
if (_suppressSameNameError === true) {
|
||||
// XXX In theory we do not have to throw when `ok` is falsy. The
|
||||
@@ -308,10 +315,8 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
///
|
||||
|
||||
_getFindSelector(args) {
|
||||
if (args.length == 0)
|
||||
return {};
|
||||
else
|
||||
return args[0];
|
||||
if (args.length == 0) return {};
|
||||
else return args[0];
|
||||
},
|
||||
|
||||
_getFindOptions(args) {
|
||||
@@ -319,12 +324,19 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
if (args.length < 2) {
|
||||
return { transform: self._transform };
|
||||
} else {
|
||||
check(args[1], Match.Optional(Match.ObjectIncluding({
|
||||
fields: Match.Optional(Match.OneOf(Object, undefined)),
|
||||
sort: Match.Optional(Match.OneOf(Object, Array, Function, undefined)),
|
||||
limit: Match.Optional(Match.OneOf(Number, undefined)),
|
||||
skip: Match.Optional(Match.OneOf(Number, undefined))
|
||||
})));
|
||||
check(
|
||||
args[1],
|
||||
Match.Optional(
|
||||
Match.ObjectIncluding({
|
||||
fields: Match.Optional(Match.OneOf(Object, undefined)),
|
||||
sort: Match.Optional(
|
||||
Match.OneOf(Object, Array, Function, undefined)
|
||||
),
|
||||
limit: Match.Optional(Match.OneOf(Number, undefined)),
|
||||
skip: Match.Optional(Match.OneOf(Number, undefined)),
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
return {
|
||||
transform: self._transform,
|
||||
@@ -386,31 +398,33 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
this._getFindSelector(args),
|
||||
this._getFindOptions(args)
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
Object.assign(Mongo.Collection, {
|
||||
_publishCursor(cursor, sub, collection) {
|
||||
var observeHandle = cursor.observeChanges({
|
||||
added: function (id, fields) {
|
||||
sub.added(collection, id, fields);
|
||||
var observeHandle = cursor.observeChanges(
|
||||
{
|
||||
added: function(id, fields) {
|
||||
sub.added(collection, id, fields);
|
||||
},
|
||||
changed: function(id, fields) {
|
||||
sub.changed(collection, id, fields);
|
||||
},
|
||||
removed: function(id) {
|
||||
sub.removed(collection, id);
|
||||
},
|
||||
},
|
||||
changed: function (id, fields) {
|
||||
sub.changed(collection, id, fields);
|
||||
},
|
||||
removed: function (id) {
|
||||
sub.removed(collection, id);
|
||||
}
|
||||
},
|
||||
// Publications don't mutate the documents
|
||||
// This is tested by the `livedata - publish callbacks clone` test
|
||||
{ nonMutatingCallbacks: true });
|
||||
// Publications don't mutate the documents
|
||||
// This is tested by the `livedata - publish callbacks clone` test
|
||||
{ nonMutatingCallbacks: true }
|
||||
);
|
||||
|
||||
// We don't call sub.ready() here: it gets called in livedata_server, after
|
||||
// possibly calling _publishCursor on multiple returned cursors.
|
||||
|
||||
// register stop callback (expects lambda w/ no args).
|
||||
sub.onStop(function () {
|
||||
sub.onStop(function() {
|
||||
observeHandle.stop();
|
||||
});
|
||||
|
||||
@@ -425,8 +439,7 @@ Object.assign(Mongo.Collection, {
|
||||
// instead.
|
||||
_rewriteSelector(selector, { fallbackId } = {}) {
|
||||
// shorthand -- scalars match _id
|
||||
if (LocalCollection._selectorIsId(selector))
|
||||
selector = {_id: selector};
|
||||
if (LocalCollection._selectorIsId(selector)) selector = { _id: selector };
|
||||
|
||||
if (Array.isArray(selector)) {
|
||||
// This is consistent with the Mongo console itself; if we don't do this
|
||||
@@ -434,13 +447,13 @@ Object.assign(Mongo.Collection, {
|
||||
throw new Error("Mongo selector can't be an array.");
|
||||
}
|
||||
|
||||
if (!selector || (('_id' in selector) && !selector._id)) {
|
||||
if (!selector || ('_id' in selector && !selector._id)) {
|
||||
// can't match anything
|
||||
return { _id: fallbackId || Random.id() };
|
||||
}
|
||||
|
||||
return selector;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
Object.assign(Mongo.Collection.prototype, {
|
||||
@@ -486,7 +499,7 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
insert(doc, callback) {
|
||||
// Make sure we were passed a document to insert
|
||||
if (!doc) {
|
||||
throw new Error("insert requires an argument");
|
||||
throw new Error('insert requires an argument');
|
||||
}
|
||||
|
||||
// Make a shallow clone of the document, preserving its prototype.
|
||||
@@ -496,11 +509,13 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
);
|
||||
|
||||
if ('_id' in doc) {
|
||||
if (! doc._id ||
|
||||
! (typeof doc._id === 'string' ||
|
||||
doc._id instanceof Mongo.ObjectID)) {
|
||||
if (
|
||||
!doc._id ||
|
||||
!(typeof doc._id === 'string' || doc._id instanceof Mongo.ObjectID)
|
||||
) {
|
||||
throw new Error(
|
||||
"Meteor requires document _id fields to be non-empty strings or ObjectIDs");
|
||||
'Meteor requires document _id fields to be non-empty strings or ObjectIDs'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
let generateId = true;
|
||||
@@ -522,7 +537,7 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
|
||||
// On inserts, always return the id that we generated; on all other
|
||||
// operations, just return the result from the collection.
|
||||
var chooseReturnValueFromCollectionResult = function (result) {
|
||||
var chooseReturnValueFromCollectionResult = function(result) {
|
||||
if (doc._id) {
|
||||
return doc._id;
|
||||
}
|
||||
@@ -536,10 +551,12 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
};
|
||||
|
||||
const wrappedCallback = wrapCallback(
|
||||
callback, chooseReturnValueFromCollectionResult);
|
||||
callback,
|
||||
chooseReturnValueFromCollectionResult
|
||||
);
|
||||
|
||||
if (this._isRemoteCollection()) {
|
||||
const result = this._callMutatorMethod("insert", [doc], wrappedCallback);
|
||||
const result = this._callMutatorMethod('insert', [doc], wrappedCallback);
|
||||
return chooseReturnValueFromCollectionResult(result);
|
||||
}
|
||||
|
||||
@@ -584,8 +601,13 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
if (options && options.upsert) {
|
||||
// set `insertedId` if absent. `insertedId` is a Meteor extension.
|
||||
if (options.insertedId) {
|
||||
if (!(typeof options.insertedId === 'string' || options.insertedId instanceof Mongo.ObjectID))
|
||||
throw new Error("insertedId must be string or ObjectID");
|
||||
if (
|
||||
!(
|
||||
typeof options.insertedId === 'string' ||
|
||||
options.insertedId instanceof Mongo.ObjectID
|
||||
)
|
||||
)
|
||||
throw new Error('insertedId must be string or ObjectID');
|
||||
insertedId = options.insertedId;
|
||||
} else if (!selector || !selector._id) {
|
||||
insertedId = this._makeNewID();
|
||||
@@ -594,19 +616,16 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
}
|
||||
}
|
||||
|
||||
selector =
|
||||
Mongo.Collection._rewriteSelector(selector, { fallbackId: insertedId });
|
||||
selector = Mongo.Collection._rewriteSelector(selector, {
|
||||
fallbackId: insertedId,
|
||||
});
|
||||
|
||||
const wrappedCallback = wrapCallback(callback);
|
||||
|
||||
if (this._isRemoteCollection()) {
|
||||
const args = [
|
||||
selector,
|
||||
modifier,
|
||||
options
|
||||
];
|
||||
const args = [selector, modifier, options];
|
||||
|
||||
return this._callMutatorMethod("update", args, wrappedCallback);
|
||||
return this._callMutatorMethod('update', args, wrappedCallback);
|
||||
}
|
||||
|
||||
// it's my collection. descend into the collection object
|
||||
@@ -616,7 +635,11 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
// operation asynchronously, then queryRet will be undefined, and the
|
||||
// result will be returned through the callback instead.
|
||||
return this._collection.update(
|
||||
selector, modifier, options, wrappedCallback);
|
||||
selector,
|
||||
modifier,
|
||||
options,
|
||||
wrappedCallback
|
||||
);
|
||||
} catch (e) {
|
||||
if (callback) {
|
||||
callback(e);
|
||||
@@ -641,7 +664,7 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
const wrappedCallback = wrapCallback(callback);
|
||||
|
||||
if (this._isRemoteCollection()) {
|
||||
return this._callMutatorMethod("remove", [selector], wrappedCallback);
|
||||
return this._callMutatorMethod('remove', [selector], wrappedCallback);
|
||||
}
|
||||
|
||||
// it's my collection. descend into the collection object
|
||||
@@ -680,16 +703,21 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
* @param {Function} [callback] Optional. If present, called with an error object as the first argument and, if no error, the number of affected documents as the second.
|
||||
*/
|
||||
upsert(selector, modifier, options, callback) {
|
||||
if (! callback && typeof options === "function") {
|
||||
if (!callback && typeof options === 'function') {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
return this.update(selector, modifier, {
|
||||
...options,
|
||||
_returnObject: true,
|
||||
upsert: true,
|
||||
}, callback);
|
||||
return this.update(
|
||||
selector,
|
||||
modifier,
|
||||
{
|
||||
...options,
|
||||
_returnObject: true,
|
||||
upsert: true,
|
||||
},
|
||||
callback
|
||||
);
|
||||
},
|
||||
|
||||
// We'll actually design an index API later. For now, we just pass through to
|
||||
@@ -697,7 +725,7 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
_ensureIndex(index, options) {
|
||||
var self = this;
|
||||
if (!self._collection._ensureIndex || !self._collection.createIndex)
|
||||
throw new Error("Can only call createIndex on server collections");
|
||||
throw new Error('Can only call createIndex on server collections');
|
||||
// TODO enable this message a release before we will remove this function
|
||||
// import { Log } from 'meteor/logging';
|
||||
// Log.debug(`_ensureIndex has been deprecated, please use the new 'createIndex' instead${options?.name ? `, index name: ${options.name}` : `, index: ${JSON.stringify(index)}`}`)
|
||||
@@ -715,7 +743,7 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
* @memberof Mongo.Collection
|
||||
* @instance
|
||||
* @param {Object} index A document that contains the field and value pairs where the field is the index key and the value describes the type of index for that field. For an ascending index on a field, specify a value of `1`; for descending index, specify a value of `-1`. Use `text` for text indexes.
|
||||
* @param {Object} [options] All options are listed in [MongoDB documentation](https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/#std-label-ensureIndex-options)
|
||||
* @param {Object} [options] All options are listed in [MongoDB documentation](https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/#options)
|
||||
* @param {String} options.name Name of the index
|
||||
* @param {Boolean} options.unique Define that the index values must be unique, more at [MongoDB documentation](https://docs.mongodb.com/manual/core/index-unique/)
|
||||
* @param {Boolean} options.sparse Define that the index is sparse, more at [MongoDB documentation](https://docs.mongodb.com/manual/core/index-sparse/)
|
||||
@@ -723,28 +751,30 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
createIndex(index, options) {
|
||||
var self = this;
|
||||
if (!self._collection.createIndex)
|
||||
throw new Error("Can only call createIndex on server collections");
|
||||
throw new Error('Can only call createIndex on server collections');
|
||||
self._collection.createIndex(index, options);
|
||||
},
|
||||
|
||||
_dropIndex(index) {
|
||||
var self = this;
|
||||
if (!self._collection._dropIndex)
|
||||
throw new Error("Can only call _dropIndex on server collections");
|
||||
throw new Error('Can only call _dropIndex on server collections');
|
||||
self._collection._dropIndex(index);
|
||||
},
|
||||
|
||||
_dropCollection() {
|
||||
var self = this;
|
||||
if (!self._collection.dropCollection)
|
||||
throw new Error("Can only call _dropCollection on server collections");
|
||||
throw new Error('Can only call _dropCollection on server collections');
|
||||
self._collection.dropCollection();
|
||||
},
|
||||
|
||||
_createCappedCollection(byteSize, maxDocuments) {
|
||||
var self = this;
|
||||
if (!self._collection._createCappedCollection)
|
||||
throw new Error("Can only call _createCappedCollection on server collections");
|
||||
throw new Error(
|
||||
'Can only call _createCappedCollection on server collections'
|
||||
);
|
||||
self._collection._createCappedCollection(byteSize, maxDocuments);
|
||||
},
|
||||
|
||||
@@ -756,8 +786,8 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
*/
|
||||
rawCollection() {
|
||||
var self = this;
|
||||
if (! self._collection.rawCollection) {
|
||||
throw new Error("Can only call rawCollection on server collections");
|
||||
if (!self._collection.rawCollection) {
|
||||
throw new Error('Can only call rawCollection on server collections');
|
||||
}
|
||||
return self._collection.rawCollection();
|
||||
},
|
||||
@@ -770,24 +800,27 @@ Object.assign(Mongo.Collection.prototype, {
|
||||
*/
|
||||
rawDatabase() {
|
||||
var self = this;
|
||||
if (! (self._driver.mongo && self._driver.mongo.db)) {
|
||||
throw new Error("Can only call rawDatabase on server collections");
|
||||
if (!(self._driver.mongo && self._driver.mongo.db)) {
|
||||
throw new Error('Can only call rawDatabase on server collections');
|
||||
}
|
||||
return self._driver.mongo.db;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Convert the callback to not return a result if there is an error
|
||||
function wrapCallback(callback, convertResult) {
|
||||
return callback && function (error, result) {
|
||||
if (error) {
|
||||
callback(error);
|
||||
} else if (typeof convertResult === "function") {
|
||||
callback(error, convertResult(result));
|
||||
} else {
|
||||
callback(error, result);
|
||||
return (
|
||||
callback &&
|
||||
function(error, result) {
|
||||
if (error) {
|
||||
callback(error);
|
||||
} else if (typeof convertResult === 'function') {
|
||||
callback(error, convertResult(result));
|
||||
} else {
|
||||
callback(error, result);
|
||||
}
|
||||
}
|
||||
};
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -821,17 +854,16 @@ Mongo.Collection.ObjectID = Mongo.ObjectID;
|
||||
Meteor.Collection = Mongo.Collection;
|
||||
|
||||
// Allow deny stuff is now in the allow-deny package
|
||||
Object.assign(
|
||||
Meteor.Collection.prototype,
|
||||
AllowDeny.CollectionPrototype
|
||||
);
|
||||
Object.assign(Meteor.Collection.prototype, AllowDeny.CollectionPrototype);
|
||||
|
||||
function popCallbackFromArgs(args) {
|
||||
// Pull off any callback (or perhaps a 'callback' variable that was passed
|
||||
// in undefined, like how 'upsert' does it).
|
||||
if (args.length &&
|
||||
(args[args.length - 1] === undefined ||
|
||||
args[args.length - 1] instanceof Function)) {
|
||||
if (
|
||||
args.length &&
|
||||
(args[args.length - 1] === undefined ||
|
||||
args[args.length - 1] instanceof Function)
|
||||
) {
|
||||
return args.pop();
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1
tools/tests/apps/ecmascript-regression/.gitignore
vendored
Normal file
1
tools/tests/apps/ecmascript-regression/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
node_modules/
|
||||
@@ -0,0 +1,19 @@
|
||||
# This file contains information which helps Meteor properly upgrade your
|
||||
# app when you run 'meteor update'. You should check it into version control
|
||||
# with your project.
|
||||
|
||||
notices-for-0.9.0
|
||||
notices-for-0.9.1
|
||||
0.9.4-platform-file
|
||||
notices-for-facebook-graph-api-2
|
||||
1.2.0-standard-minifiers-package
|
||||
1.2.0-meteor-platform-split
|
||||
1.2.0-cordova-changes
|
||||
1.2.0-breaking-changes
|
||||
1.3.0-split-minifiers-package
|
||||
1.4.0-remove-old-dev-bundle-link
|
||||
1.4.1-add-shell-server-package
|
||||
1.4.3-split-account-service-packages
|
||||
1.5-add-dynamic-import-package
|
||||
1.7-split-underscore-from-meteor-base
|
||||
1.8.3-split-jquery-from-blaze
|
||||
1
tools/tests/apps/ecmascript-regression/.meteor/.gitignore
vendored
Normal file
1
tools/tests/apps/ecmascript-regression/.meteor/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
local
|
||||
7
tools/tests/apps/ecmascript-regression/.meteor/.id
Normal file
7
tools/tests/apps/ecmascript-regression/.meteor/.id
Normal file
@@ -0,0 +1,7 @@
|
||||
# This file contains a token that is unique to your project.
|
||||
# Check it into your repository along with the rest of this directory.
|
||||
# It can be used for purposes such as:
|
||||
# - ensuring you don't accidentally deploy one app on top of another
|
||||
# - providing package authors with aggregated statistics
|
||||
|
||||
y1s06jw2jowx.c256atzmooh5
|
||||
23
tools/tests/apps/ecmascript-regression/.meteor/packages
Normal file
23
tools/tests/apps/ecmascript-regression/.meteor/packages
Normal file
@@ -0,0 +1,23 @@
|
||||
# Meteor packages used by this project, one per line.
|
||||
# Check this file (and the other files in this directory) into your repository.
|
||||
#
|
||||
# 'meteor add' and 'meteor remove' will edit this file for you,
|
||||
# but you can also edit it by hand.
|
||||
|
||||
meteor-base@1.5.1 # Packages every Meteor app needs to have
|
||||
mobile-experience@1.1.0 # Packages for a great mobile UX
|
||||
mongo@1.13.0 # The database Meteor supports right now
|
||||
reactive-var@1.0.11 # Reactive variable for tracker
|
||||
|
||||
standard-minifier-css@1.7.4 # CSS minifier run for production mode
|
||||
standard-minifier-js@2.7.0 # JS minifier run for production mode
|
||||
es5-shim@4.8.0 # ECMAScript 5 compatibility for older browsers
|
||||
ecmascript@0.15.3 # Enable ECMAScript2015+ syntax in app code
|
||||
typescript@4.3.5 # Enable TypeScript syntax in .ts and .tsx modules
|
||||
shell-server@0.5.0 # Server-side component of the `meteor shell` command
|
||||
hot-module-replacement@0.3.0 # Update client in development without reloading the page
|
||||
|
||||
autopublish@1.0.7 # Publish all data to the clients (for prototyping)
|
||||
insecure@1.0.7 # Allow all DB writes from clients (for prototyping)
|
||||
static-html@1.3.2 # Define static page content in .html files
|
||||
react-meteor-data # React higher-order component for reactively tracking Meteor data
|
||||
2
tools/tests/apps/ecmascript-regression/.meteor/platforms
Normal file
2
tools/tests/apps/ecmascript-regression/.meteor/platforms
Normal file
@@ -0,0 +1,2 @@
|
||||
server
|
||||
browser
|
||||
1
tools/tests/apps/ecmascript-regression/.meteor/release
Normal file
1
tools/tests/apps/ecmascript-regression/.meteor/release
Normal file
@@ -0,0 +1 @@
|
||||
METEOR@2.4
|
||||
78
tools/tests/apps/ecmascript-regression/.meteor/versions
Normal file
78
tools/tests/apps/ecmascript-regression/.meteor/versions
Normal file
@@ -0,0 +1,78 @@
|
||||
allow-deny@1.1.0
|
||||
autopublish@1.0.7
|
||||
autoupdate@1.7.0
|
||||
babel-compiler@7.7.0
|
||||
babel-runtime@1.5.0
|
||||
base64@1.0.12
|
||||
binary-heap@1.0.11
|
||||
blaze-tools@1.1.2
|
||||
boilerplate-generator@1.7.1
|
||||
caching-compiler@1.2.2
|
||||
caching-html-compiler@1.2.1
|
||||
callback-hook@1.4.0
|
||||
check@1.3.1
|
||||
ddp@1.4.0
|
||||
ddp-client@2.5.0
|
||||
ddp-common@1.4.0
|
||||
ddp-server@2.5.0
|
||||
diff-sequence@1.1.1
|
||||
dynamic-import@0.7.1
|
||||
ecmascript@0.15.3
|
||||
ecmascript-runtime@0.8.0
|
||||
ecmascript-runtime-client@0.12.1
|
||||
ecmascript-runtime-server@0.11.0
|
||||
ejson@1.1.1
|
||||
es5-shim@4.8.0
|
||||
fetch@0.1.1
|
||||
geojson-utils@1.0.10
|
||||
hot-code-push@1.0.4
|
||||
hot-module-replacement@0.3.0
|
||||
html-tools@1.1.2
|
||||
htmljs@1.1.1
|
||||
http@1.0.10
|
||||
id-map@1.1.1
|
||||
insecure@1.0.7
|
||||
inter-process-messaging@0.1.1
|
||||
launch-screen@1.3.0
|
||||
logging@1.3.1
|
||||
meteor@1.10.0
|
||||
meteor-base@1.5.1
|
||||
meteortesting:browser-tests@1.3.4
|
||||
meteortesting:mocha@2.0.3
|
||||
meteortesting:mocha-core@8.0.1
|
||||
minifier-css@1.6.0
|
||||
minifier-js@2.7.1
|
||||
minimongo@1.7.0
|
||||
mobile-experience@1.1.0
|
||||
mobile-status-bar@1.1.0
|
||||
modern-browsers@0.1.7
|
||||
modules@0.17.0
|
||||
modules-runtime@0.12.0
|
||||
modules-runtime-hot@0.13.0
|
||||
mongo@1.13.0
|
||||
mongo-decimal@0.1.2
|
||||
mongo-dev-server@1.1.0
|
||||
mongo-id@1.0.8
|
||||
npm-mongo@3.9.1
|
||||
ordered-dict@1.1.0
|
||||
promise@0.12.0
|
||||
random@1.2.0
|
||||
react-fast-refresh@0.1.1
|
||||
react-meteor-data@2.3.3
|
||||
reactive-var@1.0.11
|
||||
reload@1.3.1
|
||||
retry@1.1.0
|
||||
routepolicy@1.1.1
|
||||
shell-server@0.5.0
|
||||
socket-stream-client@0.4.0
|
||||
spacebars-compiler@1.3.0
|
||||
standard-minifier-css@1.7.4
|
||||
standard-minifier-js@2.7.1
|
||||
static-html@1.3.2
|
||||
templating-tools@1.2.1
|
||||
tracker@1.2.0
|
||||
typescript@4.3.5
|
||||
underscore@1.0.10
|
||||
url@1.3.2
|
||||
webapp@1.12.0
|
||||
webapp-hashing@1.1.0
|
||||
4
tools/tests/apps/ecmascript-regression/client/main.css
Normal file
4
tools/tests/apps/ecmascript-regression/client/main.css
Normal file
@@ -0,0 +1,4 @@
|
||||
body {
|
||||
padding: 10px;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
7
tools/tests/apps/ecmascript-regression/client/main.html
Normal file
7
tools/tests/apps/ecmascript-regression/client/main.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<head>
|
||||
<title>escmascript-regression</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="react-target"></div>
|
||||
</body>
|
||||
8
tools/tests/apps/ecmascript-regression/client/main.jsx
Normal file
8
tools/tests/apps/ecmascript-regression/client/main.jsx
Normal file
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { render } from 'react-dom';
|
||||
import { App } from '/imports/ui/App';
|
||||
|
||||
Meteor.startup(() => {
|
||||
render(<App/>, document.getElementById('react-target'));
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import React from 'react';
|
||||
import { Hello } from './Hello.jsx';
|
||||
|
||||
export const App = () => (
|
||||
<div>
|
||||
<h1>Welcome to Meteor!</h1>
|
||||
<Hello />
|
||||
</div>
|
||||
);
|
||||
16
tools/tests/apps/ecmascript-regression/imports/ui/Hello.jsx
Normal file
16
tools/tests/apps/ecmascript-regression/imports/ui/Hello.jsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import React, { useState } from 'react';
|
||||
|
||||
export const Hello = () => {
|
||||
const [counter, setCounter] = useState(0);
|
||||
|
||||
const increment = () => {
|
||||
setCounter(counter + 1);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button onClick={increment}>Click Me</button>
|
||||
<p>You've pressed the button {counter} times.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
1248
tools/tests/apps/ecmascript-regression/package-lock.json
generated
Normal file
1248
tools/tests/apps/ecmascript-regression/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
23
tools/tests/apps/ecmascript-regression/package.json
Normal file
23
tools/tests/apps/ecmascript-regression/package.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "escmascript-regression",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "meteor run",
|
||||
"test": "meteor test --driver-package meteortesting:mocha",
|
||||
"test-app": "TEST_WATCH=1 meteor test --full-app --driver-package meteortesting:mocha --exclude-archs web.browser"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.15.3",
|
||||
"meteor-node-stubs": "^1.1.0",
|
||||
"puppeteer": "^10.4.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2"
|
||||
},
|
||||
"meteor": {
|
||||
"mainModule": {
|
||||
"client": "client/main.jsx",
|
||||
"server": "server/main.js"
|
||||
},
|
||||
"testModule": "tests/main.js"
|
||||
}
|
||||
}
|
||||
1
tools/tests/apps/ecmascript-regression/server/main.js
Normal file
1
tools/tests/apps/ecmascript-regression/server/main.js
Normal file
@@ -0,0 +1 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
27
tools/tests/apps/ecmascript-regression/tests/main.js
Normal file
27
tools/tests/apps/ecmascript-regression/tests/main.js
Normal file
@@ -0,0 +1,27 @@
|
||||
import assert from 'assert';
|
||||
|
||||
describe('escmascript-regression', function() {
|
||||
if (Meteor.isClient) {
|
||||
it('NodeList spread', function() {
|
||||
const div = document.createElement('div');
|
||||
document.body.appendChild(div);
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const child = document.createElement('div');
|
||||
child.innerText = `child ${i}`;
|
||||
div.appendChild(child);
|
||||
}
|
||||
|
||||
try {
|
||||
assert.strictEqual(div.childNodes?.length, 5);
|
||||
const arr = [...div.childNodes];
|
||||
|
||||
arr.forEach((el, i) => {
|
||||
assert.equal(el.innerText, `child ${i}`);
|
||||
});
|
||||
} finally {
|
||||
document.body.removeChild(div);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1,51 +1,54 @@
|
||||
var selftest = require('../tool-testing/selftest.js');
|
||||
var Sandbox = selftest.Sandbox;
|
||||
var utils = require('../utils/utils.js');
|
||||
import { getUrl } from '../utils/http-helpers.js';
|
||||
|
||||
var MONGO_LISTENING =
|
||||
{ stdout: " [initandlisten] waiting for connections on port" };
|
||||
var MONGO_LISTENING = {
|
||||
stdout: ' [initandlisten] waiting for connections on port',
|
||||
};
|
||||
|
||||
function startRun(sandbox) {
|
||||
var run = sandbox.run();
|
||||
run.match("myapp");
|
||||
run.match("proxy");
|
||||
run.match('myapp');
|
||||
run.match('proxy');
|
||||
run.tellMongo(MONGO_LISTENING);
|
||||
run.waitSecs(20);
|
||||
run.match("MongoDB");
|
||||
run.match('MongoDB');
|
||||
return run;
|
||||
};
|
||||
}
|
||||
|
||||
selftest.define("modules - test app", function () {
|
||||
selftest.define('modules - test app', function() {
|
||||
const s = new Sandbox();
|
||||
|
||||
// Make sure we use the right "env" section of .babelrc.
|
||||
s.set("NODE_ENV", "development");
|
||||
s.set('NODE_ENV', 'development');
|
||||
|
||||
// For meteortesting:mocha to work we must set test broswer driver
|
||||
// For meteortesting:mocha to work we must set test browser driver
|
||||
// See https://github.com/meteortesting/meteor-mocha
|
||||
s.set("TEST_BROWSER_DRIVER", "puppeteer");
|
||||
s.set('TEST_BROWSER_DRIVER', 'puppeteer');
|
||||
|
||||
s.createApp("modules-test-app", "modules");
|
||||
s.cd("modules-test-app", function () {
|
||||
s.createApp('modules-test-app', 'modules');
|
||||
s.cd('modules-test-app', function() {
|
||||
const run = s.run(
|
||||
"test", "--once", "--full-app",
|
||||
"--driver-package", "meteortesting:mocha"
|
||||
'test',
|
||||
'--once',
|
||||
'--full-app',
|
||||
'--driver-package',
|
||||
'meteortesting:mocha'
|
||||
);
|
||||
|
||||
run.waitSecs(60);
|
||||
run.match("App running at");
|
||||
run.match("SERVER FAILURES: 0");
|
||||
run.match("CLIENT FAILURES: 0");
|
||||
run.match('App running at');
|
||||
run.match('SERVER FAILURES: 0');
|
||||
run.match('CLIENT FAILURES: 0');
|
||||
run.expectExit(0);
|
||||
});
|
||||
});
|
||||
|
||||
selftest.define("modules - unimported lazy files", function() {
|
||||
selftest.define('modules - unimported lazy files', function() {
|
||||
const s = new Sandbox();
|
||||
s.createApp("myapp", "app-with-unimported-lazy-file");
|
||||
s.cd("myapp", function() {
|
||||
const run = s.run("--once");
|
||||
s.createApp('myapp', 'app-with-unimported-lazy-file');
|
||||
s.cd('myapp', function() {
|
||||
const run = s.run('--once');
|
||||
run.waitSecs(30);
|
||||
run.expectExit(1);
|
||||
run.forbid("This file shouldn't be loaded");
|
||||
@@ -55,43 +58,47 @@ selftest.define("modules - unimported lazy files", function() {
|
||||
// Checks that `import X from 'meteor/package'` will import (and re-export) the
|
||||
// mainModule if one exists, otherwise will simply export Package['package'].
|
||||
// Overlaps with compiler-plugin.js's "install-packages.js" code.
|
||||
selftest.define("modules - import chain for packages", () => {
|
||||
selftest.define('modules - import chain for packages', () => {
|
||||
const s = new Sandbox({ fakeMongo: true });
|
||||
|
||||
s.createApp("myapp", "package-tests");
|
||||
s.cd("myapp");
|
||||
s.createApp('myapp', 'package-tests');
|
||||
s.cd('myapp');
|
||||
|
||||
s.write(".meteor/packages", [
|
||||
"meteor-base",
|
||||
"modules",
|
||||
"with-add-files",
|
||||
"with-main-module",
|
||||
""
|
||||
].join("\n"));
|
||||
s.write(
|
||||
'.meteor/packages',
|
||||
['meteor-base', 'modules', 'with-add-files', 'with-main-module', ''].join(
|
||||
'\n'
|
||||
)
|
||||
);
|
||||
|
||||
s.write("main.js", [
|
||||
"var packageNameA = require('meteor/with-add-files').name;",
|
||||
"var packageNameB = require('meteor/with-main-module').name;",
|
||||
"",
|
||||
"console.log('with-add-files: ' + packageNameA);",
|
||||
"console.log('with-main-module: ' + packageNameB);",
|
||||
""
|
||||
].join("\n"));
|
||||
s.write(
|
||||
'main.js',
|
||||
[
|
||||
"var packageNameA = require('meteor/with-add-files').name;",
|
||||
"var packageNameB = require('meteor/with-main-module').name;",
|
||||
'',
|
||||
"console.log('with-add-files: ' + packageNameA);",
|
||||
"console.log('with-main-module: ' + packageNameB);",
|
||||
'',
|
||||
].join('\n')
|
||||
);
|
||||
|
||||
const run = startRun(s);
|
||||
|
||||
run.waitSecs(30);
|
||||
|
||||
// On the server, we just check that importing *works*, not *how* it works
|
||||
run.match("with-add-files: with-add-files");
|
||||
run.match("with-main-module: with-main-module");
|
||||
run.match('with-add-files: with-add-files');
|
||||
run.match('with-main-module: with-main-module');
|
||||
|
||||
// On the client, we just check that install() is called correctly
|
||||
checkModernAndLegacyUrls("/packages/modules.js", body => {
|
||||
checkModernAndLegacyUrls('/packages/modules.js', body => {
|
||||
selftest.expectTrue(body.includes('\ninstall("with-add-files");'));
|
||||
selftest.expectTrue(
|
||||
body.includes('\ninstall("with-main-module", ' +
|
||||
'"meteor/with-main-module/with-main-module.js");')
|
||||
body.includes(
|
||||
'\ninstall("with-main-module", ' +
|
||||
'"meteor/with-main-module/with-main-module.js");'
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
@@ -99,9 +106,9 @@ selftest.define("modules - import chain for packages", () => {
|
||||
});
|
||||
|
||||
function checkModernAndLegacyUrls(path, test) {
|
||||
if (! path.startsWith("/")) {
|
||||
path = "/" + path;
|
||||
if (!path.startsWith('/')) {
|
||||
path = '/' + path;
|
||||
}
|
||||
test(getUrl("http://localhost:3000" + path));
|
||||
test(getUrl("http://localhost:3000/__browser.legacy" + path));
|
||||
test(getUrl('http://localhost:3000' + path));
|
||||
test(getUrl('http://localhost:3000/__browser.legacy' + path));
|
||||
}
|
||||
|
||||
32
tools/tests/regressions.js
Normal file
32
tools/tests/regressions.js
Normal file
@@ -0,0 +1,32 @@
|
||||
var selftest = require('../tool-testing/selftest.js');
|
||||
var Sandbox = selftest.Sandbox;
|
||||
|
||||
selftest.define('regressions - web.browser.legacy', function() {
|
||||
const s = new Sandbox();
|
||||
|
||||
// Make sure we use the right "env" section of .babelrc.
|
||||
s.set('NODE_ENV', 'development');
|
||||
|
||||
// For meteortesting:mocha to work we must set test browser driver
|
||||
// See https://github.com/meteortesting/meteor-mocha
|
||||
s.set('TEST_BROWSER_DRIVER', 'puppeteer');
|
||||
|
||||
s.createApp('modules-test-app', 'ecmascript-regression');
|
||||
s.cd('modules-test-app', function() {
|
||||
const run = s.run(
|
||||
'test',
|
||||
'--once',
|
||||
'--full-app',
|
||||
'--driver-package',
|
||||
'meteortesting:mocha',
|
||||
'--exclude-archs',
|
||||
'web.browser'
|
||||
);
|
||||
|
||||
run.waitSecs(60);
|
||||
run.match('App running at');
|
||||
run.match('SERVER FAILURES: 0');
|
||||
run.match('CLIENT FAILURES: 0');
|
||||
run.expectExit(0);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user