Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions .versions
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,33 @@ blaze@2.1.3
blaze-tools@1.0.4
boilerplate-generator@1.0.4
callback-hook@1.0.4
check@1.0.6
dburles:collection-helpers@1.0.4
check@1.1.0
ddp@1.2.2
ddp-client@1.2.1
ddp-common@1.2.1
ddp-server@1.2.1
ddp-common@1.2.2
ddp-server@1.2.2
deps@1.0.9
diff-sequence@1.0.1
ecmascript@0.1.5
ecmascript-collections@0.1.6
ecmascript@0.1.6
ecmascript-runtime@0.2.6
ejson@1.0.7
ephemer:collection-helpers@1.1.0
geojson-utils@1.0.4
html-tools@1.0.5
htmljs@1.0.5
id-map@1.0.4
jquery@1.11.4
local-test:dburles:collection-helpers@1.0.4
local-test:ephemer:collection-helpers@1.1.0
logging@1.0.8
meteor@1.1.9
meteor@1.1.10
minimongo@1.0.10
mongo@1.1.2
mongo@1.1.3
mongo-id@1.0.1
npm-mongo@1.4.39_1
observe-sequence@1.0.7
ordered-dict@1.0.4
promise@0.5.0
random@1.0.4
promise@0.5.1
random@1.0.5
reactive-var@1.0.6
retry@1.0.4
routepolicy@1.0.6
Expand All @@ -42,5 +42,5 @@ tinytest@1.0.6
tracker@1.0.9
ui@1.0.8
underscore@1.0.4
webapp@1.2.2
webapp@1.2.3
webapp-hashing@1.0.5
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Collection helpers automatically sets up a transformation on your collections us
## Installation

```sh
$ meteor add dburles:collection-helpers
$ meteor add ephemer:collection-helpers
```

## Usage
Expand Down
55 changes: 42 additions & 13 deletions collection-helpers.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,47 @@
Mongo.Collection.prototype.helpers = function(helpers) {
var self = this;
let self = this;

if (self._transform && ! self._helpers)
throw new Meteor.Error("Can't apply helpers to '" +
self._name + "' a transform function already exists!");
if (!self._helpers) {
let OriginalDocument = class OriginalDocument {};

if (! self._helpers) {
self._helpers = function Document(doc) { return _.extend(this, doc); };
self._transform = function(doc) {
return new self._helpers(doc);
};
}
if (self._transform) {
let transformedDoc = createDummyTransformedDocument.call(self);
OriginalDocument = transformedDoc.__proto__.constructor;
if (OriginalDocument === Object) {
OriginalDocument = self._transform;
}
}

_.each(helpers, function(helper, key) {
self._helpers.prototype[key] = helper;
});
self._helpers = class DocumentWithHelpers extends OriginalDocument {
constructor(doc) {
super(doc);
return _.extend(this, doc);
}
}

self._transform = function(doc) {
return new self._helpers(doc);
};
}

let transformedDoc = createDummyTransformedDocument.call(self);
_.each(helpers, function(helper, key) {
if (transformedDoc[key] === undefined) {
self._helpers.prototype[key] = helper;
} else {
throw new Meteor.Error(`A helper called ${key} already exists on ${self}`)
}
});
};


