Skip to content
This repository has been archived by the owner on Sep 1, 2022. It is now read-only.

Commit

Permalink
Use dependency injection for Jupyter Notebook deps
Browse files Browse the repository at this point in the history
Should allow us to use init.js/DeclWidgetModel.js outside of
Notebook env.
Fix `IPython` object references.
Newer `new_widget` API takes 3rd param.
`init()` should be backwards compat with older API.
Use getter for kernel instance -- helps with case where kernel
is restarted and a new kernel instance used.
Fix tests which weren't properly testing server state.

Ref #141
Ref #196

(c) Copyright IBM Corp. 2016
  • Loading branch information
jhpedemonte committed Mar 14, 2016
1 parent 4378e34 commit 1085b21
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 112 deletions.
50 changes: 26 additions & 24 deletions elements/urth-core-behaviors/execution-complete-behavior.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,35 @@
This Behavior represents the completion of a code cell's execution.
-->
<script>
window.Urth = window.Urth || {};
(function() {
'use strict';
var Urth = window.Urth = window.Urth || {};

Urth.ExecutionCompleteBehavior = {
Urth.ExecutionCompleteBehavior = {

ready: function() {
// Code execution defined to be complete when an ExecuteReply is received.
console.debug("Registering _onExecutionComplete for Execute Reply messages.");
this.__replyCallback = this._onExecutionComplete.bind(this);
ready: function() {
// Code execution defined to be complete when an ExecuteReply is received.
console.debug("Registering _onExecutionComplete for Execute Reply messages.");
this.__replyCallback = this._onExecutionComplete.bind(this);

IPython.notebook.kernel.widget_manager.notebook.events.on(
'shell_reply.Kernel', this.__replyCallback
);
},
Urth.events.on(
'shell_reply.Kernel', this.__replyCallback
);
},

detached: function() {
console.debug("Unregistering _onExecutionComplete for Execute Reply messages.");
if (this.__replyCallback){
IPython.notebook.kernel.widget_manager.notebook.events.off(
'shell_reply.Kernel', this.__replyCallback
);
}
},

/**
* A callback fired when code execution has completed for a cell.
*/
_onExecutionComplete: function() {}
}
detached: function() {
console.debug("Unregistering _onExecutionComplete for Execute Reply messages.");
if (this.__replyCallback){
Urth.events.off(
'shell_reply.Kernel', this.__replyCallback
);
}
},

/**
* A callback fired when code execution has completed for a cell.
*/
_onExecutionComplete: function() {}
};
})();
</script>
14 changes: 7 additions & 7 deletions elements/urth-core-behaviors/jupyter-kernel-observer.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
This behavior is used to implement handlers to kernel events
-->
<script>
'use strict';
(function() {
window.Urth = window.Urth || {};
'use strict';
var Urth = window.Urth = window.Urth || {};

/**
* Behavior that provides pre-attached callbacks to kernel events.
Expand All @@ -20,25 +20,25 @@
Urth.JupyterKernelObserver = {

created: function(){
if (!window.IPython) {
if (!Urth.events) {
return;
}
console.debug("Registering onKernelReady for Kernel Ready messages.")

this.__kernelReadyCallback = this.onKernelReady.bind(this);
IPython.notebook.events.on(
Urth.events.on(
'kernel_ready.Kernel', this.__kernelReadyCallback
);

if( IPython.notebook.kernel.is_connected() ){
if (Urth.kernel && Urth.kernel.is_connected()) {
this.onKernelReady();
}
},

detached: function(){
if (window.IPython && this.__kernelReadyCallback) {
if (this.__kernelReadyCallback) {
console.debug("Unregistering onKernelReady for Kernel Ready messages.")
IPython.notebook.events.off(
Urth.events.off(
'kernel_ready.Kernel', this.__kernelReadyCallback
);
}
Expand Down
4 changes: 2 additions & 2 deletions elements/urth-core-behaviors/jupyter-notebook-env.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<script>
'use strict';
(function() {
window.Urth = window.Urth || {};
var Urth = window.Urth = window.Urth || {};

/**
* Behavior that contains notebook related properties
Expand All @@ -22,7 +22,7 @@
properties: {
_baseURL: {
value: function(){
return window['IPython'] ? IPython.notebook.base_url : '/';
return Urth._baseURL || '/';
}
},

Expand Down
10 changes: 5 additions & 5 deletions elements/urth-core-behaviors/jupyter-save-behavior.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
-->

<script>
'use strict';
(function() {
'use strict';
var SAVE_EVENT = 'before_save.Notebook';
window.Urth = window.Urth || {};
var Urth = window.Urth = window.Urth || {};

/**
* Behavior that provides registration with the save event. Elements
Expand All @@ -19,15 +19,15 @@
*/
Urth.JupyterSaveBehavior = {
created: function(event, callback) {
if (window.IPython && window.IPython.notebook && window.IPython.notebook.events) {
if (Urth.events) {
this.__saveCallback = this.onSave.bind(this);
IPython.notebook.events.on(SAVE_EVENT, this.__saveCallback);
Urth.events.on(SAVE_EVENT, this.__saveCallback);
}
},

detached: function(event, callback) {
if (this.__saveCallback) {
IPython.notebook.events.off(SAVE_EVENT, this.__saveCallback);
Urth.events.off(SAVE_EVENT, this.__saveCallback);
}
},

Expand Down
19 changes: 10 additions & 9 deletions elements/urth-core-behaviors/jupyter-widget-behavior.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
-->
<link rel='import' href='error-display-behavior.html'>
<script>
'use strict';
(function() {
window.Urth = window.Urth || {};
'use strict';
var Urth = window.Urth = window.Urth || {};

/**
* Behavior that encapsulate some of the functions needed by
Expand Down Expand Up @@ -45,11 +45,12 @@

_doCreateModel: function(){
console.debug('Urth.JupyterWidgetBehavior createModel', this.kernelClass);
IPython.notebook.kernel.widget_manager.new_widget(
Urth.kernel.widget_manager.new_widget(
{
model_name: 'DeclWidgetModel',
widget_class: this.kernelClass
}
},
{}
).then(function(model) {
console.log('Model creation successful!', model);
this.__modelChangeCallback = this._onModelChange.bind(this);
Expand All @@ -75,7 +76,7 @@
this._doCreateModel();
}.bind(this);

IPython.notebook.events.one(
Urth.events.one(
'shell_reply.Kernel', this.__shellReplyCallback
);
},
Expand Down Expand Up @@ -109,7 +110,7 @@
*/
_unRegisterNotebookCallbacks: function() {
if (this.__shellReplyCallback){
IPython.notebook.events.off(
Urth.events.off(
'shell_reply.Kernel', this.__shellReplyCallback
);
}
Expand Down Expand Up @@ -181,15 +182,15 @@
},

_callbacks: function(){
// this.model is from IPython widgets widgets.js and
// this.model is from Jupyter widgets widgets.js and
// keeps track of a pending_msgs counter. Specifying
// this.model.callbacks() as the callback handler for
// send allows widgets.js to properly decrement the
// counter when responses are received.

// parentCell also has additional callbacks that will handle
// 'display_type' messages (among others)
var parentCell = this.parentCell()
var parentCell = this.parentCell();

var callbacks = (parentCell && parentCell.get_callbacks()) || {iopub:{}};
this.mixin(callbacks.iopub,this.model.callbacks().iopub);
Expand All @@ -212,7 +213,7 @@
if(this[funcName]){
this[funcName].call(this, changes[change]);
}
}.bind(this))
}.bind(this));

this.onModelChange.call(this, options);
},
Expand Down
11 changes: 5 additions & 6 deletions elements/urth-core-behaviors/test/jupyter-save-behavior.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,8 @@
// STEP 4: Define any globals needed by the test suite.

before(function () {
window.IPython = window.IPython || {};
IPython.notebook = IPython.notebook || {};
IPython.notebook.events = IPython.notebook.events || new function() {
window.Urth = window.Urth || {};
Urth.events = Urth.events || new function() {
this.__mocked = true;
this.__events = {};
this.on = function(event, cb) {
Expand All @@ -84,8 +83,8 @@
});

after(function() {
if (IPython.notebook.events.__mocked) {
delete IPython.notebook.events;
if (Urth.events.__mocked) {
delete Urth.events;
}
});

Expand All @@ -97,7 +96,7 @@

testSave.setSaveHandler(saveSpy);

IPython.notebook.events.trigger('before_save.Notebook');
Urth.events.trigger('before_save.Notebook');

expect(saveSpy).to.have.been.calledOnce;
});
Expand Down
42 changes: 26 additions & 16 deletions elements/urth-core-import/test/urth-core-import.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,39 +61,53 @@
<script>
// STEP 4: Define any globals needed by the test suite.
var server;
var serverUrthImportCalledCount = 0;

before(function() {
beforeEach(function() {
server = sinon.fakeServer.create();
server.respondImmediately = true;
});
after(function() {
afterEach(function() {
server.restore();
serverUrthImportCalledCount = 0;
});

function setupServer() {
serverUrthImportCalledCount = 0;

server.respondWith('POST', '/urth_import', function(xhr, id) {
serverUrthImportCalledCount++;
xhr.respond(200, { 'Content-Type': 'application/json' }, '{ "status": 0}');
});

server.xhr.useFilters = true;
server.xhr.addFilter(function(method, uri) {
return !uri.startsWith('/urth_import');
});
}

// STEP 5: Define suite(s) and tests.
describe('package attribute', function() {
it('should cause POST server request to install the package if href is not found', function(done) {
server.respondWith('POST', '/urth_import',
[200, { 'Content-Type': 'application/json' }, '{ "status": 0}']);

setupServer();
var link = fixture('invalidHref');
var importSpy = sinon.spy(link, 'importHref');

link.addEventListener('load', function() {
expect(importSpy).to.be.calledOnce;
expect.fail('should have resulted in `importerror` instead of successful `load`');
done();
});
link.addEventListener('importerror', function() {
expect(importSpy).to.be.calledOnce;
expect(serverUrthImportCalledCount).to.equal(1);
done();
});
});

it('should not invoke POST server request if href exists', function(done) {
setupServer();
var link = fixture('validHref');
var importSpy = sinon.spy(link, 'importHref');

link.onload = function() {
expect(importSpy).to.not.be.called;
expect(serverUrthImportCalledCount).to.equal(0);
done();
};
link.onerror = function() {
Expand All @@ -114,16 +128,12 @@
});

it('should fire if the href can not be loaded', function(done) {
server.respondWith('POST', '/urth_import',
[200, { 'Content-Type': 'application/json' }, '{ "status": 0}']);

setupServer();
var link = fixture('invalidHref');
var importSpy = sinon.spy(link, 'importHref');

link.addEventListener('importerror', function(event) {
importSpy.restore();
expect(event.detail.msg).to.not.be.null;
expect(importSpy).to.be.calledOnce;
expect(serverUrthImportCalledCount).to.equal(1);
done();
});
});
Expand Down
Loading

0 comments on commit 1085b21

Please sign in to comment.