From 9085e8b695c2e73e896f7acbdd08aaac46882073 Mon Sep 17 00:00:00 2001 From: David Burles Date: Wed, 27 Nov 2024 07:16:12 +1100 Subject: [PATCH 01/11] update tests thanks @drone1 --- collection-helpers_tests.js | 186 +++++++++++++++++++++++++----------- 1 file changed, 130 insertions(+), 56 deletions(-) diff --git a/collection-helpers_tests.js b/collection-helpers_tests.js index 0d2f595..76b6c83 100644 --- a/collection-helpers_tests.js +++ b/collection-helpers_tests.js @@ -1,74 +1,148 @@ -Tinytest.add("works", function(test) { - Books = new Mongo.Collection('books' + test.id); - Authors = new Mongo.Collection('authors' + test.id); +const meteorVersion = Meteor.release + ? parseFloat(Meteor.release.split("@")[1]) + : null; - var author1 = Authors.insert({ - firstName: 'Charles', - lastName: 'Darwin' - }); +if (meteorVersion && meteorVersion >= 3) { + Tinytest.addAsync("works", async function (test, onComplete) { + const Books = new Mongo.Collection( + Meteor.isClient ? null : "books" + test.id + ); + const Authors = new Mongo.Collection( + Meteor.isClient ? null : "authors" + test.id + ); - var author2 = Authors.insert({ - firstName: 'Carl', - lastName: 'Sagan' - }); + const author1 = await Authors.insertAsync({ + firstName: "Charles", + lastName: "Darwin", + }); - var book1 = Books.insert({ - authorId: author1, - name: 'On the Origin of Species' - }); + const author2 = await Authors.insertAsync({ + firstName: "Carl", + lastName: "Sagan", + }); - var book2 = Books.insert({ - authorId: author2, - name: 'Contact' - }); + const book1 = await Books.insertAsync({ + authorId: author1, + name: "On the Origin of Species", + }); - Books.helpers({ - author: function() { - return Authors.findOne(this.authorId); - } - }); + const book2 = await Books.insertAsync({ + authorId: author2, + name: "Contact", + }); - // We should be able to apply more if we wish - Books.helpers({ - foo: 'bar' - }); + Books.helpers({ + author() { + return Authors.findOneAsync(this.authorId); + }, + }); + + // We should be able to apply more if we wish + Books.helpers({ + foo: "bar", + }); + + Authors.helpers({ + fullName() { + return this.firstName + " " + this.lastName; + }, + books() { + return Books.find({ authorId: this._id }); + }, + }); + + const book = await Books.findOneAsync(book1); + const author = await book.author(); - Authors.helpers({ - fullName: function() { - return this.firstName + ' ' + this.lastName; - }, - books: function() { - return Books.find({ authorId: this._id }); - } + test.equal(author.firstName, "Charles"); + test.equal(author.fullName(), "Charles Darwin"); + test.equal(book.foo, "bar"); + + const authorCarl = await Authors.findOneAsync(author2); + const booksByCarl = await authorCarl.books().fetchAsync(); + + test.equal(booksByCarl.length, 1); + + onComplete(); }); +} else { + // Meteor < 3.0 + Tinytest.add("works", function (test) { + const Books = new Mongo.Collection("books" + test.id); + const Authors = new Mongo.Collection("authors" + test.id); - var book = Books.findOne(book1); - var author = book.author(); - test.equal(author.firstName, 'Charles'); - test.equal(book.foo, 'bar'); + const author1 = Authors.insert({ + firstName: "Charles", + lastName: "Darwin", + }); - book = Books.findOne(book2); - author = book.author(); - test.equal(author.fullName(), 'Carl Sagan'); + const author2 = Authors.insert({ + firstName: "Carl", + lastName: "Sagan", + }); - author = Authors.findOne(author1); - books = author.books(); - test.equal(books.count(), 1); -}); + const book1 = Books.insert({ + authorId: author1, + name: "On the Origin of Species", + }); -Tinytest.add("throw error if transform function already exists", function(test) { - Author = function(doc) { return _.extend(this, doc); }; + const book2 = Books.insert({ + authorId: author2, + name: "Contact", + }); - Author.prototype.fullName = 'Charles Darwin'; + Books.helpers({ + author: function () { + return Authors.findOne(this.authorId); + }, + }); - Authors = new Meteor.Collection('authors' + test.id, { - transform: function(doc) { return new Author(doc); }}); + // We should be able to apply more if we wish + Books.helpers({ + foo: "bar", + }); - test.throws(function() { Authors.helpers({ - fullName: function() { - return this.firstName + ' ' + this.lastName; - } + fullName: function () { + return this.firstName + " " + this.lastName; + }, + books: function () { + return Books.find({ authorId: this._id }); + }, }); + + const book = Books.findOne(book1); + const author = book.author(); + test.equal(author.firstName, "Charles"); + test.equal(book.foo, "bar"); + + const authorCarl = Authors.findOne(author1); + const booksByCarl = author.books(); + test.equal(booksByCarl.count(), 1); }); -}); \ No newline at end of file +} + +Tinytest.add( + "throw error if transform function already exists", + function (test) { + Author = function (doc) { + return _.extend(this, doc); + }; + + Author.prototype.fullName = "Charles Darwin"; + + Authors = new Meteor.Collection("authors" + test.id, { + transform: function (doc) { + return new Author(doc); + }, + }); + + test.throws(function () { + Authors.helpers({ + fullName: function () { + return this.firstName + " " + this.lastName; + }, + }); + }); + } +); From fd9a660c5fff42e31a9c57057d4bd3a9d38a967c Mon Sep 17 00:00:00 2001 From: David Burles Date: Wed, 27 Nov 2024 07:18:44 +1100 Subject: [PATCH 02/11] update supported Meteor versions --- package.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.js b/package.js index 4b6ff85..4217a8c 100644 --- a/package.js +++ b/package.js @@ -7,7 +7,7 @@ Package.describe({ }); Package.onUse(function(api) { - api.versionsFrom('1.4.2'); + api.versionsFrom(['1.4.2', '2.3', '3.0']); api.use([ 'underscore', 'mongo']); From e8b2505542b6b7dc4591b59188805febd2d82e64 Mon Sep 17 00:00:00 2001 From: drone1 Date: Tue, 26 Nov 2024 18:12:54 +0100 Subject: [PATCH 03/11] updates README with async examples & testing instructions --- README.md | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5a96d71..99ae181 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,10 @@ Authors = new Mongo.Collection('authors'); Books.helpers({ author() { - return Authors.findOne(this.authorId); + return Authors.findOne(this.authorId); // client-only + }, + async authorAsync() { // Async helpers supported + return await Authors.findOneAsync(this.authorId); } }); @@ -27,7 +30,7 @@ Authors.helpers({ return `${this.firstName} ${this.lastName}`; }, books() { - return Books.find({ authorId: this._id }); + return Books.find({ authorId: this._id }); // returns a cursor } }); ``` @@ -35,9 +38,17 @@ Authors.helpers({ This will then allow you to do: ```javascript -Books.findOne().author().firstName; // Charles -Books.findOne().author().fullName(); // Charles Darwin -Authors.findOne().books() +const book = await Books.findOneAsync(); +const author = await book.authorAsync(); +author.firstName; // Charles +author.fullName(); // Charles Darwin +``` + +and: + +```javascript +const author = await Authors.findOneAsync(); +await author.books().fetchAsync(); ``` Our relationships are resolved by the collection helper, avoiding unnecessary template helpers. So we can simply write: @@ -87,6 +98,15 @@ var transformedDoc = Authors._transform(doc); transformedDoc.fullName(); // Charles Darwin ``` +### Testing + +Clone the repo, then, from the repo root directory, run: + +```bash +cd tests +npm i && npm run test:watch +```` + ### License MIT From 03827087f515f63e2352e3c48b400156f9ee7a09 Mon Sep 17 00:00:00 2001 From: David Burles Date: Wed, 27 Nov 2024 07:25:13 +1100 Subject: [PATCH 04/11] update readme --- README.md | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 99ae181..52ec978 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Collection helpers automatically sets up a transformation on your collections us ## Installation ```sh -$ meteor add dburles:collection-helpers +meteor add dburles:collection-helpers ``` ## Usage @@ -13,15 +13,15 @@ $ meteor add dburles:collection-helpers Write your helpers somewhere seen by both client and server. ```javascript -Books = new Mongo.Collection('books'); -Authors = new Mongo.Collection('authors'); +const Books = new Mongo.Collection('books'); +const Authors = new Mongo.Collection('authors'); Books.helpers({ author() { - return Authors.findOne(this.authorId); // client-only + return Authors.findOne(this.authorId); // Client only (Meteor 3+) }, - async authorAsync() { // Async helpers supported - return await Authors.findOneAsync(this.authorId); + authorAsync() { + return Authors.findOneAsync(this.authorId); } }); @@ -30,7 +30,7 @@ Authors.helpers({ return `${this.firstName} ${this.lastName}`; }, books() { - return Books.find({ authorId: this._id }); // returns a cursor + return Books.find({ authorId: this._id }); } }); ``` @@ -73,7 +73,7 @@ Template.books.helpers({ ``` -## Meteor.users +### Meteor.users You can also apply helpers to the Meteor.users collection @@ -88,24 +88,21 @@ Meteor.users.helpers({ Sometimes it may be useful to apply the transformation directly to an object. ```js -var doc = { +const doc = { firstName: 'Charles', lastName: 'Darwin' }; -var transformedDoc = Authors._transform(doc); +const transformedDoc = Authors._transform(doc); transformedDoc.fullName(); // Charles Darwin ``` ### Testing -Clone the repo, then, from the repo root directory, run: - -```bash -cd tests -npm i && npm run test:watch -```` +```sh +meteor test-packages ./ +``` ### License From 4f50a476eb670b575e264c95e034af20ff318154 Mon Sep 17 00:00:00 2001 From: David Burles Date: Wed, 27 Nov 2024 07:25:42 +1100 Subject: [PATCH 05/11] 1.2.0 --- package.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.js b/package.js index 4217a8c..8bbe29b 100644 --- a/package.js +++ b/package.js @@ -1,7 +1,7 @@ Package.describe({ name: "dburles:collection-helpers", summary: "Transform your collections with helpers that you define", - version: "1.1.0", + version: "1.2.0", documentation: "README.md", git: "/~https://github.com/dburles/meteor-collection-helpers.git", }); From 1577126692162dfa4c2b7629edd57b4be4164e2c Mon Sep 17 00:00:00 2001 From: David Burles Date: Wed, 27 Nov 2024 13:09:00 +1100 Subject: [PATCH 06/11] onComplete not required with promises --- collection-helpers_tests.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/collection-helpers_tests.js b/collection-helpers_tests.js index 76b6c83..260693a 100644 --- a/collection-helpers_tests.js +++ b/collection-helpers_tests.js @@ -3,7 +3,7 @@ const meteorVersion = Meteor.release : null; if (meteorVersion && meteorVersion >= 3) { - Tinytest.addAsync("works", async function (test, onComplete) { + Tinytest.addAsync("works", async function (test) { const Books = new Mongo.Collection( Meteor.isClient ? null : "books" + test.id ); @@ -62,8 +62,6 @@ if (meteorVersion && meteorVersion >= 3) { const booksByCarl = await authorCarl.books().fetchAsync(); test.equal(booksByCarl.length, 1); - - onComplete(); }); } else { // Meteor < 3.0 From b636ec139dbb49a1e794adb335be131a3aa31b6c Mon Sep 17 00:00:00 2001 From: harryadel Date: Mon, 2 Dec 2024 16:13:00 +0200 Subject: [PATCH 07/11] Add basic testing setup --- .github/workflows/codeql.yml | 41 +++++++++++++++++++++++++++++++++ .github/workflows/testsuite.yml | 32 +++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 .github/workflows/codeql.yml create mode 100644 .github/workflows/testsuite.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..c9ce53b --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,41 @@ +name: "CodeQL" + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + schedule: + - cron: "34 22 * * 4" + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ javascript ] + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + queries: +security-and-quality + + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{ matrix.language }}" \ No newline at end of file diff --git a/.github/workflows/testsuite.yml b/.github/workflows/testsuite.yml new file mode 100644 index 0000000..a7adca2 --- /dev/null +++ b/.github/workflows/testsuite.yml @@ -0,0 +1,32 @@ +# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +name: Test suite + +on: [push, pull_request] + +jobs: + tests: + name: tests + runs-on: ubuntu-latest + strategy: + matrix: + meteor-release: + - '--release 2.8.2' + - '--release 3.1' + # needs: [lintcode,lintstyle,lintdocs] # we could add prior jobs for linting, if desired + steps: + - name: checkout + uses: actions/checkout@v3 + + - name: Install Dependencies + run: | + curl https://install.meteor.com | /bin/sh + npm i -g @zodern/mtest + + - name: Run Tests + run: | + # Fix using old versions of Meteor + export NODE_TLS_REJECT_UNAUTHORIZED=0 + + mtest --package ./ --once ${{ matrix.meteorRelease }} From d1513c3622ba95509de65563303f47fc12bf1828 Mon Sep 17 00:00:00 2001 From: David Burles Date: Tue, 10 Dec 2024 07:51:46 +1100 Subject: [PATCH 08/11] drop underscore dependency --- collection-helpers.js | 18 ++++++------------ package.js | 7 ++----- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/collection-helpers.js b/collection-helpers.js index 47c1c74..55a25f8 100644 --- a/collection-helpers.js +++ b/collection-helpers.js @@ -1,18 +1,12 @@ Mongo.Collection.prototype.helpers = function(helpers) { - var self = this; - - if (self._transform && ! self._helpers) + if (this._transform && !this._helpers) throw new Meteor.Error("Can't apply helpers to '" + - self._name + "' a transform function already exists!"); + this._name + "' a transform function already exists!"); - if (! self._helpers) { - self._helpers = function Document(doc) { return _.extend(this, doc); }; - self._transform = function(doc) { - return new self._helpers(doc); - }; + if (!this._helpers) { + this._helpers = function Document(doc) { return Object.assign(this, doc); }; + this._transform = doc => new this._helpers(doc); } - _.each(helpers, function(helper, key) { - self._helpers.prototype[key] = helper; - }); + Object.keys(helpers).forEach(key => (this._helpers.prototype[key] = helpers[key])); }; diff --git a/package.js b/package.js index 8bbe29b..fe33dab 100644 --- a/package.js +++ b/package.js @@ -7,10 +7,8 @@ Package.describe({ }); Package.onUse(function(api) { - api.versionsFrom(['1.4.2', '2.3', '3.0']); - api.use([ - 'underscore', - 'mongo']); + api.versionsFrom(['2.3', '3.0']); + api.use(['mongo']); api.addFiles('collection-helpers.js'); }); @@ -18,7 +16,6 @@ Package.onUse(function(api) { Package.onTest(function(api) { api.use([ 'tinytest', - 'underscore', 'mongo', 'dburles:collection-helpers']); From ceb7737e5db8ec09f9b6c26bc2c358964dfc2356 Mon Sep 17 00:00:00 2001 From: David Burles Date: Tue, 10 Dec 2024 07:51:57 +1100 Subject: [PATCH 09/11] 2.0.0 drops Meteor 1.0 support --- package.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.js b/package.js index fe33dab..de75af7 100644 --- a/package.js +++ b/package.js @@ -1,7 +1,7 @@ Package.describe({ name: "dburles:collection-helpers", summary: "Transform your collections with helpers that you define", - version: "1.2.0", + version: "2.0.0", documentation: "README.md", git: "/~https://github.com/dburles/meteor-collection-helpers.git", }); From 9475ff8239ac3609163f6fc98a008e98fd11f527 Mon Sep 17 00:00:00 2001 From: David Burles Date: Tue, 10 Dec 2024 07:53:14 +1100 Subject: [PATCH 10/11] Delete codeql.yml --- .github/workflows/codeql.yml | 41 ------------------------------------ 1 file changed, 41 deletions(-) delete mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index c9ce53b..0000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: "CodeQL" - -on: - push: - branches: [ "master" ] - pull_request: - branches: [ "master" ] - schedule: - - cron: "34 22 * * 4" - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ javascript ] - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - queries: +security-and-quality - - - name: Autobuild - uses: github/codeql-action/autobuild@v2 - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{ matrix.language }}" \ No newline at end of file From 4856638d5c1661ac8ea43546057fbf8bcaf12dac Mon Sep 17 00:00:00 2001 From: David Burles Date: Tue, 10 Dec 2024 07:54:15 +1100 Subject: [PATCH 11/11] Update testsuite.yml --- .github/workflows/testsuite.yml | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/.github/workflows/testsuite.yml b/.github/workflows/testsuite.yml index a7adca2..13c7283 100644 --- a/.github/workflows/testsuite.yml +++ b/.github/workflows/testsuite.yml @@ -1,20 +1,14 @@ -# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions - -name: Test suite - +name: Tests on: [push, pull_request] - jobs: tests: name: tests runs-on: ubuntu-latest strategy: matrix: - meteor-release: - - '--release 2.8.2' - - '--release 3.1' - # needs: [lintcode,lintstyle,lintdocs] # we could add prior jobs for linting, if desired + meteor-release: + - "--release 2.8.2" + - "--release 3.1" steps: - name: checkout uses: actions/checkout@v3