function createDummyTransformedDocument() {
try {
return this._transform({_id: 'fakeDocument'});
} catch(e) {
throw new Meteor.Error(`Error while adding helpers to your Collection`,
`This only happens when your Collection has an existing transform
that accesses non-initialised state internally and then you try to
add helpers via Collection.helpers({}).`)
}
}
208 changes: 145 additions & 63 deletions collection-helpers_tests.js
Original file line number Diff line number Diff line change
@@ -1,74 +1,156 @@
Tinytest.add("works", function(test) {
Books = new Mongo.Collection('books' + test.id);
Authors = new Mongo.Collection('authors' + test.id);

var author1 = Authors.insert({
firstName: 'Charles',
lastName: 'Darwin'
});

var author2 = Authors.insert({
firstName: 'Carl',
lastName: 'Sagan'
});

var book1 = Books.insert({
authorId: author1,
name: 'On the Origin of Species'
});

var book2 = Books.insert({
authorId: author2,
name: 'Contact'
});

Books.helpers({
author: function() {
return Authors.findOne(this.authorId);
'use strict';

Tinytest.add("Works as expected in base case", function(test) {
var Books = new Mongo.Collection(null);
var Authors = new Mongo.Collection(null);

var author1 = Authors.insert({
firstName: 'Charles',
lastName: 'Darwin'
});

var author2 = Authors.insert({
firstName: 'Carl',
lastName: 'Sagan'
});

var book1 = Books.insert({
authorId: author1,
name: 'On the Origin of Species'
});

var book2 = Books.insert({
authorId: author2,
name: 'Contact'
});

Books.helpers({
author: function() {
return Authors.findOne(this.authorId);
}
});

// We should be able to apply more if we wish
Books.helpers({
foo: 'bar'
});

Authors.helpers({
fullName: function() {
return this.firstName + ' ' + this.lastName;
},
books: function() {
return Books.find({ authorId: this._id });
}
});

var book = Books.findOne(book1);
var author = book.author();

test.equal(author.firstName, 'Charles');
test.equal(book.foo, 'bar');

book = Books.findOne(book2);
author = book.author();
test.equal(author.fullName(), 'Carl Sagan');

author = Authors.findOne(author1);
var books = author.books();
test.equal(books.count(), 1);
});

Tinytest.add("Throw error if transform function already exists", function(test) {
class Author {
constructor(doc) {
return _.extend(this, doc);
}

fullName() {
return 'Charles Darwin';
}
}
});

// We should be able to apply more if we wish
Books.helpers({
foo: 'bar'
});

Authors.helpers({
fullName: function() {
return this.firstName + ' ' + this.lastName;
},
books: function() {
return Books.find({ authorId: this._id });

var Authors = new Meteor.Collection(null, {
transform(doc) {
return new Author(doc);
}
});

test.throws(function() {
Authors.helpers({
fullName() {
return this.firstName + ' ' + this.lastName;
}
});
});
});

Tinytest.add("Work normally if non-conflicting transform function already exists", function(test) {
class Author {
constructor(doc) {
return _.extend(this, doc);
}

aSmartMan() {
return 'Charles Darwin';
}
}
});

var book = Books.findOne(book1);
var author = book.author();
test.equal(author.firstName, 'Charles');
test.equal(book.foo, 'bar');
var Authors = new Meteor.Collection(null, {
transform(doc) {
return new Author(doc);
}
});

book = Books.findOne(book2);
author = book.author();
test.equal(author.fullName(), 'Carl Sagan');
Authors.helpers({
fullName() {
return this.firstName + ' ' + this.lastName;
}
});

author = Authors.findOne(author1);
books = author.books();
test.equal(books.count(), 1);
});
Authors.insert({
firstName: 'Charles',
lastName: 'Darwin'
});

Tinytest.add("throw error if transform function already exists", function(test) {
Author = function(doc) { return _.extend(this, doc); };
let author = Authors.findOne();
test.equal(author.fullName(), author.aSmartMan());
});

Author.prototype.fullName = 'Charles Darwin';

Authors = new Meteor.Collection('authors' + test.id, {
transform: function(doc) { return new Author(doc); }});
Tinytest.add("Use a normal transform too without breaking things", function(test) {
var Authors = new Meteor.Collection(null, {
transform(doc) {
doc.normalTransform = 'working';
return doc;
}
});

test.throws(function() {
Authors.helpers({
fullName: function() {
return this.firstName + ' ' + this.lastName;
}
fullName() {
return this.firstName + ' ' + this.lastName;
}
});
});
});

Authors.insert({
firstName: 'Bob',
lastName: 'Dole'
});

let bob = Authors.findOne();

test.equal(bob.firstName, 'Bob');
test.equal(bob.lastName, 'Dole');
test.equal(bob.fullName(), 'Bob Dole');
test.equal(bob.normalTransform, 'working');

test.throws(function() {
Authors.helpers({
normalTransform() {
return "This should fail";
}
});
});

test.equal(bob.normalTransform, 'working');
});
34 changes: 18 additions & 16 deletions package.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
Package.describe({
name: "dburles:collection-helpers",
summary: "Transform your collections with helpers that you define",
version: "1.0.4",
documentation: "README.md",
git: "https://github.com/dburles/meteor-collection-helpers.git",
name: "ephemer:collection-helpers",
summary: "Transform Collections with self-defined helpers. Works with TAPi18n & other self-defined transforms!",
version: "1.1.0",
documentation: "README.md",
git: "https://github.com/ephemer/meteor-collection-helpers.git",
});

Package.onUse(function(api) {
api.versionsFrom('1.2.0.2');
api.use([
'underscore',
'mongo']);
api.versionsFrom('1.2.0.2');
api.use([
'ecmascript',
'underscore',
'mongo']);

api.addFiles('collection-helpers.js');
api.addFiles('collection-helpers.js');
});

Package.onTest(function(api) {
api.use([
'tinytest',
'underscore',
'mongo',
'dburles:collection-helpers']);
api.addFiles('collection-helpers_tests.js');
api.use([
'ecmascript',
'tinytest',
'underscore',
'mongo',
'ephemer:collection-helpers']);
api.addFiles('collection-helpers_tests.js');
});