Skip to content

Commit 4d45ec7

Browse files
committed
followed suggestion by tom, started tests
1 parent d468081 commit 4d45ec7

File tree

3 files changed

+144
-8
lines changed

3 files changed

+144
-8
lines changed

notebook/static/edit/js/editor.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -246,15 +246,11 @@ function(
246246
};
247247
var that = this;
248248

249-
// record change generation for isClean
250-
// (I don't know what this implies for the editor)
251-
this.generation = this.codemirror.changeGeneration();
252-
253249
var _save = function () {
254-
// What does this event do? Does this always need to happen,
255-
// even if the file can't be saved? What is dependent on it?
256250
that.events.trigger("file_saving.Editor");
257251
return that.contents.save(that.file_path, model).then(function(data) {
252+
// record change generation for isClean
253+
this.generation = this.codemirror.changeGeneration();
258254
that.events.trigger("file_saved.Editor", data);
259255
that.last_modified = new Date(data.last_modified);
260256
that._clean_state();
@@ -278,8 +274,8 @@ function(
278274
console.warn("Last saving was done on `"+that.last_modified+"`("+that._last_modified+"), "+
279275
"while the current file seem to have been saved on `"+data.last_modified+"`");
280276
if (that._changed_on_disk_dialog !== null) {
281-
// since the modal's event bindings are removed when destroyed,
282-
// we reinstate save & reload callbacks on the confirmation & reload buttons
277+
// since the modal's event bindings are removed when destroyed, we reinstate
278+
// save & reload callbacks on the confirmation & reload buttons
283279
that._changed_on_disk_dialog.find('.save-confirm-btn').click(_save);
284280
that._changed_on_disk_dialog.find('.btn-warning').click(function () {window.location.reload()});
285281

notebook/tests/editor/save.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//
2+
// Test prompt when overwriting a file that is modified on disk
3+
//
4+
5+
casper.editor_test(function () {
6+
var fname = "has#hash and space and unicø∂e.py";
7+
8+
this.append_cell("s = '??'", 'code');
9+
10+
this.thenEvaluate(function (nbname) {
11+
require(['base/js/events'], function (events) {
12+
IPython.editor.set_notebook_name(nbname);
13+
IPython._save_success = IPython._save_failed = false;
14+
events.on('file_saved.Editor', function () {
15+
IPython._save_success = true;
16+
});
17+
IPython.notebook.save_notebook();
18+
});
19+
}, {nbname:nbname});
20+
21+
this.waitFor(function () {
22+
return this.evaluate(function(){
23+
return IPython._save_failed || IPython._save_success;
24+
});
25+
});
26+
27+
this.thenEvaluate(function(){
28+
IPython._checkpoint_created = false;
29+
require(['base/js/events'], function (events) {
30+
events.on('checkpoint_created.Notebook', function (evt, data) {
31+
IPython._checkpoint_created = true;
32+
});
33+
});
34+
IPython.notebook.save_checkpoint();
35+
});
36+
37+
this.waitFor(function() {
38+
return this.evaluate(function () {
39+
return IPython && IPython.notebook && true;
40+
});
41+
});
42+
43+
});

notebook/tests/util.js

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,103 @@ casper.dashboard_test = function (test) {
734734
});
735735
};
736736

737+
/**
738+
* Editor Tests
739+
*
740+
* The functions below are utilities for setting up an editor and tearing it down
741+
* after the test is over.
742+
*/
743+
caspser.open_new_file = function () {
744+
// load up the jupyter notebook server (it's like running `jupyter notebook` in the shell)
745+
var baseUrl = this.get_notebook_server();
746+
747+
// go to the base url, wait for it to load, then make a new file
748+
this.start(baseUrl);
749+
this.waitFor(this.page_loaded);
750+
this.waitForSelector('#new-file a');
751+
this.thenClick('#new-file a');
752+
753+
// when the popup loads, go into that popup and wait until the main text box is loaded
754+
this.withPopup(0, function () {this.waitForSelector('.CodeMirror-sizer');});
755+
756+
// now let's open the window where the file editor is displayed & load
757+
this.then(function () {
758+
this.open(this.popups[0].url);
759+
});
760+
this.waitFor(this.page_loaded);
761+
762+
// Hook the log and error methods of the console, forcing them to
763+
// serialize their arguments before printing. This allows the
764+
// Objects to cross into the phantom/slimer regime for display.
765+
this.thenEvaluate(function(){
766+
var serialize_arguments = function(f, context) {
767+
return function() {
768+
var pretty_arguments = [];
769+
for (var i = 0; i < arguments.length; i++) {
770+
var value = arguments[i];
771+
if (value instanceof Object) {
772+
var name = value.name || 'Object';
773+
// Print a JSON string representation of the object.
774+
// If we don't do this, [Object object] gets printed
775+
// by casper, which is useless. The long regular
776+
// expression reduces the verbosity of the JSON.
777+
pretty_arguments.push(name + ' {' + JSON.stringify(value, null, ' ')
778+
.replace(/(\s+)?({)?(\s+)?(}(\s+)?,?)?(\s+)?(\s+)?\n/g, '\n')
779+
.replace(/\n(\s+)?\n/g, '\n'));
780+
} else {
781+
pretty_arguments.push(value);
782+
}
783+
}
784+
f.apply(context, pretty_arguments);
785+
};
786+
};
787+
console.log = serialize_arguments(console.log, console);
788+
console.error = serialize_arguments(console.error, console);
789+
});
790+
791+
console.log('Editor loaded.')
792+
793+
}
794+
795+
casper.editor_test = function(test) {
796+
// Wrap a notebook test to reduce boilerplate.
797+
this.open_new_file();
798+
799+
// Echo whether or not we are running this test using SlimerJS
800+
if (this.evaluate(function(){
801+
return typeof InstallTrigger !== 'undefined'; // Firefox 1.0+
802+
})) {
803+
console.log('This test is running in SlimerJS.');
804+
this.slimerjs = true;
805+
}
806+
807+
// Make sure to remove the onbeforeunload callback. This callback is
808+
// responsible for the "Are you sure you want to quit?" type messages.
809+
// PhantomJS ignores these prompts, SlimerJS does not which causes hangs.
810+
this.then(function(){
811+
this.evaluate(function(){
812+
window.onbeforeunload = function(){};
813+
});
814+
});
815+
816+
this.then(test);
817+
818+
// This is required to clean up the page we just finished with. If we don't call this
819+
// casperjs will leak file descriptors of all the open WebSockets in that page. We
820+
// have to set this.page=null so that next time casper.start runs, it will create a
821+
// new page from scratch.
822+
this.then(function () {
823+
this.page.close();
824+
this.page = null;
825+
});
826+
827+
// Run the browser automation.
828+
this.run(function() {
829+
this.test.done();
830+
});
831+
};
832+
833+
737834
// note that this will only work for UNIQUE events -- if you want to
738835
// listen for the same event twice, this will not work!
739836
casper.event_test = function (name, events, action, timeout) {

0 commit comments

Comments
 (0)