Author: mhermanto Date: Fri Nov 5 22:36:55 2010 New Revision: 1031865 URL: http://svn.apache.org/viewvc?rev=1031865&view=rev Log: Common container: facilitate timing for gadget navigation - timing information can be broadcast'ed to containers for analysis / custom reporting. - Shindig will only (to start) synchronously broadcast metadata response time, mrt. - at Google, we additionally broadcast in-gadget-render times, page render times (prt), dom load (dl) and ol (onload). - this is done by an asychronous hook to our custom timing feature. &mid= is in render URL to uniquely identify gadget on page.
http://codereview.appspot.com/2560041/ Added: shindig/trunk/features/src/test/javascript/features/container/ shindig/trunk/features/src/test/javascript/features/container/container_test.js shindig/trunk/features/src/test/javascript/features/container/gadget_holder_test.js shindig/trunk/features/src/test/javascript/features/container/gadget_site_test.js shindig/trunk/features/src/test/javascript/features/container/service_test.js shindig/trunk/features/src/test/javascript/features/container/util_test.js Modified: shindig/trunk/features/pom.xml shindig/trunk/features/src/main/javascript/features/container/constant.js shindig/trunk/features/src/main/javascript/features/container/container.js shindig/trunk/features/src/main/javascript/features/container/gadget_holder.js shindig/trunk/features/src/main/javascript/features/container/gadget_site.js shindig/trunk/features/src/main/javascript/features/container/util.js shindig/trunk/features/src/test/javascript/features/alltests.js Modified: shindig/trunk/features/pom.xml URL: http://svn.apache.org/viewvc/shindig/trunk/features/pom.xml?rev=1031865&r1=1031864&r2=1031865&view=diff ============================================================================== --- shindig/trunk/features/pom.xml (original) +++ shindig/trunk/features/pom.xml Fri Nov 5 22:36:55 2010 @@ -116,6 +116,12 @@ <source>core.prefs/prefs.js</source> <source>core.log/log.js</source> <source>core.io/io.js</source> + <source>container/constant.js</source> + <source>container/util.js</source> + <source>container/service.js</source> + <source>container/gadget_holder.js</source> + <source>container/gadget_site.js</source> + <source>container/container.js</source> <source>i18n/currencycodemap.js</source> <source>i18n/datetimeformat.js</source> <source>i18n/datetimeparse.js</source> Modified: shindig/trunk/features/src/main/javascript/features/container/constant.js URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/constant.js?rev=1031865&r1=1031864&r2=1031865&view=diff ============================================================================== --- shindig/trunk/features/src/main/javascript/features/container/constant.js (original) +++ shindig/trunk/features/src/main/javascript/features/container/constant.js Fri Nov 5 22:36:55 2010 @@ -54,6 +54,30 @@ shindig.container.TokenResponse.TOKEN = /** + * Constants to key into timing response JSON. + * @type {string} + */ +shindig.container.NavigateTiming = {}; +// The gadget URL reporting this timing information. +shindig.container.NavigateTiming.URL = 'url'; +// The gadget site ID reporting this timing information. +shindig.container.NavigateTiming.ID = 'id'; +// Absolute time (ms) when gadget navigation is requested. +shindig.container.NavigateTiming.START = 'start'; +// Time (ms) to receive XHR response time. In CC, for metadata and token. +shindig.container.NavigateTiming.XRT = 'xrt'; +// Time (ms) to receive first byte. Typically timed at start of page. +shindig.container.NavigateTiming.SRT = 'srt'; +// Time (ms) to load the DOM. Typically timed at end of page. +shindig.container.NavigateTiming.DL = 'dl'; +// Time (ms) when body onload is called. +shindig.container.NavigateTiming.OL = 'ol'; +// Time (ms) when page is ready for use. Typically happen after data XHR (ex: +// calendar, email) is received/presented to users. Overridable by user. +shindig.container.NavigateTiming.PRT = 'prt'; + + +/** * Constants to key into request renderParam JSON. * @enum {string} */ Modified: shindig/trunk/features/src/main/javascript/features/container/container.js URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/container.js?rev=1031865&r1=1031864&r2=1031865&view=diff ============================================================================== --- shindig/trunk/features/src/main/javascript/features/container/container.js (original) +++ shindig/trunk/features/src/main/javascript/features/container/container.js Fri Nov 5 22:36:55 2010 @@ -84,6 +84,14 @@ shindig.container.Container = function(o 30 * 60 * 1000)); /** + * @type {number} + * @private + */ + this.navigateCallback_ = String(shindig.container.util.getSafeJsonValue( + config, shindig.container.ContainerConfig.NAVIGATE_CALLBACK, + null)); + + /** * @type {shindig.container.Service} * @private */ @@ -110,8 +118,13 @@ shindig.container.Container = function(o */ shindig.container.Container.prototype.newGadgetSite = function( gadgetEl, opt_bufferEl) { - var site = new shindig.container.GadgetSite( - this.service_, gadgetEl, opt_bufferEl); + var bufferEl = opt_bufferEl || null; + var site = new shindig.container.GadgetSite({ + 'service' : this.service_, + 'navigateCallback' : this.navigateCallback_, + 'gadgetEl' : gadgetEl, + 'bufferEl' : bufferEl + }); this.sites_[site.getId()] = site; return site; }; @@ -313,6 +326,13 @@ shindig.container.ContainerConfig.RENDER * @const */ shindig.container.ContainerConfig.TOKEN_REFRESH_INTERVAL = 'tokenRefreshInterval'; +/** + * Globally-defined callback function upon gadget navigation. Useful to + * broadcast timing and stat information back to container. + * @type {string} + * @const + */ +shindig.container.ContainerConfig.NAVIGATE_CALLBACK = 'navigateCallback'; /** Modified: shindig/trunk/features/src/main/javascript/features/container/gadget_holder.js URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/gadget_holder.js?rev=1031865&r1=1031864&r2=1031865&view=diff ============================================================================== --- shindig/trunk/features/src/main/javascript/features/container/gadget_holder.js (original) +++ shindig/trunk/features/src/main/javascript/features/container/gadget_holder.js Fri Nov 5 22:36:55 2010 @@ -259,7 +259,8 @@ shindig.container.GadgetHolder.prototype uri.setExistingP('st', this.securityToken_); } - uri.setFP('mid', String(this.siteId_)); + // Uniquely identify possibly-same gadgets on a page. + uri.setQP('mid', String(this.siteId_)); if (!shindig.container.util.isEmptyJson(this.viewParams_)) { var gadgetParamText = gadgets.json.stringify(this.viewParams_); Modified: shindig/trunk/features/src/main/javascript/features/container/gadget_site.js URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/gadget_site.js?rev=1031865&r1=1031864&r2=1031865&view=diff ============================================================================== --- shindig/trunk/features/src/main/javascript/features/container/gadget_site.js (original) +++ shindig/trunk/features/src/main/javascript/features/container/gadget_site.js Fri Nov 5 22:36:55 2010 @@ -25,32 +25,37 @@ /** - * @param {shindig.container.Service} service To fetch gadgets metadata, token. - * @param {Element} gadgetEl Element into which to render the gadget. - * @param {Element=} opt_bufferEl Optional element for double buffering. + * @param {Object} args containing: + * {shindig.container.Service} service to fetch gadgets metadata, token. + * {string} navigateCallback name of callback function on navigateTo(). + * {Element} gadgetEl Element into which to render the gadget. + * {Element} bufferEl Optional element for double buffering. * @constructor */ -shindig.container.GadgetSite = function(service, gadgetEl, opt_bufferEl) { +shindig.container.GadgetSite = function(args) { /** - * Service to fetch gadgets metadata and token. * @type {shindig.container.Service} * @private */ - this.service_ = service; + this.service_ = args['service']; + + /** + * @type {string} + * @private + */ + this.navigateCallback_ = args['navigateCallback']; /** - * Element holding the current gadget. * @type {Element} * @private */ - this.currentGadgetEl_ = gadgetEl; + this.currentGadgetEl_ = args['gadgetEl']; /** - * Element holding the loading gadget for 2x buffering. - * @type {Element?} + * @type {Element} * @private */ - this.loadingGadgetEl_ = opt_bufferEl || null; + this.loadingGadgetEl_ = args['bufferEl']; /** * Unique ID of this site. @@ -201,10 +206,13 @@ shindig.container.GadgetSite.prototype.g */ shindig.container.GadgetSite.prototype.navigateTo = function( gadgetUrl, viewParams, renderParams, opt_callback) { + var start = shindig.container.util.getCurrentTimeMs(); + var cached = this.service_.getCachedGadgetMetadata(gadgetUrl); var callback = opt_callback || function() {}; var request = shindig.container.util.newMetadataRequest([gadgetUrl]); var self = this; this.service_.getGadgetMetadata(request, function(response) { + var xrt = (!cached) ? (shindig.container.util.getCurrentTimeMs() - start) : 0; var gadgetInfo = response[gadgetUrl]; if (gadgetInfo.error) { var message = ['Failed to navigate for gadget ', gadgetUrl, '.'].join(''); @@ -212,6 +220,15 @@ shindig.container.GadgetSite.prototype.n } else { self.render(gadgetInfo, viewParams, renderParams); } + + // Return metadata server response time. + var timingInfo = {}; + timingInfo[shindig.container.NavigateTiming.URL] = gadgetUrl; + timingInfo[shindig.container.NavigateTiming.ID] = self.id_; + timingInfo[shindig.container.NavigateTiming.START] = start; + timingInfo[shindig.container.NavigateTiming.XRT] = xrt; + self.onNavigateTo(timingInfo); + // Possibly with an error. Leave to user to deal with raw response. callback(gadgetInfo); }); @@ -219,6 +236,20 @@ shindig.container.GadgetSite.prototype.n /** + * Provide overridable callback invoked when navigateTo is completed. + * @param {Object} data the statistic/timing information to return. + */ +shindig.container.GadgetSite.prototype.onNavigateTo = function(data) { + if (this.navigateCallback_) { + var func = window[this.navigateCallback_]; + if (typeof func === 'function') { + func(data); + } + } +}; + + +/** * Render a gadget in this site, using a JSON gadget description. * @param {Object} gadgetInfo the JSON gadget description. * @param {Object} viewParams Look at shindig.container.ViewParam. Modified: shindig/trunk/features/src/main/javascript/features/container/util.js URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/util.js?rev=1031865&r1=1031864&r2=1031865&view=diff ============================================================================== --- shindig/trunk/features/src/main/javascript/features/container/util.js (original) +++ shindig/trunk/features/src/main/javascript/features/container/util.js Fri Nov 5 22:36:55 2010 @@ -91,7 +91,9 @@ shindig.container.util.newTokenRequest = return { 'container': window.__CONTAINER, 'ids': gadgetUrls, - 'fields': ['token'] + 'fields': [ + 'token' + ] }; }; @@ -132,3 +134,11 @@ shindig.container.util.warn = function(m console.warn(message); } }; + + +/** + * @return {number} current time in ms. + */ +shindig.container.util.getCurrentTimeMs = function() { + return new Date().getTime(); +}; \ No newline at end of file Modified: shindig/trunk/features/src/test/javascript/features/alltests.js URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/test/javascript/features/alltests.js?rev=1031865&r1=1031864&r2=1031865&view=diff ============================================================================== --- shindig/trunk/features/src/test/javascript/features/alltests.js (original) +++ shindig/trunk/features/src/test/javascript/features/alltests.js Fri Nov 5 22:36:55 2010 @@ -77,6 +77,12 @@ if (!this.JsUtil) { eval(JsUtil.prototype.include(srcDir + '/osapi/gadgetsrpctransport.js')); eval(JsUtil.prototype.include(srcDir + '/osapi/peoplehelpers.js')); eval(JsUtil.prototype.include(srcDir + '/shindig.uri/uri.js')); + eval(JsUtil.prototype.include(srcDir + '/container/constant.js')); + eval(JsUtil.prototype.include(srcDir + '/container/util.js')); + eval(JsUtil.prototype.include(srcDir + '/container/service.js')); + eval(JsUtil.prototype.include(srcDir + '/container/gadget_holder.js')); + eval(JsUtil.prototype.include(srcDir + '/container/gadget_site.js')); + eval(JsUtil.prototype.include(srcDir + '/container/container.js')); eval(JsUtil.prototype.include(testToolsDir + "/JsUnit.js")); eval(JsUtil.prototype.include(testSrcDir + "/core/authtest.js")); eval(JsUtil.prototype.include(testSrcDir + "/core/config-test.js")); @@ -99,6 +105,11 @@ if (!this.JsUtil) { eval(JsUtil.prototype.include(testSrcDir + "/views/urltemplatetest.js")); eval(JsUtil.prototype.include(testSrcDir + "/xhrwrapper/xhrwrappertest.js")); eval(JsUtil.prototype.include(testSrcDir + '/shindig.uri/uritest.js')); + eval(JsUtil.prototype.include(testSrcDir + '/container/util_test.js')); + eval(JsUtil.prototype.include(testSrcDir + '/container/service_test.js')); + eval(JsUtil.prototype.include(testSrcDir + '/container/gadget_holder_test.js')); + eval(JsUtil.prototype.include(testSrcDir + '/container/gadget_site_test.js')); + eval(JsUtil.prototype.include(testSrcDir + '/container/container_test.js')); } function AllTests() { Added: shindig/trunk/features/src/test/javascript/features/container/container_test.js URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/test/javascript/features/container/container_test.js?rev=1031865&view=auto ============================================================================== --- shindig/trunk/features/src/test/javascript/features/container/container_test.js (added) +++ shindig/trunk/features/src/test/javascript/features/container/container_test.js Fri Nov 5 22:36:55 2010 @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * @fileoverview + * + * Unittests for the container library. + */ + +function ContainerTest(name) { + TestCase.call(this, name); +} + +ContainerTest.inherits(TestCase); + +ContainerTest.prototype.setUp = function() { + this.apiUri = window.__API_URI; + window.__API_URI = shindig.uri('http://shindig.com'); + this.containerUri = window.__CONTAINER_URI; + window.__CONTAINER_URI = shindig.uri('http://container.com'); +}; + +ContainerTest.prototype.tearDown = function() { + window.__API_URI = this.apiUri; + window.__CONTAINER_URI = this.containerUri; +}; + +ContainerTest.prototype.testNew = function() { + // TODO: here for a placeholder. +}; Added: shindig/trunk/features/src/test/javascript/features/container/gadget_holder_test.js URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/test/javascript/features/container/gadget_holder_test.js?rev=1031865&view=auto ============================================================================== --- shindig/trunk/features/src/test/javascript/features/container/gadget_holder_test.js (added) +++ shindig/trunk/features/src/test/javascript/features/container/gadget_holder_test.js Fri Nov 5 22:36:55 2010 @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * @fileoverview + * + * Unittests for the gadget_holder library. + */ + +function GadgetHolderTest(name) { + TestCase.call(this, name); +} + +GadgetHolderTest.inherits(TestCase); + +GadgetHolderTest.prototype.setUp = function() { +}; + +GadgetHolderTest.prototype.tearDown = function() { +}; + +GadgetHolderTest.prototype.testNew = function() { + var element = {}; + var holder = new shindig.container.GadgetHolder(123, element); + this.assertEquals(element, holder.getElement()); + this.assertNull(holder.getIframeId()); + this.assertNull(holder.getGadgetInfo()); + this.assertNull(holder.getUrl()); +}; Added: shindig/trunk/features/src/test/javascript/features/container/gadget_site_test.js URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/test/javascript/features/container/gadget_site_test.js?rev=1031865&view=auto ============================================================================== --- shindig/trunk/features/src/test/javascript/features/container/gadget_site_test.js (added) +++ shindig/trunk/features/src/test/javascript/features/container/gadget_site_test.js Fri Nov 5 22:36:55 2010 @@ -0,0 +1,137 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * @fileoverview + * + * Unittests for the gadget_site library. + */ + +function GadgetSiteTest(name) { + TestCase.call(this, name); +} + +GadgetSiteTest.inherits(TestCase); + +GadgetSiteTest.prototype.NAVIGATE_CALLBACK = 'nc'; +GadgetSiteTest.prototype.GADGET_URL = 'http://gadget/abc.xml'; + +GadgetSiteTest.prototype.setUp = function() { + var self = this; + + this.util_getCurrentTimeMs_value = 100; + this.util_getCurrentTimeMs_func = shindig.container.util.getCurrentTimeMs; + shindig.container.util.getCurrentTimeMs = function() { + return self.util_getCurrentTimeMs_value++; + }; + + this.util_warn_value = null; + this.util_warn_func = shindig.container.util.warn; + shindig.container.util.warn = function(value) { + self.util_warn_value = value; + }; + + window[this.NAVIGATE_CALLBACK] = function(timingInfo) { + self.window_navigateCallback_timingInfo = timingInfo; + }; +}; + +GadgetSiteTest.prototype.tearDown = function() { + shindig.container.util.getCurrentTimeMs = this.util_getCurrentTimeMs_func; + shindig.container.util.warn = this.util_warn_func; + delete window[this.NAVIGATE_CALLBACK]; +}; + +GadgetSiteTest.prototype.testGetId = function() { + var site; + site = new shindig.container.GadgetSite({}); + this.assertEquals(0, site.getId()); + site = new shindig.container.GadgetSite({}); + this.assertEquals(1, site.getId()); +}; + +GadgetSiteTest.prototype.testNavigateToWithUncachedError = function() { + var self = this; + var service = { + getCachedGadgetMetadata : function(url) { + self.service_getCachedGadgetMetadata_url = url; + return null; // not cached + }, + getGadgetMetadata : function(request, callback) { + self.service_getGadgetMetadata_request = request; + self.service_getGadgetMetadata_callback = callback; + callback(self.newMetadataError(self.GADGET_URL, 'na')); + } + }; + var navigateToCallback = function(gadgetInfo) { + self.site_navigateToCallback_gadgetInfo = gadgetInfo; + }; + var site = this.newGadgetSite(service, 'nc'); + site.navigateTo(this.GADGET_URL, {}, {}, navigateToCallback); + this.assertEquals('Failed to navigate for gadget ' + this.GADGET_URL + '.', + this.util_warn_value); + this.assertTrue(this.window_navigateCallback_timingInfo['id'] >= 0); + this.assertEquals(this.GADGET_URL, this.window_navigateCallback_timingInfo['url']); + this.assertEquals(100, this.window_navigateCallback_timingInfo['start']); + this.assertEquals(1, this.window_navigateCallback_timingInfo['xrt']); // not cached + this.assertEquals(this.GADGET_URL, this.service_getCachedGadgetMetadata_url); + this.assertTrue(this.site_navigateToCallback_gadgetInfo['error'] != null); +}; + +GadgetSiteTest.prototype.testNavigateToWithCachedError = function() { + var self = this; + var service = { + getCachedGadgetMetadata : function(url) { + self.service_getCachedGadgetMetadata_url = url; + return self.newMetadataError(self.GADGET_URL, 'na'); // cached + }, + getGadgetMetadata : function(request, callback) { + self.service_getGadgetMetadata_request = request; + self.service_getGadgetMetadata_callback = callback; + callback(self.newMetadataError(self.GADGET_URL, 'na')); + } + }; + var navigateToCallback = function(gadgetInfo) { + self.site_navigateToCallback_gadgetInfo = gadgetInfo; + }; + var site = this.newGadgetSite(service, this.NAVIGATE_CALLBACK); + site.navigateTo(this.GADGET_URL, {}, {}, navigateToCallback); + this.assertEquals('Failed to navigate for gadget ' + this.GADGET_URL + '.', + this.util_warn_value); + this.assertTrue(this.window_navigateCallback_timingInfo['id'] >= 0); + this.assertEquals(this.GADGET_URL, this.window_navigateCallback_timingInfo['url']); + this.assertEquals(100, this.window_navigateCallback_timingInfo['start']); + this.assertEquals(0, this.window_navigateCallback_timingInfo['xrt']); // cached + this.assertEquals(this.GADGET_URL, this.service_getCachedGadgetMetadata_url); + this.assertTrue(this.site_navigateToCallback_gadgetInfo['error'] != null); +}; + +GadgetSiteTest.prototype.newMetadataError = function(url, message) { + var response = {}; + response[url] = {}; + response[url]['error'] = message; + return response; +}; + +GadgetSiteTest.prototype.newGadgetSite = function(service, navigateCallback) { + return new shindig.container.GadgetSite({ + 'service' : service, + 'navigateCallback' : navigateCallback + }); +}; Added: shindig/trunk/features/src/test/javascript/features/container/service_test.js URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/test/javascript/features/container/service_test.js?rev=1031865&view=auto ============================================================================== --- shindig/trunk/features/src/test/javascript/features/container/service_test.js (added) +++ shindig/trunk/features/src/test/javascript/features/container/service_test.js Fri Nov 5 22:36:55 2010 @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * @fileoverview + * + * Unittests for the service library. + */ + +function ServiceTest(name) { + TestCase.call(this, name); +} + +ServiceTest.inherits(TestCase); + +ServiceTest.prototype.setUp = function() { + this.apiUri = window.__API_URI; + window.__API_URI = shindig.uri('http://shindig.com'); +}; + +ServiceTest.prototype.tearDown = function() { + window.__API_URI = this.apiUri; +}; + +ServiceTest.prototype.testNew = function() { + var service = new shindig.container.Service(); + this.assertTrue(service != null); +}; Added: shindig/trunk/features/src/test/javascript/features/container/util_test.js URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/test/javascript/features/container/util_test.js?rev=1031865&view=auto ============================================================================== --- shindig/trunk/features/src/test/javascript/features/container/util_test.js (added) +++ shindig/trunk/features/src/test/javascript/features/container/util_test.js Fri Nov 5 22:36:55 2010 @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * @fileoverview + * + * Unittests for the util library. + */ + +function UtilTest(name) { + TestCase.call(this, name); +} + +UtilTest.inherits(TestCase); + + +UtilTest.prototype.setUp = function() { + this.container = window.__CONTAINER; + window.__CONTAINER = 'abc'; +}; + +UtilTest.prototype.tearDown = function() { + window.__CONTAINER = this.container; +}; + +UtilTest.prototype.testIsEmptyJson = function() { + this.assertEquals(true, shindig.container.util.isEmptyJson({})); + this.assertFalse(shindig.container.util.isEmptyJson({ 'a' : 'b' })); +}; + +UtilTest.prototype.testNewMetadataRequest = function() { + var req = shindig.container.util.newMetadataRequest(['a.xml', 'b.xml']); + this.assertEquals('abc', req.container); + this.assertEquals(2, req.ids.length); + this.assertEquals('a.xml', req.ids[0]); + this.assertEquals('b.xml', req.ids[1]); +};
