UNPKG

sku-pg

Version:

Skulpt is a Javascript implementation of Python 2.x. Python that runs in your browser!

344 lines (293 loc) 8.13 kB
<!DOCTYPE html> <html> <!-- Copyright 2008 The Closure Library Authors. All Rights Reserved. Use of this source code is governed by the Apache License, Version 2.0. See the COPYING file for details. --> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Closure Unit Tests - goog.testing.LooseMock</title> <script src="../base.js"></script> <script> goog.require('goog.testing.LooseMock'); goog.require('goog.testing.PropertyReplacer'); goog.require('goog.testing.jsunit'); goog.require('goog.testing.mockmatchers'); </script> </head> <body> <script> // The object that we will be mocking var RealObject = function() { }; RealObject.prototype.a = function() { fail('real object should never be called'); }; RealObject.prototype.b = function() { fail('real object should never be called'); }; var mock; var stubs; function setUp() { var obj = new RealObject(); mock = new goog.testing.LooseMock(obj); stubs = new goog.testing.PropertyReplacer(); } function tearDown() { stubs.reset(); } /* * Calling this method evades the logTestFailure in * goog.testing.Mock.prototype.$recordAndThrow, so it doesn't look like the * test failed. */ function silenceFailureLogging() { if (goog.global['G_testRunner']) { stubs.set(goog.global['G_testRunner'], 'logTestFailure', goog.nullFunction); } } function unsilenceFailureLogging() { stubs.reset(); } /** * Version of assertThrows that doesn't log the exception generated by the * mocks under test. * TODO: would be nice to check that a particular substring is in the thrown * message so we know it's not something dumb like a syntax error */ function assertThrowsQuiet(var_args) { silenceFailureLogging(); assertThrows.apply(null, arguments); unsilenceFailureLogging(); } // Most of the basic functionality is tested in strictmock_test; these tests // cover the cases where loose mocks are different from strict mocks function testSimpleExpectations() { mock.a(5); mock.b(); mock.$replay(); mock.a(5); mock.b(); mock.$verify(); mock.$reset(); mock.a(); mock.b(); mock.$replay(); mock.b(); mock.a(); mock.$verify(); mock.$reset(); mock.a(5).$times(2); mock.a(5); mock.a(2); mock.$replay(); mock.a(5); mock.a(5); mock.a(5); mock.a(2); mock.$verify(); } function testMultipleExpectations() { mock.a().$returns(1); mock.a().$returns(2); mock.$replay(); assertEquals(1, mock.a()); assertEquals(2, mock.a()); mock.$verify(); } function testMultipleExpectationArgs() { mock.a('asdf').$anyTimes(); mock.a('qwer').$anyTimes(); mock.b().$times(3); mock.$replay(); mock.a('asdf'); mock.b(); mock.a('asdf'); mock.a('qwer'); mock.b(); mock.a('qwer'); mock.b(); mock.$verify(); mock.$reset(); mock.a('asdf').$anyTimes(); mock.a('qwer').$anyTimes(); mock.$replay(); mock.a('asdf'); mock.a('qwer'); goog.bind(mock.a, mock, 'asdf'); goog.bind(mock.$verify, mock); } function testSameMethodOutOfOrder() { mock.a('foo').$returns(1); mock.a('bar').$returns(2); mock.$replay(); assertEquals(2, mock.a('bar')); assertEquals(1, mock.a('foo')); } function testSameMethodDifferentReturnValues() { mock.a('foo').$returns(1).$times(2); mock.a('foo').$returns(3); mock.a('bar').$returns(2); mock.$replay(); assertEquals(1, mock.a('foo')); assertEquals(2, mock.a('bar')); assertEquals(1, mock.a('foo')); assertEquals(3, mock.a('foo')); assertThrowsQuiet(function() { mock.a('foo'); mock.$verify(); }); } function testSameMethodBrokenExpectations() { // This is a weird corner case. // No way to ever make this verify no matter what you call after replaying, // because the second expectation of mock.a('foo') will be masked by // the first expectation that can be called any number of times, and so we // can never satisfy that second expectation. mock.a('foo').$returns(1).$anyTimes(); mock.a('bar').$returns(2); mock.a('foo').$returns(3); // LooseMock can detect this case and fail on $replay. assertThrowsQuiet(goog.bind(mock.$replay, mock)); mock.$reset(); // This is a variant of the corner case above, but it's harder to determine // that the expectation to mock.a('bar') can never be satisfied. So we don't // fail on $replay, but we do fail on $verify. mock.a(goog.testing.mockmatchers.isString).$returns(1).$anyTimes(); mock.a('bar').$returns(2); mock.$replay(); assertEquals(1, mock.a('foo')); assertEquals(1, mock.a('bar')); assertThrowsQuiet(goog.bind(mock.$verify, mock)); } function testSameMethodMultipleAnyTimes() { mock.a('foo').$returns(1).$anyTimes(); mock.a('foo').$returns(2).$anyTimes(); mock.$replay(); assertEquals(1, mock.a('foo')); assertEquals(1, mock.a('foo')); assertEquals(1, mock.a('foo')); // Note we'll never return 2 but that's ok. mock.$verify(); } function testFailingFast() { mock.a().$anyTimes(); mock.$replay(); mock.a(); mock.a(); assertThrowsQuiet(goog.bind(mock.b, mock)); mock.$reset(); // too many mock.a(); mock.b(); mock.$replay(); mock.a(); mock.b(); var message; silenceFailureLogging(); try { mock.a(); } catch (e) { message = e.message; } unsilenceFailureLogging(); assertTrue('No exception thrown on unexpected call', goog.isDef(message)); assertContains('Too many calls to a', message); } function testTimes() { mock.a().$times(3); mock.b().$times(2); mock.$replay(); mock.a(); mock.b(); mock.b(); mock.a(); mock.a(); mock.$verify(); } function testFailingSlow() { // not enough mock.a().$times(3); mock.$replay(); mock.a(); mock.a(); assertThrowsQuiet(goog.bind(mock.$verify, mock)); mock.$reset(); // not enough, interleaved order mock.a().$times(3); mock.b().$times(3); mock.$replay(); mock.a(); mock.b(); mock.a(); mock.b(); assertThrowsQuiet(goog.bind(mock.$verify, mock)); mock.$reset(); // bad args mock.a('asdf').$anyTimes(); mock.$replay(); mock.a('asdf'); assertThrowsQuiet(goog.bind(mock.a, mock, 'qwert')); assertThrowsQuiet(goog.bind(mock.$verify, mock)); } function testArgsAndReturns() { mock.a('asdf').$atLeastOnce().$returns(5); mock.b('qwer').$times(2).$returns(3); mock.$replay(); assertEquals(5, mock.a('asdf')); assertEquals(3, mock.b('qwer')); assertEquals(5, mock.a('asdf')); assertEquals(5, mock.a('asdf')); assertEquals(3, mock.b('qwer')); mock.$verify(); } function testThrows() { mock.a().$throws('exception!'); mock.$replay(); assertThrowsQuiet(goog.bind(mock.a, mock)); mock.$verify(); } function testDoes() { mock.a(1, 2).$does(function(a, b) {return a + b;}); mock.$replay(); assertEquals('Mock should call the function', 3, mock.a(1, 2)); mock.$verify(); } function testIgnoresExtraCalls() { mock = new goog.testing.LooseMock(RealObject, true); mock.a(); mock.$replay(); mock.a(); mock.b(); // doesn't throw mock.$verify(); } function testSkipAnyTimes() { mock = new goog.testing.LooseMock(RealObject); mock.a(1).$anyTimes(); mock.a(2).$anyTimes(); mock.a(3).$anyTimes(); mock.$replay(); mock.a(1); mock.a(3); mock.$verify(); } function testErrorMessageForBadArgs() { mock.a(); mock.$anyTimes(); mock.$replay(); var message; silenceFailureLogging(); try { mock.a('a'); } catch (e) { message = e.message; } unsilenceFailureLogging(); assertTrue('No exception thrown on verify', goog.isDef(message)); assertContains('Bad arguments to a()', message); } </script> </body> </html>