Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

basic livedata method invocation tests

  • Loading branch information...
commit e0722bedf828150b262c51f9920221bd3c28996e 1 parent 8cf92b1
@gschmidt gschmidt authored
View
2  packages/livedata/livedata_connection.js
@@ -227,6 +227,8 @@ _.extend(Meteor._LivedataConnection.prototype, {
self._send_method(
{msg: 'method', method: name, params: args},
result_func);
+
+ return ret;
},
status: function () {
View
15 packages/livedata/livedata_test_service.js
@@ -0,0 +1,15 @@
+App.methods({
+ echo: function (/* arguments */) {
+ return _.toArray(arguments);
+ },
+ exception: function (where) {
+ Meteor._debug("hi there");
+ var shouldThrow =
+ (Meteor.is_server && where === "server") ||
+ (Meteor.is_client && where === "client") ||
+ where === "both";
+
+ if (shouldThrow)
+ throw new Error("Test method throwing an exception");
+ }
+});
View
135 packages/livedata/livedata_tests.js
@@ -12,4 +12,137 @@ test("livedata - basics", function () {
assert.length(coll.find({foo: 'bar'}).fetch(), 1);
});
-// XXX many more tests here!
+/******************************************************************************/
+
+var ExpectationManager = function (onComplete) {
+ var self = this;
+ self.onComplete = onComplete;
+ self.closed = false;
+ self.dead = false;
+ self.outstanding = 0;
+};
+
+_.extend(ExpectationManager.prototype, {
+ expect: function (/* arguments */) {
+ var self = this;
+
+ if (typeof arguments[0] === "function")
+ var expected = arguments[0];
+ else
+ var expected = _.toArray(arguments);
+
+ if (self.closed)
+ throw new Error("Too late to add more expectations to the test");
+ self.outstanding++;
+
+ return function (/* arguments */) {
+ if (typeof expected === "function")
+ expected.apply({}, arguments);
+ else
+ assert.equal(expected, _.toArray(arguments));
+
+ self.outstanding--;
+ self._check_complete();
+ };
+ },
+
+ done: function () {
+ var self = this;
+ self.closed = true;
+ self._check_complete();
+ },
+
+ cancel: function () {
+ var self = this;
+ self.dead = true;
+ },
+
+ _check_complete: function () {
+ var self = this;
+ if (!self.outstanding && self.closed && !self.dead) {
+ self.dead = true;
+ self.onComplete();
+ }
+ }
+});
+
+var testAsyncMulti = function (name, funcs) {
+ testAsync(name, function (onComplete) {
+ var remaining = _.clone(funcs);
+
+ var runNext = function () {
+ var func = remaining.shift();
+ if (!func)
+ onComplete();
+ else {
+ var em = new ExpectationManager(runNext);
+ try {
+ func(_.bind(em.expect, em));
+ } catch (exception) {
+ em.cancel();
+ test.exception(exception);
+ return;
+ }
+ em.done();
+ }
+ };
+
+ runNext();
+ });
+};
+
+/******************************************************************************/
+
+// XXX should check error codes
+var failure = function (reason) {
+ return function (error, result) {
+ assert.equal(result, undefined);
+ assert.equal(typeof(error), "object");
+ assert.equal(error.reason, reason);
+ // XXX should check that other keys aren't present.. should
+ // probably use something like the Matcher we used to have
+ };
+}
+
+testAsyncMulti("livedata - basic method invocation", [
+ function (expect) {
+ var ret = App.call("unknown method", expect(failure("Method not found")));
+ assert.equal(ret, undefined);
+ },
+
+ function (expect) {
+ var ret = App.call("echo", expect(undefined, []));
+ assert.equal(ret, []);
+ },
+
+ function (expect) {
+ var ret = App.call("echo", 12, expect(undefined, [12]));
+ assert.equal(ret, [12]);
+ },
+
+ function (expect) {
+ var ret = App.call("echo", 12, {x: 13}, expect(undefined, [12, {x: 13}]));
+ assert.equal(ret, [12, {x: 13}]);
+ },
+
+ function (expect) {
+ assert.throws(function () {
+ var ret = App.call("exception", "both");
+ });
+ },
+
+ function (expect) {
+ var ret = App.call("exception", "server",
+ expect(failure("Internal server error")));
+ assert.equal(ret, undefined);
+ },
+
+ function (expect) {
+ assert.throws(function () {
+ var ret = App.call("exception", "client");
+ });
+ }
+
+]);
+
+// XXX need a lot more tests
View
1  packages/livedata/package.js
@@ -24,4 +24,5 @@ Package.on_test(function (api) {
api.use('mongo-livedata', ['client', 'server']);
api.use('tinytest');
api.add_files('livedata_tests.js', 'client');
+ api.add_files('livedata_test_service.js', ['client', 'server']);
});
View
11 packages/stream/stream_client.js
@@ -235,7 +235,16 @@ _.extend(Meteor._Stream.prototype, {
self._connected(data.data);
else if (self.current_status.connected)
_.each(self.event_callbacks.message, function (callback) {
- callback(data.data);
+ try {
+ callback(data.data);
+ } catch (e) {
+ // XXX sockjs catches and silently ignores any exceptions
+ // that we raise here. not sure what we should do, but for
+ // now, just print the exception so you are at least aware
+ // that something went wrong.
+ // XXX improve error message
@majek
majek added a note

Filed a sockjs issue for that: sockjs/sockjs-client#61

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ Meteor._debug("Exception while processing message", e.stack);
+ }
});
};
self.socket.onclose = function () {
View
4 packages/test-in-browser/driver.js
@@ -70,6 +70,8 @@ Template.test.eventsArray = function() {
var dupLists = partitionBy(
_.map(events, function(e) {
+ // XXX XXX We need something better than stringify!
+ // stringify([undefined]) === "[null]"
return {obj: e, str: JSON.stringify(e)};
}), function(x) { return x.str; });
@@ -94,6 +96,8 @@ Template.event.get_details = function() {
if (! details) {
return null;
} else {
+ // XXX XXX We need something better than stringify!
+ // stringify([undefined]) === "[null]"
return JSON.stringify(details);
}
};
View
47 packages/tinytest/tinytest.js
@@ -91,6 +91,7 @@ var TestRun = function (manager, onReport) {
self.current_test = null;
self.current_fail_count = null;
self.stop_at_offset = null;
+ self.current_onException = null;
_.each(self.manager.ordered_tests, _.bind(self._report, self));
};
@@ -110,18 +111,12 @@ _.extend(TestRun.prototype, {
var cleanup = function () {
globals.assert = original_assert;
self.current_test = null;
+ self.current_fail_count = null;
self.stop_at_offset = null;
+ self.current_onException = null;
};
- test.run(function () {
- /* onComplete */
- cleanup();
-
- var totalTime = (+new Date) - startTime;
- self._report(test, {events: [{type: "finish", timeMs: totalTime}]});
- onComplete();
- }, function (exception) {
- /* onException */
+ self.current_onException = function (exception) {
cleanup();
// XXX you want the "name" and "message" fields on the
@@ -137,7 +132,16 @@ _.extend(TestRun.prototype, {
});
onComplete();
- });
+ };
+
+ test.run(function () {
+ /* onComplete */
+ cleanup();
+
+ var totalTime = (+new Date) - startTime;
+ self._report(test, {events: [{type: "finish", timeMs: totalTime}]});
+ onComplete();
+ }, _.bind(self.current_onException, self));
},
run: function (onComplete) {
@@ -213,6 +217,20 @@ _.extend(TestRun.prototype, {
}]});
self.expecting_failure = false;
self.current_fail_count++;
+ },
+
+ // Call this to fail the current test with an exception. Use this to record
+ // exceptions that occur inside asynchronous callbacks in tests.
+ //
+ // It should only be used with asynchronous tests, and if you call
+ // this function, you should make sure that (1) the test doesn't
+ // call its callback (onComplete function); (2) the test function
+ // doesn't directly raise an exception.
+ exception: function (exception) {
+ var self = this;
+ if (!self.current_onException)
+ throw new Error("Not in a test");
+ self.current_onException(exception);
}
});
@@ -228,6 +246,11 @@ var test_assert = {
* actual. Otherwise compare the JSON stringifications of expected
* and actual. (It's no good to stringify a DOM node. Circular
* references, to start with..) */
+
+ // XXX WE REALLY SHOULD NOT BE USING
+ // STRINGIFY. stringify([undefined]) === stringify([null]). should use
+ // deep equality instead.
+
// XXX remove cruft specific to liverange
if (typeof expected === "object" && expected.nodeType) {
var matched = expected === actual;
@@ -334,6 +357,10 @@ _.extend(globals.test, {
currentRun.fail(doc);
},
+ exception: function (exception) {
+ currentRun.exception(exception);
+ },
+
run: function (onComplete) {
if (currentRun)
throw new Error("Only one test run can be happening at once");
Please sign in to comment.
Something went wrong with that request. Please try again.