mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Merge remote-tracking branch 'origin/release-3.0-fix-ci-tests' into release-3.0-fix-ci-tests
This commit is contained in:
@@ -100,7 +100,7 @@ can_disable_fibers: &can_disable_fibers
|
||||
parameters:
|
||||
fibers:
|
||||
type: boolean
|
||||
default: true
|
||||
default: false # now is always off
|
||||
|
||||
set_fibers_env: &set_fibers_env
|
||||
name: "Disable Fibers"
|
||||
@@ -700,6 +700,7 @@ jobs:
|
||||
path: /tmp/memuse.txt
|
||||
|
||||
Test Group 11:
|
||||
<<: *can_disable_fibers
|
||||
<<: *build_machine_environment
|
||||
steps:
|
||||
- run:
|
||||
@@ -708,6 +709,7 @@ jobs:
|
||||
<<: *run_env_change
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run: *set_fibers_env
|
||||
- run:
|
||||
name: "Print environment"
|
||||
command: printenv
|
||||
@@ -910,6 +912,7 @@ workflows:
|
||||
requires:
|
||||
- Get Ready
|
||||
- Test Group 11:
|
||||
<<: *matrix_for_fibers
|
||||
requires:
|
||||
- Get Ready
|
||||
- Clean Up:
|
||||
|
||||
@@ -1,125 +1,158 @@
|
||||
|
||||
|
||||
## v3.0, TBD
|
||||
|
||||
### Highlights
|
||||
|
||||
#### Breaking Changes
|
||||
|
||||
* `webapp`:
|
||||
- These methods are now async:
|
||||
- `WebAppInternals.reloadClientPrograms()`
|
||||
- `WebAppInternals.pauseClient()`
|
||||
- `WebAppInternals.generateClientProgram()`
|
||||
- `WebAppInternals.generateBoilerplate()`
|
||||
- `WebAppInternals.setInlineScriptsAllowed()`
|
||||
- `WebAppInternals.enableSubresourceIntegrity()`
|
||||
- `WebAppInternals.setBundledJsCssUrlRewriteHook()`
|
||||
- `WebAppInternals.setBundledJsCssPrefix()`
|
||||
- `webapp`:
|
||||
|
||||
* `email`:
|
||||
- `Email.send` is no longer available. Use `Email.sendAsync` instead.
|
||||
- These methods are now async:
|
||||
- `WebAppInternals.reloadClientPrograms()`
|
||||
- `WebAppInternals.pauseClient()`
|
||||
- `WebAppInternals.generateClientProgram()`
|
||||
- `WebAppInternals.generateBoilerplate()`
|
||||
- `WebAppInternals.setInlineScriptsAllowed()`
|
||||
- `WebAppInternals.enableSubresourceIntegrity()`
|
||||
- `WebAppInternals.setBundledJsCssUrlRewriteHook()`
|
||||
- `WebAppInternals.setBundledJsCssPrefix()`
|
||||
|
||||
* `accounts-2fa`:
|
||||
- Some methods are now async. See below:
|
||||
- `Accounts._is2faEnabledForUser`
|
||||
- `(Meteor Method) - generate2faActivationQrCode`
|
||||
- `(Meteor Method) - enableUser2fa`
|
||||
- `(Meteor Method) - disableUser2fa`
|
||||
- `(Meteor Method) - has2faEnabled`
|
||||
- `email`:
|
||||
|
||||
* `accounts-base`:
|
||||
**TODO**
|
||||
- `methods.removeOtherTokens` is now async
|
||||
- `Accounts.destroyToken` is now async
|
||||
- `Email.send` is no longer available. Use `Email.sendAsync` instead.
|
||||
|
||||
* `accounts-password`:
|
||||
- Some server methods are now async:
|
||||
- `Accounts.sendResetPasswordEmail`
|
||||
- `Accounts.sendEnrollmentEmail`
|
||||
- `Accounts.sendVerificationEmail`
|
||||
- `Accounts.addEmail`
|
||||
- `Accounts.removeEmail`
|
||||
- `Accounts.verifyEmail`
|
||||
- `Accounts.createUserVerifyingEmail`
|
||||
- `Accounts.createUser`
|
||||
- `Accounts.generateVerificationToken`
|
||||
- `Accounts.generateResetToken`
|
||||
- `Accounts.forgotPassword`
|
||||
- `Accounts.setPassword`
|
||||
- `Accounts.changePassword`
|
||||
- `Accounts.setUsername`
|
||||
- `Accounts.findUserByEmail`
|
||||
- `Accounts.findUserByUsername`
|
||||
- `accounts-2fa`:
|
||||
|
||||
* `accounts-passwordless`:
|
||||
- `Accounts.sendLoginTokenEmail` is now async
|
||||
- Some methods are now async. See below:
|
||||
- `Accounts._is2faEnabledForUser`
|
||||
- `(Meteor Method) - generate2faActivationQrCode`
|
||||
- `(Meteor Method) - enableUser2fa`
|
||||
- `(Meteor Method) - disableUser2fa`
|
||||
- `(Meteor Method) - has2faEnabled`
|
||||
|
||||
* `boilerplate-generator`:
|
||||
- `toHTML` is no longer available (it was already deprecated). Use `toHTMLStream` instead.
|
||||
- `accounts-base`:
|
||||
|
||||
* `ddp`:
|
||||
- Added method `Meteor.isAsyncCall` that can be used to check if the current method call is async or not.
|
||||
- `methods.removeOtherTokens` is now async
|
||||
- `Accounts.destroyToken` is now async
|
||||
|
||||
* `oauth`:
|
||||
- `_endOfPopupResponseTemplate` and `_endOfRedirectResponseTemplate` are no longer a property but now a function that returns a promise of the same value as before
|
||||
- the following server methods are now async:
|
||||
- `OAuth._renderOauthResults`
|
||||
- `OAuth._endOfLoginResponse`
|
||||
- `OAuth.renderEndOfLoginResponse`
|
||||
- `OAuth._storePendingCredential`
|
||||
- `OAuth._retrievePendingCredential`
|
||||
- `ensureConfigured`
|
||||
- `_cleanStaleResults`
|
||||
- `accounts-password`:
|
||||
|
||||
* `oauth1`:
|
||||
- the following server methods are now async:
|
||||
- `OAuth._storeRequestToken`
|
||||
- `OAuth._retrieveRequestToken`
|
||||
- Some server methods are now async:
|
||||
- `Accounts.sendResetPasswordEmail`
|
||||
- `Accounts.sendEnrollmentEmail`
|
||||
- `Accounts.sendVerificationEmail`
|
||||
- `Accounts.addEmail`
|
||||
- `Accounts.removeEmail`
|
||||
- `Accounts.verifyEmail`
|
||||
- `Accounts.createUserVerifyingEmail`
|
||||
- `Accounts.createUser`
|
||||
- `Accounts.generateVerificationToken`
|
||||
- `Accounts.generateResetToken`
|
||||
- `Accounts.forgotPassword`
|
||||
- `Accounts.setPassword`
|
||||
- `Accounts.changePassword`
|
||||
- `Accounts.setUsername`
|
||||
- `Accounts.findUserByEmail`
|
||||
- `Accounts.findUserByUsername`
|
||||
|
||||
* `oauth2`:
|
||||
- `OAuth._requestHandlers['2']` is now async.
|
||||
- `accounts-passwordless`:
|
||||
|
||||
* `minifier-css`:
|
||||
- `minifyCss` is now async.
|
||||
- `Accounts.sendLoginTokenEmail` is now async
|
||||
|
||||
* `webapp`:
|
||||
- `WebAppInternals.getBoilerplate` is now async.
|
||||
- Changed engine from connect to express and changed api naming to match express. See below:
|
||||
- `WebApp.connectHandlers.use(middleware)` is now `WebApp.expressHandlers.use(middleware)`
|
||||
- `WebApp.rawConnectHandlers.use(middleware)` is now `WebApp.rawExpressHandlers.use(middleware)`
|
||||
- `WebApp.connectApp` is now `WebApp.expressApp`
|
||||
- `boilerplate-generator`:
|
||||
|
||||
#### Internal API changes
|
||||
- `toHTML` is no longer available (it was already deprecated). Use `toHTMLStream` instead.
|
||||
|
||||
- `ddp`:
|
||||
|
||||
- Added method `Meteor.isAsyncCall` that can be used to check if the current method call is async or not.
|
||||
|
||||
- `oauth`:
|
||||
|
||||
- `_endOfPopupResponseTemplate` and `_endOfRedirectResponseTemplate` are no longer a property but now a function that returns a promise of the same value as before
|
||||
- the following server methods are now async:
|
||||
- `OAuth._renderOauthResults`
|
||||
- `OAuth._endOfLoginResponse`
|
||||
- `OAuth.renderEndOfLoginResponse`
|
||||
- `OAuth._storePendingCredential`
|
||||
- `OAuth._retrievePendingCredential`
|
||||
- `ensureConfigured`
|
||||
- `_cleanStaleResults`
|
||||
|
||||
- `oauth1`:
|
||||
|
||||
- the following server methods are now async:
|
||||
- `OAuth._storeRequestToken`
|
||||
- `OAuth._retrieveRequestToken`
|
||||
|
||||
- `oauth2`:
|
||||
|
||||
- `OAuth._requestHandlers['2']` is now async.
|
||||
|
||||
- `minifier-css`:
|
||||
|
||||
- `minifyCss` is now async.
|
||||
|
||||
- `webapp`:
|
||||
- `WebAppInternals.getBoilerplate` is now async.
|
||||
- Changed engine from connect to express and changed api naming to match express. See below:
|
||||
- `WebApp.connectHandlers.use(middleware)` is now `WebApp.expressHandlers.use(middleware)`
|
||||
- `WebApp.rawConnectHandlers.use(middleware)` is now `WebApp.rawExpressHandlers.use(middleware)`
|
||||
- `WebApp.connectApp` is now `WebApp.expressApp`
|
||||
|
||||
* `minimongo@get-version`:
|
||||
TODO: add this aswell to the minimongo docs
|
||||
- `cursor.observe` now returns `isReady` and `isReadyPromise` wich indicates
|
||||
if the cursor is ready and if the callbacks are have been called.
|
||||
If you only use it in the `Client` or as a `LocalCollection` things have not
|
||||
changed.
|
||||
|
||||
|
||||
#### Migration Steps
|
||||
#### New Public API
|
||||
|
||||
You can follow in [here](https://guide.meteor.com/3.0-migration.html).
|
||||
- `accounts-base`: (2.9+)
|
||||
- `Meteor.userAsync()`
|
||||
|
||||
#### Meteor Version Release
|
||||
- `callback-hook`:forEachAsync
|
||||
- `forEachAsync`
|
||||
|
||||
#### Special thanks to
|
||||
- `ddp-server`: (2.8+)
|
||||
- `Meteor.callAsync()`
|
||||
|
||||
For making this great framework even better!ifier-css`:
|
||||
- `minifyCss` is now async.
|
||||
- `minifier-css`: (2.9+)
|
||||
- `CssTools.minifyCssAsync()`
|
||||
|
||||
* `webapp`:
|
||||
- `WebAppInternals.getBoilerplate` is now async.
|
||||
- Changed engine from connect to express and changed api naming to match express. See below:
|
||||
- `WebApp.connectHandlers.use(middleware)` is now `WebApp.expressHandlers.use(middleware)`
|
||||
- `WebApp.rawConnectHandlers.use(middleware)` is now `WebApp.rawExpressHandlers.use(middleware)`
|
||||
- `WebApp.connectApp` is now `WebApp.expressApp`
|
||||
- `mongo`:
|
||||
|
||||
#### Internal API changes
|
||||
- `Mongo.Collection`: (2.8+)
|
||||
- `createCappedCollectionAsync`
|
||||
- `createIndexAsync`
|
||||
- `dropCollectionAsync`
|
||||
- `dropIndexAsync`
|
||||
- `findOneAsync`
|
||||
- `insertAsync`
|
||||
- `removeAsync`
|
||||
- `updateAsync`
|
||||
- `upsertAsync`
|
||||
- `Collection.Cursor`: (2.8+)
|
||||
- `countAsync`
|
||||
- `fetchAsync`
|
||||
- `forEachAsync`
|
||||
- `mapAsync`
|
||||
- `[Symbol.asyncIterator]` so this code should work:
|
||||
```js
|
||||
for await (const document of collection.find(query, options)) /* ... */
|
||||
```
|
||||
|
||||
#### Internal API changes
|
||||
|
||||
#### Migration Steps
|
||||
`accounts-base`:
|
||||
|
||||
You can follow in [here](https://guide.meteor.com/3.0-migration.html).
|
||||
- `_attemptLogin`
|
||||
- `_loginMethod`
|
||||
- `_runLoginHandlers`
|
||||
|
||||
#### Meteor Version Release
|
||||
#### New Internal API
|
||||
|
||||
#### Special thanks to
|
||||
`accounts-password`:
|
||||
|
||||
For making this great framework even better!
|
||||
- `Accounts._checkPasswordAsync`
|
||||
|
||||
2840
npm-packages/meteor-babel/package-lock.json
generated
2840
npm-packages/meteor-babel/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -41,7 +41,7 @@
|
||||
"@babel/template": "^7.16.7",
|
||||
"@babel/traverse": "^7.17.0",
|
||||
"@babel/types": "^7.17.0",
|
||||
"@meteorjs/reify": "https://github.com/meteor/reify/tarball/ee36898798645097948258eb9106dd0af60cec64",
|
||||
"@meteorjs/reify": "https://github.com/meteor/reify/tarball/0867be73ca61e87ae9d60edef62baf26b38719ef",
|
||||
"babel-preset-meteor": "^7.10.0",
|
||||
"babel-preset-minify": "^0.5.1",
|
||||
"convert-source-map": "^1.6.0",
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"no-console": "off",
|
||||
"camelcase": "warn",
|
||||
"consistent-return": "off",
|
||||
"quotes": "warn",
|
||||
"quotes": ["warn", "single", { "allowTemplateLiterals": true }],
|
||||
"no-shadow": [
|
||||
"error",
|
||||
{
|
||||
|
||||
@@ -94,7 +94,8 @@ BCp.processOneFileForTarget = function (inputFile, source) {
|
||||
features.modernBrowsers = true;
|
||||
}
|
||||
|
||||
features.topLevelAwait = arch.startsWith('os.') || enableClientTLA
|
||||
features.topLevelAwait = inputFile.supportsTopLevelAwait &&
|
||||
(arch.startsWith('os.') || enableClientTLA);
|
||||
|
||||
features.useNativeAsyncAwait = Meteor.isFibersDisabled;
|
||||
|
||||
|
||||
@@ -83,9 +83,7 @@ function runEagerModules(config, callback) {
|
||||
|
||||
var path = config.eagerModulePaths[index];
|
||||
var exports = config.require(path);
|
||||
// TODO[fibers]: retest the function checkAsyncModule. It looks like it's returning the wrong values
|
||||
// returning false when exports is a promise
|
||||
if (exports && exports.then) {
|
||||
if (checkAsyncModule(exports)) {
|
||||
if (path === config.mainModulePath) {
|
||||
mainModuleAsync = true;
|
||||
}
|
||||
@@ -127,15 +125,14 @@ function runEagerModules(config, callback) {
|
||||
}
|
||||
|
||||
function checkAsyncModule (exports) {
|
||||
// Uses property descriptor to avoid running any getters
|
||||
var isPromise = exports && hasOwn.call(exports, 'then') &&
|
||||
typeof Object.getOwnPropertyDescriptor(exports, 'then').value === 'function';
|
||||
var potentiallyAsync = exports && typeof exports === 'object' &&
|
||||
hasOwn.call(exports, '__reifyAsyncModule');
|
||||
|
||||
if (!isPromise) {
|
||||
return false;
|
||||
if (!potentiallyAsync) {
|
||||
return;
|
||||
}
|
||||
|
||||
return hasOwn.call(exports, '__reifyAsyncModule');
|
||||
return typeof exports.then === 'function';
|
||||
}
|
||||
|
||||
// For this to be accurate, all linked files must be queued before calling this
|
||||
|
||||
@@ -333,7 +333,7 @@ export default class Cursor {
|
||||
}
|
||||
// it means it's an id map
|
||||
if (query.results?.size?.()) {
|
||||
query.results.forEachAsync(handler);
|
||||
query.results.forEach(handler);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,14 +361,15 @@ export default class Cursor {
|
||||
|
||||
// run the observe callbacks resulting from the initial contents
|
||||
// before we leave the observe.
|
||||
const isReadyPromise = this.collection._observeQueue.drain();
|
||||
const drainResult = this.collection._observeQueue.drain();
|
||||
|
||||
if (Meteor.isClient) handle.isReady = true;
|
||||
else isReadyPromise.then(() => (handle.isReady = true));
|
||||
|
||||
handle.isReadyPromise = Meteor.isClient
|
||||
? Promise.resolve()
|
||||
: isReadyPromise;
|
||||
if (drainResult instanceof Promise) {
|
||||
handle.isReadyPromise = drainResult;
|
||||
drainResult.then(() => (handle.isReady = true));
|
||||
} else {
|
||||
handle.isReady = true;
|
||||
handle.isReadyPromise = Promise.resolve();
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
@@ -1651,11 +1651,8 @@ LocalCollection._observeFromObserveChanges = (cursor, observeCallbacks) => {
|
||||
{ nonMutatingCallbacks: true });
|
||||
|
||||
// If needed, re-enable callbacks as soon as the initial batch is ready.
|
||||
if (suppressed) {
|
||||
handle.isReadyPromise.then(() => {
|
||||
suppressed = false;
|
||||
});
|
||||
}
|
||||
if (handle.isReady) suppressed = false;
|
||||
else handle.isReadyPromise.then(() => (suppressed = false));
|
||||
|
||||
return handle;
|
||||
};
|
||||
|
||||
@@ -1895,12 +1895,12 @@ Tinytest.addAsync('minimongo - observe ordered with projection', async test => {
|
||||
test.equal(operations.shift(), undefined);
|
||||
|
||||
const cursor = c.find({}, {fields: {a: 1, _id: 0}});
|
||||
await test.throwsAsync(async () => {
|
||||
await cursor.observeChanges({ added() {} });
|
||||
});
|
||||
test.throws(() => {
|
||||
cursor.observe({ added() {} });
|
||||
});
|
||||
test.throws(() => {
|
||||
cursor.observeChanges({ added() {} });
|
||||
});
|
||||
test.throws(() => {
|
||||
cursor.observe({ added() {} });
|
||||
});
|
||||
|
||||
// test initial inserts (and backwards sort)
|
||||
handle = c.find({}, {sort: {a: -1}, fields: { a: 1 } }).observe(cbs);
|
||||
@@ -3790,11 +3790,11 @@ Tinytest.add('minimongo - update should clone', test => {
|
||||
Tinytest.addAsync("minimongo - fetch in observe", (test, done) => {
|
||||
const coll = new LocalCollection();
|
||||
let callbackInvoked = false;
|
||||
coll.find().observeChanges({
|
||||
async added(id, fields) {
|
||||
const observe = coll.find().observeChanges({
|
||||
added(id, fields) {
|
||||
callbackInvoked = true;
|
||||
test.equal(fields, { foo: 1 }, "equals fields");
|
||||
const doc = await coll.findOneAsync({ foo: 1 });
|
||||
test.equal(fields, { foo: 1 });
|
||||
const doc = coll.findOne({ foo: 1 });
|
||||
test.isTrue(doc);
|
||||
test.equal(doc.foo, 1);
|
||||
},
|
||||
@@ -3812,6 +3812,22 @@ Tinytest.addAsync("minimongo - fetch in observe", (test, done) => {
|
||||
});
|
||||
});
|
||||
|
||||
Tinytest.add("minimongo - simple reactivity", (test) => {
|
||||
const coll = new LocalCollection();
|
||||
let runs = 0;
|
||||
|
||||
Tracker.autorun(() => {
|
||||
runs += 1;
|
||||
coll.find().fetch()
|
||||
});
|
||||
|
||||
coll.insert({ _id: "test" });
|
||||
Tracker.flush();
|
||||
// runs should now be 2
|
||||
test.equal(runs, 2);
|
||||
});
|
||||
|
||||
|
||||
// See #2254
|
||||
Tinytest.addAsync(
|
||||
"minimongo - fine-grained reactivity of observe with fields projection",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"@meteorjs/reify": {
|
||||
"version": "git+https://github.com/meteor/reify.git#ee36898798645097948258eb9106dd0af60cec64"
|
||||
"version": "git+https://github.com/meteor/reify.git#0867be73ca61e87ae9d60edef62baf26b38719ef"
|
||||
},
|
||||
"@types/estree": {
|
||||
"version": "1.0.0",
|
||||
|
||||
@@ -6,7 +6,7 @@ Package.describe({
|
||||
});
|
||||
|
||||
Npm.depends({
|
||||
"@meteorjs/reify": "git+https://github.com/meteor/reify.git#ee36898798645097948258eb9106dd0af60cec64",
|
||||
"@meteorjs/reify": "git+https://github.com/meteor/reify.git#0867be73ca61e87ae9d60edef62baf26b38719ef",
|
||||
"meteor-babel-helpers": "0.0.3",
|
||||
});
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ async function runNextUrl(browser) {
|
||||
console.log(`
|
||||
The number of tests from Test number may be different because
|
||||
of the way the test is written. causing the test to fail or
|
||||
to run more than once. in the console. Test number total: ${ testNumber }`);
|
||||
to run more than once. in the console. Test number total: ${ testNumber }`);
|
||||
console.log(`Tests complete with ${ failCount } failures`);
|
||||
console.log(`Tests complete with ${ await getPassCount(page) } passes`);
|
||||
if (failCount > 0) {
|
||||
|
||||
@@ -239,6 +239,13 @@ class InputFile extends buildPluginModule.InputFile {
|
||||
// accept a lazy finalizer function as a second argument, so that
|
||||
// compilation can be avoided until/unless absolutely necessary.
|
||||
this.supportsLazyCompilation = true;
|
||||
|
||||
// Communicate to compiler plugins that this version of Meteor
|
||||
// is able to support top level await
|
||||
// TODO: maybe this should also check if the file and package meet the
|
||||
// minimum requirements to use top level await (file isn't bare, and
|
||||
// package uses core-runtime and modules)
|
||||
this.supportsTopLevelAwait = true;
|
||||
}
|
||||
|
||||
getContentsAsBuffer() {
|
||||
|
||||
@@ -410,7 +410,7 @@ const loadServerBundles = Profile("Load server bundles", async function () {
|
||||
const scriptPath =
|
||||
parsedSourceMaps[absoluteFilePath] ? absoluteFilePath : fileInfoOSPath;
|
||||
|
||||
const func = await require('vm').runInThisContext(wrapped, {
|
||||
const func = require('vm').runInThisContext(wrapped, {
|
||||
filename: scriptPath,
|
||||
displayErrors: true
|
||||
});
|
||||
@@ -428,14 +428,14 @@ const loadServerBundles = Profile("Load server bundles", async function () {
|
||||
});
|
||||
} else {
|
||||
// Allows us to use code-coverage if the debugger is not enabled
|
||||
await Profile(fileInfo.path, func).apply(global, args);
|
||||
Profile(fileInfo.path, func).apply(global, args);
|
||||
}
|
||||
}
|
||||
|
||||
await maybeWaitForDebuggerToAttach();
|
||||
|
||||
for (const info of infos) {
|
||||
await info.fn.apply(global, info.args);
|
||||
info.fn.apply(global, info.args);
|
||||
}
|
||||
if (global.Package['core-runtime']) {
|
||||
return global.Package['core-runtime'].waitUntilAllLoaded();
|
||||
@@ -509,5 +509,3 @@ var runMain = Profile("Run main()", async function () {
|
||||
console.log(e.stack);
|
||||
process.exit(1)
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ selftest.define("testModule", async function () {
|
||||
await s.init();
|
||||
|
||||
await s.createApp("app-config-mainModule", "app-config");
|
||||
s.cd("app-config-mainModule");
|
||||
await s.cd("app-config-mainModule");
|
||||
|
||||
// For meteortesting:mocha to work we must set test broswer driver
|
||||
// See https://github.com/meteortesting/meteor-mocha
|
||||
@@ -160,7 +160,8 @@ selftest.define("testModule", async function () {
|
||||
"test",
|
||||
// Not running with the --full-app option here, in order to exercise
|
||||
// the normal `meteor test` behavior.
|
||||
"--driver-package", "meteortesting:mocha"
|
||||
/// TODO: Fibers => turn this back to meteortesthing:mocha when 3.0.0 is released
|
||||
"--driver-package", "grubba:mocha" /// meteortesting:mocha"
|
||||
);
|
||||
|
||||
run.waitSecs(60);
|
||||
|
||||
@@ -12,3 +12,4 @@ es5-shim # ECMAScript 5 compatibility for older browsers
|
||||
ecmascript # Enable ECMAScript2015+ syntax in app code
|
||||
shell-server # Server-side component of the `meteor shell` command
|
||||
less # Support .less files for defining CSS styles
|
||||
grubba:mocha
|
||||
|
||||
@@ -62,3 +62,4 @@ underscore@1.0.11
|
||||
url@1.2.0
|
||||
webapp@1.5.0
|
||||
webapp-hashing@1.0.9
|
||||
grubba:mocha@3.0.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
jshint@0.0.1
|
||||
jshint@1.1.8
|
||||
linter-plugin@1.0.0
|
||||
meteor@1.1.6
|
||||
my-package@0.0.0
|
||||
|
||||
1
tools/tests/apps/top-level-await-order/.meteor/.gitignore
vendored
Normal file
1
tools/tests/apps/top-level-await-order/.meteor/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
local
|
||||
16
tools/tests/apps/top-level-await-order/.meteor/packages
Normal file
16
tools/tests/apps/top-level-await-order/.meteor/packages
Normal file
@@ -0,0 +1,16 @@
|
||||
# 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.
|
||||
print
|
||||
meteor-base # Packages every Meteor app needs to have
|
||||
|
||||
ecmascript # Enable ECMAScript2015+ syntax in app code
|
||||
build-plugin
|
||||
webapp
|
||||
sync-package
|
||||
package-1
|
||||
package-2
|
||||
lazy-package
|
||||
standard-minifier-js
|
||||
1
tools/tests/apps/top-level-await-order/.meteor/release
Normal file
1
tools/tests/apps/top-level-await-order/.meteor/release
Normal file
@@ -0,0 +1 @@
|
||||
none
|
||||
7
tools/tests/apps/top-level-await-order/a.js
Normal file
7
tools/tests/apps/top-level-await-order/a.js
Normal file
@@ -0,0 +1,7 @@
|
||||
console.log('app a.js - before');
|
||||
await 0
|
||||
console.log('app a.js - after');
|
||||
|
||||
Promise.resolve().then(() => {
|
||||
console.log('app a.js - later');
|
||||
});
|
||||
7
tools/tests/apps/top-level-await-order/b.js
Normal file
7
tools/tests/apps/top-level-await-order/b.js
Normal file
@@ -0,0 +1,7 @@
|
||||
console.log('app b.js - before');
|
||||
await 0
|
||||
console.log('app b.js - after');
|
||||
|
||||
Promise.resolve().then(() => {
|
||||
console.log('app b.js - later');
|
||||
});
|
||||
18
tools/tests/apps/top-level-await-order/main.js
Normal file
18
tools/tests/apps/top-level-await-order/main.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import './a.js';
|
||||
import './b.js';
|
||||
|
||||
Meteor.startup(() => {
|
||||
console.log('entry - startup');
|
||||
});
|
||||
|
||||
console.log('entry - before');
|
||||
await 0
|
||||
console.log('entry - after');
|
||||
|
||||
Promise.resolve().then(() => console.log('entry - later'));
|
||||
|
||||
require('meteor/lazy-package').then(({ value }) => {
|
||||
console.log(`lazy package value ${value}`);
|
||||
});
|
||||
|
||||
console.log(`package 2 value ${require('meteor/package-2').value}`);
|
||||
20
tools/tests/apps/top-level-await-order/package-lock.json
generated
Normal file
20
tools/tests/apps/top-level-await-order/package-lock.json
generated
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "watch-used-files",
|
||||
"requires": true,
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"@babel/runtime": {
|
||||
"version": "7.20.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.7.tgz",
|
||||
"integrity": "sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==",
|
||||
"requires": {
|
||||
"regenerator-runtime": "^0.13.11"
|
||||
}
|
||||
},
|
||||
"regenerator-runtime": {
|
||||
"version": "0.13.11",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
|
||||
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
|
||||
}
|
||||
}
|
||||
}
|
||||
19
tools/tests/apps/top-level-await-order/package.json
Normal file
19
tools/tests/apps/top-level-await-order/package.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "top-level-await",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "meteor run",
|
||||
"test": "meteor test --once --driver-package meteortesting:mocha",
|
||||
"test-app": "TEST_WATCH=1 meteor test --full-app --driver-package meteortesting:mocha",
|
||||
"visualize": "meteor --production --extra-packages bundle-visualizer"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.15.3"
|
||||
},
|
||||
"meteor": {
|
||||
"mainModule": {
|
||||
"client": "main.js",
|
||||
"server": "main.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
Package.describe({
|
||||
name: 'build-plugin',
|
||||
});
|
||||
|
||||
Package.registerBuildPlugin({
|
||||
name: 'build-plugin',
|
||||
use: ['meteor', 'ecmascript'],
|
||||
sources: ['plugin.js']
|
||||
});
|
||||
|
||||
Package.registerBuildPlugin({
|
||||
name: 'build-plugin-no-meteor',
|
||||
use: [],
|
||||
sources: ['plugin-without-meteor.js']
|
||||
});
|
||||
|
||||
Package.onUse((api) => {
|
||||
api.use('isobuild:compiler-plugin@1.0.0')
|
||||
})
|
||||
@@ -0,0 +1 @@
|
||||
console.log('plugin without Meteor');
|
||||
@@ -0,0 +1,7 @@
|
||||
Meteor.startup(() => {
|
||||
console.log('plugin - startup');
|
||||
});
|
||||
console.log('plugin - before');
|
||||
await 0
|
||||
console.log('plugin - after');
|
||||
Promise.resolve().then(() => console.log('plugin - later'));
|
||||
@@ -0,0 +1,4 @@
|
||||
console.log('lazy package');
|
||||
await 0;
|
||||
console.log('after lazy');
|
||||
export const value = 10;
|
||||
@@ -0,0 +1,4 @@
|
||||
Package.onUse((api) => {
|
||||
api.use('ecmascript');
|
||||
api.mainModule('main.js', ['client', 'server'], { lazy: true});
|
||||
});
|
||||
@@ -0,0 +1,6 @@
|
||||
console.log('package 1 - a before');
|
||||
await 0;
|
||||
console.log('package 1 - a after');
|
||||
Promise.resolve().then(() => {
|
||||
console.log('package 1 - a later');
|
||||
});
|
||||
@@ -0,0 +1,6 @@
|
||||
console.log('package 1 - b before');
|
||||
await 0;
|
||||
console.log('package 1 - b after');
|
||||
Promise.resolve().then(() => {
|
||||
console.log('package 1 - b later');
|
||||
});
|
||||
@@ -0,0 +1,5 @@
|
||||
Package.onUse((api) => {
|
||||
api.use('ecmascript');
|
||||
api.addFiles('b.js');
|
||||
api.mainModule('a.js');
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
import './b.js';
|
||||
|
||||
console.log('package 2 - a before');
|
||||
await 0;
|
||||
console.log('package 2 - a after');
|
||||
Promise.resolve().then(() => {
|
||||
console.log('package 2 - a later');
|
||||
});
|
||||
|
||||
export const value = 6;
|
||||
@@ -0,0 +1,4 @@
|
||||
console.log('package 2 - b');
|
||||
Promise.resolve().then(() => {
|
||||
console.log('package 2 - b later');
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
Package.onUse((api) => {
|
||||
api.use('ecmascript');
|
||||
api.mainModule('a.js');
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
// Wait for Meteor package to load
|
||||
let logs = [];
|
||||
let oldLog = console.log;
|
||||
console.log = function (message) {
|
||||
logs.push(message);
|
||||
oldLog.apply(this, arguments);
|
||||
}
|
||||
|
||||
Meteor.startup(() => {
|
||||
// run after all startup hooks
|
||||
setTimeout(() => {
|
||||
Meteor.call('print', logs);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,6 @@
|
||||
Package.onUse((api) => {
|
||||
api.use('meteor');
|
||||
api.use('ddp');
|
||||
api.addFiles('client.js', 'client');
|
||||
api.addFiles('server.js', 'server');
|
||||
});
|
||||
@@ -0,0 +1,8 @@
|
||||
// Wait for Meteor package to load
|
||||
Meteor.methods({
|
||||
print(logs) {
|
||||
logs.forEach(message => {
|
||||
console.log('[client]', message);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
Package.onUse((api) => {
|
||||
api.use('ecmascript');
|
||||
api.addFiles('sync.js');
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
console.log('package sync');
|
||||
Promise.resolve().then(() => {
|
||||
console.log('package sync - later');
|
||||
});
|
||||
@@ -107,7 +107,7 @@ selftest.define("versioning hot code push", async function (options) {
|
||||
|
||||
s.set("AUTOUPDATE_VERSION", "1.0");
|
||||
await s.createApp("myapp", "hot-code-push-test");
|
||||
s.cd("myapp");
|
||||
await s.cd("myapp");
|
||||
|
||||
await s.testWithAllClients(async function (run) {
|
||||
await run.match("myapp");
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -55,7 +55,7 @@ selftest.define("static-html - throws error", async () => {
|
||||
await s.createApp('myapp', 'compiler-plugin-static-html-error');
|
||||
s.cd('myapp');
|
||||
|
||||
const run = startRun(s);
|
||||
const run = await startRun(s);
|
||||
await run.match("Attributes on <head> not supported");
|
||||
run.waitSecs(30);
|
||||
|
||||
|
||||
73
tools/tests/top-level-await.js
Normal file
73
tools/tests/top-level-await.js
Normal file
@@ -0,0 +1,73 @@
|
||||
import * as selftest from '../tool-testing/selftest.js';
|
||||
|
||||
|
||||
selftest.define("xxxx top level await - order", async function (options) {
|
||||
const s = new selftest.Sandbox({
|
||||
clients: options.clients
|
||||
});
|
||||
s.set('METEOR_ENABLE_CLIENT_TOP_LEVEL_AWAIT', 'true');
|
||||
await s.init();
|
||||
|
||||
await s.createApp("myapp", "top-level-await-order");
|
||||
s.cd("myapp");
|
||||
|
||||
await s.testWithAllClients(async (run) => {
|
||||
// TODO: Startup should be the last log, but there is a bug
|
||||
// where it runs too early in plugins
|
||||
await run.match('plugin - startup');
|
||||
await run.match('plugin - before');
|
||||
await run.match('plugin - after');
|
||||
await run.match('plugin - later');
|
||||
|
||||
await run.match('plugin without Meteor');
|
||||
|
||||
const lines = [
|
||||
'package sync',
|
||||
'package 1 - b before',
|
||||
'package 2 - b',
|
||||
'package 2 - a before',
|
||||
'package sync - later',
|
||||
'package 1 - b after',
|
||||
'package 2 - b later',
|
||||
'package 2 - a after',
|
||||
'package 1 - b later',
|
||||
'package 1 - a before',
|
||||
'package 2 - a later',
|
||||
'package 1 - a after',
|
||||
'package 1 - a later',
|
||||
'app a.js - before',
|
||||
'app b.js - before',
|
||||
'app a.js - after',
|
||||
'app b.js - after',
|
||||
'app a.js - later',
|
||||
'app b.js - later',
|
||||
'entry - before',
|
||||
'entry - after',
|
||||
'lazy package',
|
||||
'package 2 value 6',
|
||||
'entry - later',
|
||||
'after lazy',
|
||||
'lazy package value 10',
|
||||
'entry - startup',
|
||||
];
|
||||
|
||||
for(const line of lines) {
|
||||
await run.match(line);
|
||||
}
|
||||
|
||||
await run.connectClient();
|
||||
|
||||
for(const line of lines) {
|
||||
await run.match(`[client] ${line}`);
|
||||
}
|
||||
|
||||
await run.stop();
|
||||
}, {
|
||||
// concatenate js files so packages load in parallel
|
||||
// otherwise, there is too much of a delay between each
|
||||
// package loading
|
||||
// TODO: we could instead create a custom minifier for this test that
|
||||
// only concatenates, which would be faster
|
||||
args: ['--production']
|
||||
});
|
||||
});
|
||||
@@ -10,21 +10,33 @@ export default class PuppeteerClient extends Client {
|
||||
constructor(options) {
|
||||
super(options);
|
||||
|
||||
enterJob(
|
||||
this.name = 'Puppeteer';
|
||||
this.initialized = false;
|
||||
}
|
||||
|
||||
async init () {
|
||||
await enterJob(
|
||||
{
|
||||
title: 'Installing Puppeteer in Meteor tool'
|
||||
},
|
||||
() => {
|
||||
ensureDependencies(NPM_DEPENDENCIES);
|
||||
return ensureDependencies(NPM_DEPENDENCIES);
|
||||
}
|
||||
);
|
||||
|
||||
this.npmPackageExports = require('puppeteer');
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
this.name = 'Puppeteer';
|
||||
_checkInitialized() {
|
||||
if (!this.initialized) {
|
||||
throw new Error('PuppeteerClient not initialized');
|
||||
}
|
||||
}
|
||||
|
||||
async connect() {
|
||||
this._checkInitialized();
|
||||
|
||||
// Note for Travis and CircleCI to run sandbox must be turned off.
|
||||
// From a security perspective this is not ideal, in the future would be worthwhile
|
||||
// to configure to include only for CI based setups
|
||||
@@ -41,7 +53,10 @@ export default class PuppeteerClient extends Client {
|
||||
this.browser = null;
|
||||
}
|
||||
|
||||
static pushClients(clients, appConfig) {
|
||||
clients.push(new PuppeteerClient(appConfig));
|
||||
static async pushClients(clients, appConfig) {
|
||||
let client = new PuppeteerClient(appConfig);
|
||||
await client.init();
|
||||
|
||||
clients.push(client);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,10 @@ export default class Matcher {
|
||||
});
|
||||
}
|
||||
|
||||
write(data) {
|
||||
async write(data) {
|
||||
this.buf += data;
|
||||
this.fullBuffer += data;
|
||||
this._tryMatch();
|
||||
await this._tryMatch();
|
||||
}
|
||||
|
||||
getFullBuffer() {
|
||||
@@ -64,18 +64,29 @@ export default class Matcher {
|
||||
}
|
||||
|
||||
// Like match, but returns a Promise without calling .await().
|
||||
matchAsync(pattern, {
|
||||
async matchAsync(pattern, {
|
||||
timeout = null,
|
||||
strict = false,
|
||||
matchFullBuffer = false,
|
||||
}) {
|
||||
if (this.matchPromise) {
|
||||
return Promise.reject(new Error("already have a match pending?"));
|
||||
// wait a bit to let the matcher catch up
|
||||
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||
await sleep(100);
|
||||
|
||||
this._tryMatch(); // could clear this.matchPromise
|
||||
|
||||
// If we still have a matchPromise, then we have a problem.
|
||||
// you should check who is calling.
|
||||
if (this.matchPromise) {
|
||||
return Promise.reject(new Error("already have a match pending?"))
|
||||
}
|
||||
}
|
||||
this.matchPattern = pattern;
|
||||
this.matchStrict = strict;
|
||||
this.matchFullBuffer = matchFullBuffer;
|
||||
const mp = this.matchPromise = makeFulfillablePromise();
|
||||
this.matchPromise = makeFulfillablePromise();
|
||||
const mp = this.matchPromise;
|
||||
this._tryMatch(); // could clear this.matchPromise
|
||||
|
||||
let timer = null;
|
||||
@@ -92,13 +103,16 @@ export default class Matcher {
|
||||
return mp;
|
||||
}
|
||||
|
||||
return mp.then((result) => {
|
||||
clearTimeout(timer);
|
||||
return result;
|
||||
}, (error) => {
|
||||
clearTimeout(timer);
|
||||
throw error;
|
||||
});
|
||||
return mp.then(
|
||||
(result) => {
|
||||
clearTimeout(timer);
|
||||
return result;
|
||||
},
|
||||
(error) => {
|
||||
clearTimeout(timer);
|
||||
throw error;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
matchBeforeEnd(pattern, timeout) {
|
||||
@@ -114,12 +128,12 @@ export default class Matcher {
|
||||
}
|
||||
|
||||
end() {
|
||||
return this.endAsync().await();
|
||||
return this.endAsync();
|
||||
}
|
||||
|
||||
endAsync() {
|
||||
this.resolveEndPromise();
|
||||
return this._beforeEnd(() => {
|
||||
return this._beforeEnd(async () => {
|
||||
this.ended = true;
|
||||
this._tryMatch();
|
||||
return this.matchPromise;
|
||||
@@ -133,7 +147,7 @@ export default class Matcher {
|
||||
}
|
||||
}
|
||||
|
||||
_tryMatch() {
|
||||
async _tryMatch() {
|
||||
const mp = this.matchPromise;
|
||||
if (! mp) {
|
||||
return;
|
||||
|
||||
@@ -136,7 +136,7 @@ export default class Sandbox {
|
||||
}
|
||||
|
||||
if (clientOptions.puppeteer) {
|
||||
PuppeteerClient.pushClients(this.clients, appConfig);
|
||||
await PuppeteerClient.pushClients(this.clients, appConfig);
|
||||
}
|
||||
|
||||
if (clientOptions.browserstack && BrowserStackClient.prerequisitesMet()) {
|
||||
@@ -272,7 +272,7 @@ export default class Sandbox {
|
||||
if (callback) {
|
||||
const ret = callback();
|
||||
if (ret && typeof ret.then === "function") {
|
||||
return ret.then(() => this.cwd = previous);
|
||||
return ret.then(() => (this.cwd = previous));
|
||||
} else {
|
||||
this.cwd = previous;
|
||||
}
|
||||
@@ -516,7 +516,7 @@ async function setUpBuiltPackageTropohouse() {
|
||||
}
|
||||
|
||||
const tropohouse = new Tropohouse(builtPackageTropohouseDir);
|
||||
tropohouseLocalCatalog = newSelfTestCatalog();
|
||||
tropohouseLocalCatalog = await newSelfTestCatalog();
|
||||
const versions = {};
|
||||
for (const packageName of tropohouseLocalCatalog.getAllNonTestPackageNames()) {
|
||||
versions[packageName] =
|
||||
@@ -585,16 +585,16 @@ const ROOT_PACKAGES_TO_BUILD_IN_SANDBOX = [
|
||||
"typescript",
|
||||
];
|
||||
|
||||
function newSelfTestCatalog() {
|
||||
async function newSelfTestCatalog() {
|
||||
if (! files.inCheckout()) {
|
||||
throw Error("Only can build packages from a checkout");
|
||||
}
|
||||
|
||||
const catalogLocal = require('../packaging/catalog/catalog-local.js');
|
||||
const selfTestCatalog = new catalogLocal.LocalCatalog;
|
||||
const messages = capture(
|
||||
const messages = await capture(
|
||||
{ title: "scanning local core packages" },
|
||||
() => {
|
||||
async () => {
|
||||
const packagesDir =
|
||||
files.pathJoin(files.getCurrentToolsDir(), 'packages');
|
||||
|
||||
@@ -603,7 +603,7 @@ function newSelfTestCatalog() {
|
||||
// packages. One side effect of this: we really really expect them to all
|
||||
// build, and we're fine with dying if they don't (there's no worries
|
||||
// about needing to springboard).
|
||||
selfTestCatalog.initialize({
|
||||
await selfTestCatalog.initialize({
|
||||
localPackageSearchDirs: [
|
||||
packagesDir,
|
||||
files.pathJoin(packagesDir, "non-core"),
|
||||
|
||||
Reference in New Issue
Block a user