can you use tinytest to test a package that uses other packages - meteor

I have some tinytests, simple server unit tests.
Separately they run fine, but if i run them together I get errors on my collections.
What else might cause an error like the below?
I think its related to defining the exports in a JS file and the other classes in coffeescript and some scoping issue is complicating things. "Told you not to use coffeescript" i hear. But then again, it maybe something else!
os.osx.x86_64/dev_bundle/server-lib/node_modules/fibers/future.js:245
W20150418-17:39:20.312(-7)? (STDERR) throw(ex);
^
Error: A method named '/Profiles/insert' is already defined
at packages/ddp/livedata_server.js:1461:1
at Function._.each._.forEach (packages/underscore/underscore.js:113:1)
at [object Object]._.extend.methods (packages/ddp/livedata_server.js:1459:1)
at [object Object].Mongo.Collection._defineMutationMethods (packages/mongo/collection.js:90
at new Mongo.Collection (packages/mongo/collection.js:209:1)
at [object Object].Meteor.Collection (packages/dburles:collection-helpers/collection-helper
at __coffeescriptShare (packages/local-test:dcsan:mpgames/lib/exports.js:2:1)
at /private/var/folders/lw/6kdr1_9j3q1ggldr_c798qy80000gn/T/meteor-test-run126tw73/.meteor/
FWIW the app has no problems running, its just the tests that fail.

This error means you defined the Profiles collection more than once. My strategy in dealing with this problem has been to:
Use a global definition via api.export for any collections which actually should be defined by a package (e.g. if the posts package defined a Posts collection).
Define all other collections needed by the test with a null collection name (unmanaged) and use a reset like the following before each test:
var resetCollection = function(name) {
var Collection = this[name];
if (Collection)
// if the collection is already defined, remove its documents
Collection.remove({});
else
// define a new unmanaged collection
this[name] = new Mongo.Collection(null);
};
So if you call resetCollection('Posts') it would only define a new collection if needed and ensure its documents were removed. This way, you'll avoid multiple definitions and you'll start with a clean DB each time.

Related

What the proper way to avoid console warning, when meteor collection is not ready

Every time I refresh the page I receive the following console warning for every single helper that is returning something to template from collection. I know the reason is because the subscription is not ready yet, but what is the solution?
Exception in template helper: TypeError: Cannot read property 'x' of undefined.
I'm already using if(collection.find({}) !== undefined) , but this makes my codes so messy, there must be a way to fix this issue. then I tried guards and still not 100% solved.
In addition to Brendan's answer, using Blaze you can check if the subscriptions for the template is ready using
this.subscriptionsReady()
Which checks all the subscriptions scoped to the template with
this.subscribe()
in your onCreated or onRendered blocks
Meteor.subscribe returns a handle with a reactive method called .ready(). You can use that in your helper to only return the mongo cursor once it's ready.
Edit: docs

Meteor - check() VS new SimpleSchema() for verifying .publish() arguments

To ensure the type of the arguments my publications receive, should I use SimpleSchema or check()?
Meteor.publish('todos.inList', function(listId, limit) {
new SimpleSchema({
listId: { type: String },
limit: { type: Number }
}).validate({ listId, limit });
[...]
});
or
Meteor.publish('todos.inList', function(listId, limit) {
check(listId, String);
check (limit, Number);
[...]
});
check() allows you to check data type, which is one thing, but is somewhat limited.
SimpleSchema is much more powerful as it checks all keys in a documents (instead of one at a time) and lets you define not only type but also allowed values, define default (or dynamic) values when not present.
You should use SimpleSchema this way:
mySchema = new SimpleSchema({ <your schema here>});
var MyCollection = new Mongo.Collection("my_collection");
MyCollection.attachSchema(mySchema);
That way, you don't event need to check the schema in methods: it will be done automatically.
Of course it's always good practice to use the
mySchema.validate(document);
to validate a client generated document before inserting it in your collection, but if you don't and your document doesn't match the schema (extra keys, wrong types etc...) SimpleSchema will reject the parts that don't belong.
To check arguments to a publish() function or a Meteor.method() use check(). You define a SimpleSchema to validate inserts, upserts, and updates to collections. A publication is none of those - it's readonly. Your use of SimpleSchema with .validate() inline would actually work but it's a pretty unusual pattern and a bit of overkill.
You might find this helpful.
CHECK is a lightweight package for argument checking and general pattern matching. where as SimpleSchema is a huge package with one of the check features. It is just that one package was made before the other.
Both works the same. You can use CHECK externally in Meteor.methods as well. Decision is all yours.
Michel Floyd answer's, made me realize that check() actually sends Meteor.Error(400, "Match Failed") to the client, while SimpleSchema within Methods sends detailed ValidationError one can act upon to display appropriate error messages on a form for instance.
So to answer the question : should we use check() or SimpleSchema() to assess our arguments types in Meteor, I believe the answer is :
Use SimpleSchema if you need a detailed report of the error from the client, otherwise check() is the way to go not to send back critical info.

Meteor: How to know which template helper is throwing an exception

After having changed the semantics of a Session variable used in lots of places in the code, I am left with a regression where I get the "Exception in template helper" error at page load.
So I screwed up, and there is somewhere where I am using that variable where I have not modified the code to handle the new semantics. But I can't find where....
The traceback gives me no clue, as it has only entries from the meteor javascript files, no informtion about my application files:
Exception in template helper: Error: $in needs an array
at Error (native)
at Object.ELEMENT_OPERATORS.$in.compileElementSelector (http://jesper-lab:3000/packages/minimongo.js?e8806aa7782b729b2517ebc0cd10b321667f1427:1887:15)
at http://jesper-lab:3000/packages/minimongo.js?e8806aa7782b729b2517ebc0cd10b321667f1427:1569:19
at Function._.each._.forEach (http://jesper-lab:3000/packages/underscore.js?0a80a8623e1b40b5df5a05582f288ddd586eaa18:164:22)
at operatorBranchedMatcher (http://jesper-lab:3000/packages/minimongo.js?e8806aa7782b729b2517ebc0cd10b321667f1427:1549:5)
at compileValueSelector (http://jesper-lab:3000/packages/minimongo.js?e8806aa7782b729b2517ebc0cd10b321667f1427:1453:12)
at http://jesper-lab:3000/packages/minimongo.js?e8806aa7782b729b2517ebc0cd10b321667f1427:1432:9
at Function._.each._.forEach (http://jesper-lab:3000/packages/underscore.js?0a80a8623e1b40b5df5a05582f288ddd586eaa18:164:22)
at compileDocumentSelector (http://jesper-lab:3000/packages/minimongo.js?e8806aa7782b729b2517ebc0cd10b321667f1427:1415:5)
at _.extend._compileSelector (http://jesper-lab:3000/packages/minimongo.js?e8806aa7782b729b2517ebc0cd10b321667f1427:1392:12)
Is there any way I can find out WHICH template helper is throwing this exception? (Besides putting breakpoints in all of them (hundreds...))
I'm not sure it's the best possible way but what I do is use a generic try_catch function:
#try_catch = (f) ->
return (args) ->
try
f(args)
catch e
console.log e
and wrap it around every template helper I want to debug.

ReferenceError, meteor

I've seen this problem posted but did not really understand the explanations. I am new to meteor and doing this project. From what I understand some of the functionality with node is not available in the browser, but I am unsure of how to fix the problem. I have tried to wrap the code within some function(window) but still was not able to get it working. I also tried to use npm but was coming up empty with some errors about some Illegal tokens. Thanks for any help.
Your app is crashing. Here's the latest log.
/home/alex/TacticsTrainer2/.meteor/local/build/programs/server/boot.js:186
}).run();
^
ReferenceError: window is not defined
at app/js/bootstrap.min.js:6:353
at app/js/bootstrap.min.js:8:3
at /home/alex/TacticsTrainer2/.meteor/local/build/programs/server/boot.js:155:10
at Array.forEach (native)
at Function._.each._.forEach (/home/alex/.meteor/tools/5bf1690853/lib/node_modules /underscore/underscore.js:79:11)
at /home/alex/TacticsTrainer2/.meteor/local/build/programs/server/boot.js:82:5
=> Exited with code: 8
=> Your application is crashing. Waiting for file change.
It looks like you may have not structured your app correctly. You have code that is intended to run on the client/browser side that is running on the server side.
In your app:
place all code to be run on the client in the /client directory
place all server side code in the /server directory
place code that you want to run on both the server and client in the root folder or a non reserved name (public, private, tests, server or client)
For more details about this see the meteor docs: http://docs.meteor.com/#structuringyourapp
ReferenceError is a Node error. Meteor is a framework on top of Node.
Node has a global scope (aka Node's global variable). This error is thrown by Node (not Meteor) if you try to access an undefined global variable.
Browsers also have a global scope called window, and do not throw ReferenceErrors when undefined variables are accessed.
Here's a pattern I like for adding functionality to a class (it's very Meteor):
/lib/Helpers.js <-- Helpers for everyone (node+browser)
/server/Helpers.js <-- Server helpers (node)
/client/Helpers.js <-- Client helpers (browser)
Consider these implementations:
// /lib/Helpers.js
Helpers = {/* functions */}; // Assigned to window.Helpers and global.Helpers
// /server/Helpers.js
Helpers = _.extend(Helpers, {/*more functions*/}
// /client/Helpers.js
Helpers = _.extend(Helpers, {/*more functions*/}
This is a trivial example. What if I didn't want to worry about load order? Why not _.extend() in /lib/Helpers.js?
// /lib/Helpers.js
// Helpers = {/* functions */}; // Overwrites...
Helpers = _.extend(Helpers, {/* functions */}); // ReferenceError
Because you'll get a ReferenceError from Node if Helpers isn't defined - specifically the "Helpers" used as an argument. (Node knows to assign Helpers as global.Helpers).
Here are two ways to "fix" this:
1) Assign Helpers to something
// /lib/Helpers.js
if (typeof Helpers === 'undefined') Helpers = {};
Helpers = _.extend(Helpers, {/* functions */});
2) Use helpers from the global
// /lib/Helpers.js
Helpers = _.extend(global.Helpers, {/* functions */}); // works in node, but...
Both of which suck.
1)'s syntax is horrible.
2) works in node, but there is no global in browsers. So it fails it's purpose.
So I gave up and went back to overwriting it the first time in lib, and looking for runtime errors if anything was overwritten.
If you have a handy cross-browser syntax for this, do comment :-)
I think you are calling a method that is loaded on the client and server.
You could write the code inside the Meteor.method like this:
if (!this.isSimulation) {
// code with node js that should only run in the server
} else {
// code that doesn't have nodejs runtime (browser)
}
This happens when you loaded the Method both in the client and server.

Backbone.js binding (BackFire) model destroy function not working

I get the following error when i try to call destroy function to my Backbone Model:
Uncaught TypeError: Cannot call method 'apply' of undefined backbone-firebase.js:126
Backbone.Firebase.sync backbone-firebase.js:126
Backbone.sync backbone-firebase.js:154
h.extend.sync backbone-min.js:1
h.extend.destroy backbone-min.js:1
Backbone.View.extend.remove sample.html:79
p.event.dispatch jquery.min.js:2
g.handle.h
Code: http://dl.dropboxusercontent.com/u/14749491/sample.html
Since you're using the "implicit" sync method, don't use destroy to remove the model, use the remove method on the collection instead.
If you'd like to use destroy, I recommend using the "explicit" sync method,,using Backbone.Collection.extend with a firebase property. More information on these two methods here: https://github.com/firebase/backfire
I don't know anything about BackFire. But it appears to be a conflict between FireBase and BackBone-FireBase. Since the code you are loading from the FireBase cdn is minified method names (like delete in this case) have been changed. Try using the unminified version of FireBase and see if it works correctly.

Resources