UNPKG

@spalger/kibana

Version:

Kibana is an open source (Apache Licensed), browser based analytics and search dashboard for Elasticsearch. Kibana is a snap to setup and start using. Kibana strives to be easy to get started with, while also being flexible and powerful, just like Elastic

192 lines (166 loc) 5.74 kB
define(function (require) { /** * # `Private()` * Private module loader, used to merge angular and require js dependency styles * by allowing a require.js module to export a single provider function that will * create a value used within an angular application. This provider can declare * angular dependencies by listing them as arguments, and can be require additional * Private modules. * * ## Define a private module provider: * ```js * define(function (require) { * return function PingProvider($http) { * this.ping = function () { * return $http.head('/health-check'); * }; * }; * }); * ``` * * ## Require a private module: * ```js * define(function (require) { * return function ServerHealthProvider(Private, Promise) { * var ping = Private(require('ui/ping')); * return { * check: Promise.method(function () { * var attempts = 0; * return (function attempt() { * attempts += 1; * return ping.ping() * .catch(function (err) { * if (attempts < 3) return attempt(); * }) * }()) * .then(function () { * return true; * }) * .catch(function () { * return false; * }); * }) * } * }; * }); * ``` * * # `Private.stub(provider, newInstance)` * `Private.stub()` replaces the instance of a module with another value. This is all we have needed until now. * * ```js * beforeEach(inject(function ($injector, Private) { * Private.stub( * // since this module just exports a function, we need to change * // what Private returns in order to modify it's behavior * require('ui/agg_response/hierarchical/_build_split'), * sinon.stub().returns(fakeSplit) * ); * })); * ``` * * # `Private.swap(oldProvider, newProvider)` * This new method does an 1-for-1 swap of module providers, unlike `stub()` which replaces a modules instance. * Pass the module you want to swap out, and the one it should be replaced with, then profit. * * Note: even though this example shows `swap()` being called in a config * function, it can be called from anywhere. It is particularly useful * in this scenario though. * * ```js * beforeEach(module('kibana', function (PrivateProvider) { * PrivateProvider.swap( * // since the courier is required automatically before the tests are loaded, * // we can't stub it's internal components unless we do so before the * // application starts. This is why angular has config functions * require('ui/courier/_redirect_when_missing'), * function StubbedRedirectProvider($decorate) { * // $decorate is a function that will instantiate the original module when called * return sinon.spy($decorate()); * } * ); * })); * ``` * * @param {[type]} prov [description] */ var _ = require('lodash'); var nextId = _.partial(_.uniqueId, 'privateProvider#'); function name(fn) { return fn.name || fn.toString().split('\n').shift(); } require('ui/modules').get('kibana') .provider('Private', function () { var provider = this; // one cache/swaps per Provider var cache = {}; var swaps = {}; // return the uniq id for this function function identify(fn) { if (typeof fn !== 'function') { throw new TypeError('Expected private module "' + fn + '" to be a function'); } if (fn.$$id) return fn.$$id; else return (fn.$$id = nextId()); } provider.stub = function (fn, instance) { cache[identify(fn)] = instance; return instance; }; provider.swap = function (fn, prov) { var id = identify(fn); swaps[id] = prov; }; provider.$get = ['$injector', function PrivateFactory($injector) { // prevent circular deps by tracking where we came from var privPath = []; var pathToString = function () { return privPath.map(name).join(' -> '); }; // call a private provider and return the instance it creates function instantiate(prov, locals) { if (~privPath.indexOf(prov)) { throw new Error( 'Circular refrence to "' + name(prov) + '"' + ' found while resolving private deps: ' + pathToString() ); } privPath.push(prov); var context = {}; var instance = $injector.invoke(prov, context, locals); if (!_.isObject(instance)) instance = context; privPath.pop(); return instance; } // retrieve an instance from cache or create and store on function get(id, prov, $delegateProv, $delegateId) { if (cache[id]) return cache[id]; var instance; if ($delegateId != null && $delegateProv != null) { instance = instantiate(prov, { $decorate: _.partial(get, $delegateId, $delegateProv) }); } else { instance = instantiate(prov); } return (cache[id] = instance); } // main api, get the appropriate instance for a provider function Private(prov) { var id = identify(prov); var $delegateId; var $delegateProv; if (swaps[id]) { $delegateId = id; $delegateProv = prov; prov = swaps[$delegateId]; id = identify(prov); } return get(id, prov, $delegateId, $delegateProv); } Private.stub = provider.stub; Private.swap = provider.swap; return Private; }]; }); });