mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Moving event to use Angular event's system
This commit is contained in:
parent
42f444118d
commit
96d3d2926c
19 changed files with 284 additions and 185 deletions
|
@ -40,7 +40,7 @@ define(function (require) {
|
|||
}
|
||||
});
|
||||
|
||||
app.directive('dashboardApp', function (Notifier, courier, savedVisualizations, AppState, timefilter) {
|
||||
app.directive('dashboardApp', function (Notifier, courier, savedVisualizations, appStateFactory, timefilter) {
|
||||
return {
|
||||
controller: function ($scope, $route, $routeParams, $location, configFile) {
|
||||
var notify = new Notifier({
|
||||
|
@ -56,7 +56,7 @@ define(function (require) {
|
|||
query: ''
|
||||
};
|
||||
|
||||
var $state = $scope.state = new AppState(stateDefaults);
|
||||
var $state = $scope.state = appStateFactory.create(stateDefaults);
|
||||
|
||||
$scope.configTemplate = new ConfigTemplate({
|
||||
save: require('text!apps/dashboard/partials/save_dashboard.html'),
|
||||
|
|
|
@ -49,7 +49,7 @@ define(function (require) {
|
|||
|
||||
|
||||
app.controller('discover', function ($scope, config, courier, $route, $window, savedSearches, savedVisualizations,
|
||||
Notifier, $location, globalState, AppState, timefilter, AdhocVis, Promise, Private) {
|
||||
Notifier, $location, globalState, appStateFactory, timefilter, AdhocVis, Promise, Private) {
|
||||
|
||||
var segmentedFetch = $scope.segmentedFetch = Private(require('apps/discover/_segmented_fetch'));
|
||||
var HitSortFn = Private(require('apps/discover/_hit_sort_fn'));
|
||||
|
@ -93,7 +93,7 @@ define(function (require) {
|
|||
'year'
|
||||
];
|
||||
|
||||
var $state = $scope.state = new AppState(stateDefaults);
|
||||
var $state = $scope.state = new appStateFactory.create(stateDefaults);
|
||||
|
||||
if (!_.contains(indexPatternList, $state.index)) {
|
||||
var reason = 'The index specified in the URL is not a configured pattern. ';
|
||||
|
|
|
@ -12,9 +12,9 @@ define(function (require) {
|
|||
.directive('kbnSettingsObjects', function (config, Notifier, Private) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
controller: function ($scope, $injector, $q, AppState) {
|
||||
controller: function ($scope, $injector, $q, appStateFactory) {
|
||||
|
||||
var $state = $scope.state = new AppState();
|
||||
var $state = $scope.state = new appStateFactory.create();
|
||||
|
||||
var resetCheckBoxes = function () {
|
||||
$scope.deleteAll = false;
|
||||
|
|
|
@ -47,7 +47,7 @@ define(function (require) {
|
|||
});
|
||||
|
||||
app.controller('VisualizeEditor', function ($scope, $route, $timeout, $window, Notifier, $location,
|
||||
globalState, AppState, timefilter, Private) {
|
||||
globalState, appStateFactory, timefilter, Private) {
|
||||
var aggs = Private(require('apps/visualize/saved_visualizations/_aggs'));
|
||||
|
||||
var notify = new Notifier({
|
||||
|
@ -63,7 +63,7 @@ define(function (require) {
|
|||
$scope.fields = _.sortBy(indexPattern.fields, 'name');
|
||||
$scope.fields.byName = indexPattern.fieldsByName;
|
||||
|
||||
var $state = $scope.state = new AppState(vis.getState());
|
||||
var $state = $scope.state = new appStateFactory.create(vis.getState());
|
||||
|
||||
if ($state.query) {
|
||||
vis.searchSource.set('query', $state.query);
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
define(function (require) {
|
||||
var _ = require('lodash');
|
||||
var rison = require('utils/rison');
|
||||
|
||||
return function ModelProvider() {
|
||||
function Model(attributes) {
|
||||
// Set the attributes or default to an empty object
|
||||
this._listners = {};
|
||||
_.assign(this, attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the attirbutes for the model
|
||||
* @returns {object}
|
||||
*/
|
||||
Model.prototype.toObject = function () {
|
||||
// return just the data.
|
||||
return _.omit(this, function (value, key) {
|
||||
return key.charAt(0) === '_' || _.isFunction(value);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the model to RISON
|
||||
* @returns {string}
|
||||
*/
|
||||
Model.prototype.toRISON = function () {
|
||||
return rison.encode(this.toObject());
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the model to JSON
|
||||
* @returns {object}
|
||||
*/
|
||||
Model.prototype.toJSON = function () {
|
||||
return this.toObject();
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a listner
|
||||
* @param {string} name The name of the event
|
||||
* @returns {void}
|
||||
*/
|
||||
Model.prototype.on = function (name, listner) {
|
||||
if (!_.isArray(this._listners[name])) {
|
||||
this._listners[name] = [];
|
||||
}
|
||||
this._listners[name].push(listner);
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes listener... if listner is empty then it removes all the events
|
||||
* @param {string} name The name of the event
|
||||
* @param {function} [listner]
|
||||
* @returns {void}
|
||||
*/
|
||||
Model.prototype.off = function (name, listner) {
|
||||
if (!listner) return delete this._listners[name];
|
||||
this._listners = _.filter(this._listners[name], function (fn) {
|
||||
return fn !== listner;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Emits and event
|
||||
* @param {string} name The name of the event
|
||||
* @param {mixed} [args...] Arguments pass to the listners
|
||||
* @returns {void}
|
||||
*/
|
||||
Model.prototype.emit = function () {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var name = args.shift();
|
||||
if (this._listners[name]) {
|
||||
_.each(this._listners[name], function (fn) {
|
||||
fn.apply(null, args);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return Model;
|
||||
|
||||
|
||||
};
|
||||
});
|
43
src/kibana/components/state_management/_base_object.js
Normal file
43
src/kibana/components/state_management/_base_object.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
define(function (require) {
|
||||
var _ = require('lodash');
|
||||
var rison = require('utils/rison');
|
||||
|
||||
return function BaseObjectProvider() {
|
||||
|
||||
function BaseObject(attributes) {
|
||||
// Set the attributes or default to an empty object
|
||||
_.assign(this, attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the attirbutes for the objct
|
||||
* @returns {object}
|
||||
*/
|
||||
BaseObject.prototype.toObject = function () {
|
||||
// return just the data.
|
||||
return _.omit(this, function (value, key) {
|
||||
return key.charAt(0) === '$' || key.charAt(0) === '_' || _.isFunction(value);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the model to RISON
|
||||
* @returns {string}
|
||||
*/
|
||||
BaseObject.prototype.toRISON = function () {
|
||||
return rison.encode(this.toObject());
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize the model to JSON
|
||||
* @returns {object}
|
||||
*/
|
||||
BaseObject.prototype.toJSON = function () {
|
||||
return this.toObject();
|
||||
};
|
||||
|
||||
return BaseObject;
|
||||
|
||||
|
||||
};
|
||||
});
|
31
src/kibana/components/state_management/_isolated_scope.js
Normal file
31
src/kibana/components/state_management/_isolated_scope.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
define(function (require) {
|
||||
var _ = require('lodash');
|
||||
|
||||
return function IsolatedScopeProvider($rootScope) {
|
||||
var Scope = $rootScope.constructor;
|
||||
|
||||
_.inherits(IsolatedScope, Scope);
|
||||
function IsolatedScope() {
|
||||
|
||||
IsolatedScope.Super.call(this);
|
||||
|
||||
// Prepare the new scope and attach it to the rootScope's linked list
|
||||
this.$root = $rootScope.$root;
|
||||
// ensure that there is just one async queue per $rootScope and its children
|
||||
this.$$asyncQueue = $rootScope.$$asyncQueue;
|
||||
this.$$postDigestQueue = $rootScope.$$postDigestQueue;
|
||||
this['this'] = this;
|
||||
this.$parent = $rootScope;
|
||||
this.$$prevSibling = $rootScope.$$childTail;
|
||||
if ($rootScope.$$childHead) {
|
||||
$rootScope.$$childTail.$$nextSibling = this;
|
||||
$rootScope.$$childTail = this;
|
||||
} else {
|
||||
$rootScope.$$childHead = $rootScope.$$childTail = this;
|
||||
}
|
||||
}
|
||||
|
||||
return IsolatedScope;
|
||||
|
||||
};
|
||||
});
|
|
@ -1,16 +1,15 @@
|
|||
define(function (require) {
|
||||
var _ = require('lodash');
|
||||
var module = require('modules').get('kibana/factories');
|
||||
|
||||
module.factory('AppState', function (Private) {
|
||||
return function AppStateProvider(Private) {
|
||||
var State = Private(require('components/state_management/state'));
|
||||
|
||||
_.inherits(AppState, State);
|
||||
function AppState(defaults) {
|
||||
AppState.Super.call(this, '_a', defaults);
|
||||
}
|
||||
_.inherits(AppState, State);
|
||||
|
||||
return AppState;
|
||||
});
|
||||
};
|
||||
|
||||
});
|
||||
|
|
41
src/kibana/components/state_management/app_state_factory.js
Normal file
41
src/kibana/components/state_management/app_state_factory.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
define(function (require) {
|
||||
var _ = require('lodash');
|
||||
var module = require('modules').get('kibana/factories');
|
||||
|
||||
module.service('appStateFactory', function (Private) {
|
||||
var AppState = Private(require('components/state_management/app_state'));
|
||||
|
||||
/**
|
||||
* We need to keep reference to the current so we can destroy it. When
|
||||
* we create a new one. The needs to happen because we need to reset the
|
||||
* listner queue and remove the refercne to the RootScope.
|
||||
*/
|
||||
var currentAppState;
|
||||
|
||||
var appStateFactory = {
|
||||
|
||||
/**
|
||||
* Factory method for creating AppStates
|
||||
* @param {string} appName The app name
|
||||
* @param {object} defaults The the defaults for the AppState
|
||||
* @returns {object} AppState
|
||||
*/
|
||||
create: function (defaults) {
|
||||
|
||||
// Check to see if the state already exists. If it does then we need
|
||||
// to call the destory method.
|
||||
if (!_.isUndefined(currentAppState)) {
|
||||
currentAppState.$destroy();
|
||||
}
|
||||
currentAppState = new AppState(defaults);
|
||||
|
||||
return currentAppState;
|
||||
}
|
||||
};
|
||||
|
||||
return appStateFactory;
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -9,10 +9,10 @@ define(function (require) {
|
|||
module.service('globalState', function (Private, $rootScope) {
|
||||
var State = Private(require('components/state_management/state'));
|
||||
|
||||
_.inherits(GlobalState, State);
|
||||
function GlobalState(defaults) {
|
||||
GlobalState.Super.call(this, '_g', defaults);
|
||||
}
|
||||
_.inherits(GlobalState, State);
|
||||
|
||||
GlobalState.prototype.writeToUrl = function (url) {
|
||||
return qs.replaceParamInUrl(url, this._urlParam, this.toRISON());
|
||||
|
|
|
@ -5,8 +5,10 @@ define(function (require) {
|
|||
var applyDiff = require('utils/diff_object');
|
||||
|
||||
return function StateProvider(Private, $rootScope, $location) {
|
||||
var Model = Private(require('components/state_management/_base_model'));
|
||||
var BaseObject = Private(require('components/state_management/_base_object'));
|
||||
var IsolatedScope = Private(require('components/state_management/_isolated_scope'));
|
||||
|
||||
_.inherits(State, IsolatedScope);
|
||||
function State(urlParam, defaults) {
|
||||
State.Super.call(this);
|
||||
this._defaults = defaults || {};
|
||||
|
@ -18,8 +20,9 @@ define(function (require) {
|
|||
// Initialize the State with fetch
|
||||
this.fetch();
|
||||
}
|
||||
_.inherits(State, Model);
|
||||
|
||||
// // mixin the base object methods
|
||||
_.mixin(State.prototype, BaseObject.prototype);
|
||||
|
||||
/**
|
||||
* Fetches the state from the url
|
||||
|
@ -33,7 +36,7 @@ define(function (require) {
|
|||
// it will change state in place.
|
||||
var diffResults = applyDiff(this, stash);
|
||||
if (diffResults.keys.length) {
|
||||
this.emit('fetch_with_changes', diffResults.keys);
|
||||
this.$emit('fetch_with_changes', diffResults.keys);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -50,7 +53,7 @@ define(function (require) {
|
|||
// it will change stash in place.
|
||||
var diffResults = applyDiff(stash, state);
|
||||
if (diffResults.keys.length) {
|
||||
this.emit('save_with_changes', diffResults.keys);
|
||||
this.$emit('save_with_changes', diffResults.keys);
|
||||
}
|
||||
search[this._urlParam] = this.toRISON();
|
||||
$location.search(search);
|
||||
|
@ -73,12 +76,18 @@ define(function (require) {
|
|||
* @returns {void}
|
||||
*/
|
||||
State.prototype.onUpdate = function (cb) {
|
||||
this.on('fetch_with_changes', cb);
|
||||
this.$on('fetch_with_changes', function () {
|
||||
// onUpdate interface for the listner expects the first argument to
|
||||
// be the start of the arguments passed to the event emitter. So we need
|
||||
// to lop off the first argument and pass the rest.
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
args.shift();
|
||||
cb.apply(null, args);
|
||||
});
|
||||
};
|
||||
|
||||
return State;
|
||||
|
||||
|
||||
};
|
||||
|
||||
});
|
||||
|
|
|
@ -9,6 +9,7 @@ define(function (require) {
|
|||
require('components/config/config');
|
||||
require('components/courier/courier');
|
||||
require('components/notify/notify');
|
||||
require('components/state_management/app_state_factory');
|
||||
require('directives/info');
|
||||
require('directives/spinner');
|
||||
require('directives/paginate');
|
||||
|
|
|
@ -14,6 +14,7 @@ define(function (require) {
|
|||
var filterPrivateAndMethods = function (obj) {
|
||||
return function (key) {
|
||||
if (_.isFunction(obj[key])) return false;
|
||||
if (key.charAt(0) === '$') return false;
|
||||
return key.charAt(0) !== '_';
|
||||
};
|
||||
};
|
||||
|
|
|
@ -74,9 +74,10 @@
|
|||
'specs/utils/versionmath',
|
||||
'specs/utils/routes/index',
|
||||
'specs/courier/search_source/_get_normalized_sort',
|
||||
'specs/state_management/_base_model',
|
||||
'specs/state_management/_base_object',
|
||||
'specs/state_management/state',
|
||||
'specs/utils/diff_object'
|
||||
'specs/utils/diff_object',
|
||||
'specs/state_management/_isolated_scope'
|
||||
], function (kibana, sinon) {
|
||||
kibana.load(function () {
|
||||
var xhr = sinon.useFakeXMLHttpRequest();
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
define(function (require) {
|
||||
var angular = require('angular');
|
||||
var mocks = require('angular-mocks');
|
||||
var _ = require('lodash');
|
||||
var sinon = require('sinon/sinon');
|
||||
require('services/private');
|
||||
|
||||
// Load kibana
|
||||
require('index');
|
||||
|
||||
describe('State Management', function () {
|
||||
describe('Model', function () {
|
||||
var $rootScope;
|
||||
var Model;
|
||||
|
||||
beforeEach(function () {
|
||||
module('kibana');
|
||||
|
||||
inject(function (_$rootScope_, Private) {
|
||||
$rootScope = _$rootScope_;
|
||||
Model = Private(require('components/state_management/_base_model'));
|
||||
});
|
||||
});
|
||||
|
||||
it('should take an inital set of values', function () {
|
||||
var model = new Model({ message: 'test' });
|
||||
expect(model).to.have.property('message', 'test');
|
||||
});
|
||||
|
||||
it('should trigger $on events', function (done) {
|
||||
var model = new Model();
|
||||
var stub = sinon.stub();
|
||||
model.on('test', stub);
|
||||
model.emit('test');
|
||||
sinon.assert.calledOnce(stub);
|
||||
done();
|
||||
});
|
||||
|
||||
|
||||
it('should be extendable ($on/$emit)', function (done) {
|
||||
|
||||
function MyModel() {
|
||||
MyModel.Super.call(this);
|
||||
}
|
||||
_.inherits(MyModel, Model);
|
||||
|
||||
var model = new MyModel();
|
||||
var stub = sinon.stub();
|
||||
model.on('test', stub);
|
||||
model.emit('test');
|
||||
sinon.assert.calledOnce(stub);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should serialize _attributes to RISON', function () {
|
||||
var model = new Model();
|
||||
model.message = 'Testing... 1234';
|
||||
var rison = model.toRISON();
|
||||
expect(rison).to.equal('(message:\'Testing... 1234\')');
|
||||
});
|
||||
|
||||
it('should serialize _attributes for JSON', function () {
|
||||
var model = new Model();
|
||||
model.message = 'Testing... 1234';
|
||||
var json = JSON.stringify(model);
|
||||
expect(json).to.equal('{"message":"Testing... 1234"}');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
});
|
49
test/unit/specs/state_management/_base_object.js
Normal file
49
test/unit/specs/state_management/_base_object.js
Normal file
|
@ -0,0 +1,49 @@
|
|||
define(function (require) {
|
||||
var angular = require('angular');
|
||||
var mocks = require('angular-mocks');
|
||||
var _ = require('lodash');
|
||||
var sinon = require('sinon/sinon');
|
||||
require('services/private');
|
||||
|
||||
// Load kibana
|
||||
require('index');
|
||||
|
||||
describe('State Management', function () {
|
||||
describe('BaseObject', function () {
|
||||
var $rootScope;
|
||||
var BaseObject;
|
||||
|
||||
beforeEach(function () {
|
||||
module('kibana');
|
||||
|
||||
inject(function (_$rootScope_, Private) {
|
||||
$rootScope = _$rootScope_;
|
||||
BaseObject = Private(require('components/state_management/_base_object'));
|
||||
});
|
||||
});
|
||||
|
||||
it('should take an inital set of values', function () {
|
||||
var baseObject = new BaseObject({ message: 'test' });
|
||||
expect(baseObject).to.have.property('message', 'test');
|
||||
});
|
||||
|
||||
it('should serialize _attributes to RISON', function () {
|
||||
var baseObject = new BaseObject();
|
||||
baseObject.message = 'Testing... 1234';
|
||||
var rison = baseObject.toRISON();
|
||||
expect(rison).to.equal('(message:\'Testing... 1234\')');
|
||||
});
|
||||
|
||||
it('should serialize _attributes for JSON', function () {
|
||||
var baseObject = new BaseObject();
|
||||
baseObject.message = 'Testing... 1234';
|
||||
baseObject._private = 'foo';
|
||||
baseObject.$private = 'stuff';
|
||||
var json = JSON.stringify(baseObject);
|
||||
expect(json).to.equal('{"message":"Testing... 1234"}');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
});
|
62
test/unit/specs/state_management/_isolated_scope.js
Normal file
62
test/unit/specs/state_management/_isolated_scope.js
Normal file
|
@ -0,0 +1,62 @@
|
|||
define(function (require) {
|
||||
var angular = require('angular');
|
||||
var mocks = require('angular-mocks');
|
||||
var _ = require('lodash');
|
||||
var sinon = require('sinon/sinon');
|
||||
require('services/private');
|
||||
|
||||
// Load kibana
|
||||
require('index');
|
||||
|
||||
describe('State Management', function () {
|
||||
describe('IsolatedScope', function () {
|
||||
var $rootScope;
|
||||
var IsolatedScope;
|
||||
|
||||
beforeEach(function () {
|
||||
module('kibana');
|
||||
|
||||
inject(function (_$rootScope_, Private) {
|
||||
$rootScope = _$rootScope_;
|
||||
IsolatedScope = Private(require('components/state_management/_isolated_scope'));
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle $on events', function () {
|
||||
var scope = new IsolatedScope();
|
||||
var stub = sinon.stub();
|
||||
scope.$on('test', stub);
|
||||
scope.$emit('test', 'Hello World');
|
||||
sinon.assert.calledOnce(stub);
|
||||
});
|
||||
|
||||
it('should handle $watch events', function () {
|
||||
var scope = new IsolatedScope();
|
||||
var stub = sinon.stub();
|
||||
scope.$watch('test', stub);
|
||||
scope.test = 'Hello World';
|
||||
$rootScope.$apply();
|
||||
sinon.assert.calledOnce(stub);
|
||||
});
|
||||
|
||||
it('should work with inherited objects', function () {
|
||||
_.inherits(MyScope, IsolatedScope);
|
||||
function MyScope() {
|
||||
MyScope.Super.call(this);
|
||||
}
|
||||
var scope = new MyScope();
|
||||
var eventStub = sinon.stub();
|
||||
var watchStub = sinon.stub();
|
||||
scope.$on('test', eventStub);
|
||||
scope.$emit('test', 'Hello World');
|
||||
scope.$watch('test', watchStub);
|
||||
scope.test = 'Hello World';
|
||||
$rootScope.$apply();
|
||||
sinon.assert.calledOnce(eventStub);
|
||||
sinon.assert.calledOnce(watchStub);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
});
|
|
@ -11,7 +11,7 @@ define(function (require) {
|
|||
describe('State Management', function () {
|
||||
describe('State', function () {
|
||||
|
||||
var $rootScope, $location, State, Model;
|
||||
var $rootScope, $location, State, IsolatedScope;
|
||||
|
||||
beforeEach(function () {
|
||||
module('kibana');
|
||||
|
@ -20,13 +20,13 @@ define(function (require) {
|
|||
$location = _$location_;
|
||||
$rootScope = _$rootScope_;
|
||||
State = Private(require('components/state_management/state'));
|
||||
Model = Private(require('components/state_management/_base_model'));
|
||||
IsolatedScope = Private(require('components/state_management/_isolated_scope'));
|
||||
});
|
||||
});
|
||||
|
||||
it('should inherit from Model', function () {
|
||||
it('should inherit from IsolatedScope', function () {
|
||||
var state = new State();
|
||||
expect(state).to.be.an(Model);
|
||||
expect(state).to.be.an(IsolatedScope);
|
||||
});
|
||||
|
||||
it('should save to $location.search()', function () {
|
||||
|
@ -39,13 +39,14 @@ define(function (require) {
|
|||
|
||||
it('should emit an event if changes are saved', function (done) {
|
||||
var state = new State();
|
||||
state.on('save_with_changes', function (keys) {
|
||||
state.$on('save_with_changes', function (event, keys) {
|
||||
expect(keys).to.eql(['test']);
|
||||
done();
|
||||
});
|
||||
state.test = 'foo';
|
||||
state.save();
|
||||
var search = $location.search();
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should fetch the state from $location.search()', function () {
|
||||
|
@ -57,7 +58,7 @@ define(function (require) {
|
|||
|
||||
it('should emit an event if changes are fetched', function (done) {
|
||||
var state = new State();
|
||||
state.on('fetch_with_changes', function (keys) {
|
||||
state.$on('fetch_with_changes', function (events, keys) {
|
||||
expect(keys).to.eql(['foo']);
|
||||
done();
|
||||
});
|
||||
|
@ -66,6 +67,16 @@ define(function (require) {
|
|||
expect(state).to.have.property('foo', 'bar');
|
||||
});
|
||||
|
||||
it('should have events that attach to scope', function (done) {
|
||||
var state = new State();
|
||||
state.$on('test', function (event, message) {
|
||||
expect(message).to.equal('foo');
|
||||
done();
|
||||
});
|
||||
state.$emit('test', 'foo');
|
||||
$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should fire listeners for #onUpdate() on #fetch()', function (done) {
|
||||
var state = new State();
|
||||
state.onUpdate(function (keys) {
|
||||
|
@ -102,9 +113,9 @@ define(function (require) {
|
|||
|
||||
it('should call fetch when $routeUpdate is fired on $rootScope', function () {
|
||||
var state = new State();
|
||||
var stub = sinon.spy(state, 'fetch');
|
||||
var spy = sinon.spy(state, 'fetch');
|
||||
$rootScope.$emit('$routeUpdate', 'test');
|
||||
sinon.assert.calledOnce(stub);
|
||||
sinon.assert.calledOnce(spy);
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -50,5 +50,12 @@ define(function (require) {
|
|||
expect(target).to.not.have.property('_private');
|
||||
});
|
||||
|
||||
it('should ignore dollar signs', function () {
|
||||
var target = { foo: 'bar', test: 'foo' };
|
||||
var source = { foo: 'test', $private: 'foo' };
|
||||
diff(target, source);
|
||||
expect(target).to.not.have.property('$private');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue