mirror of
https://github.com/jupyter/notebook.git
synced 2024-12-27 04:20:22 +08:00
followed suggestion by tom, started tests
This commit is contained in:
parent
d468081fee
commit
4d45ec7c1b
@ -246,15 +246,11 @@ function(
|
||||
};
|
||||
var that = this;
|
||||
|
||||
// record change generation for isClean
|
||||
// (I don't know what this implies for the editor)
|
||||
this.generation = this.codemirror.changeGeneration();
|
||||
|
||||
var _save = function () {
|
||||
// What does this event do? Does this always need to happen,
|
||||
// even if the file can't be saved? What is dependent on it?
|
||||
that.events.trigger("file_saving.Editor");
|
||||
return that.contents.save(that.file_path, model).then(function(data) {
|
||||
// record change generation for isClean
|
||||
this.generation = this.codemirror.changeGeneration();
|
||||
that.events.trigger("file_saved.Editor", data);
|
||||
that.last_modified = new Date(data.last_modified);
|
||||
that._clean_state();
|
||||
@ -278,8 +274,8 @@ function(
|
||||
console.warn("Last saving was done on `"+that.last_modified+"`("+that._last_modified+"), "+
|
||||
"while the current file seem to have been saved on `"+data.last_modified+"`");
|
||||
if (that._changed_on_disk_dialog !== null) {
|
||||
// since the modal's event bindings are removed when destroyed,
|
||||
// we reinstate save & reload callbacks on the confirmation & reload buttons
|
||||
// since the modal's event bindings are removed when destroyed, we reinstate
|
||||
// save & reload callbacks on the confirmation & reload buttons
|
||||
that._changed_on_disk_dialog.find('.save-confirm-btn').click(_save);
|
||||
that._changed_on_disk_dialog.find('.btn-warning').click(function () {window.location.reload()});
|
||||
|
||||
|
43
notebook/tests/editor/save.js
Normal file
43
notebook/tests/editor/save.js
Normal file
@ -0,0 +1,43 @@
|
||||
//
|
||||
// Test prompt when overwriting a file that is modified on disk
|
||||
//
|
||||
|
||||
casper.editor_test(function () {
|
||||
var fname = "has#hash and space and unicø∂e.py";
|
||||
|
||||
this.append_cell("s = '??'", 'code');
|
||||
|
||||
this.thenEvaluate(function (nbname) {
|
||||
require(['base/js/events'], function (events) {
|
||||
IPython.editor.set_notebook_name(nbname);
|
||||
IPython._save_success = IPython._save_failed = false;
|
||||
events.on('file_saved.Editor', function () {
|
||||
IPython._save_success = true;
|
||||
});
|
||||
IPython.notebook.save_notebook();
|
||||
});
|
||||
}, {nbname:nbname});
|
||||
|
||||
this.waitFor(function () {
|
||||
return this.evaluate(function(){
|
||||
return IPython._save_failed || IPython._save_success;
|
||||
});
|
||||
});
|
||||
|
||||
this.thenEvaluate(function(){
|
||||
IPython._checkpoint_created = false;
|
||||
require(['base/js/events'], function (events) {
|
||||
events.on('checkpoint_created.Notebook', function (evt, data) {
|
||||
IPython._checkpoint_created = true;
|
||||
});
|
||||
});
|
||||
IPython.notebook.save_checkpoint();
|
||||
});
|
||||
|
||||
this.waitFor(function() {
|
||||
return this.evaluate(function () {
|
||||
return IPython && IPython.notebook && true;
|
||||
});
|
||||
});
|
||||
|
||||
});
|
@ -734,6 +734,103 @@ casper.dashboard_test = function (test) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Editor Tests
|
||||
*
|
||||
* The functions below are utilities for setting up an editor and tearing it down
|
||||
* after the test is over.
|
||||
*/
|
||||
caspser.open_new_file = function () {
|
||||
// load up the jupyter notebook server (it's like running `jupyter notebook` in the shell)
|
||||
var baseUrl = this.get_notebook_server();
|
||||
|
||||
// go to the base url, wait for it to load, then make a new file
|
||||
this.start(baseUrl);
|
||||
this.waitFor(this.page_loaded);
|
||||
this.waitForSelector('#new-file a');
|
||||
this.thenClick('#new-file a');
|
||||
|
||||
// when the popup loads, go into that popup and wait until the main text box is loaded
|
||||
this.withPopup(0, function () {this.waitForSelector('.CodeMirror-sizer');});
|
||||
|
||||
// now let's open the window where the file editor is displayed & load
|
||||
this.then(function () {
|
||||
this.open(this.popups[0].url);
|
||||
});
|
||||
this.waitFor(this.page_loaded);
|
||||
|
||||
// Hook the log and error methods of the console, forcing them to
|
||||
// serialize their arguments before printing. This allows the
|
||||
// Objects to cross into the phantom/slimer regime for display.
|
||||
this.thenEvaluate(function(){
|
||||
var serialize_arguments = function(f, context) {
|
||||
return function() {
|
||||
var pretty_arguments = [];
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
var value = arguments[i];
|
||||
if (value instanceof Object) {
|
||||
var name = value.name || 'Object';
|
||||
// Print a JSON string representation of the object.
|
||||
// If we don't do this, [Object object] gets printed
|
||||
// by casper, which is useless. The long regular
|
||||
// expression reduces the verbosity of the JSON.
|
||||
pretty_arguments.push(name + ' {' + JSON.stringify(value, null, ' ')
|
||||
.replace(/(\s+)?({)?(\s+)?(}(\s+)?,?)?(\s+)?(\s+)?\n/g, '\n')
|
||||
.replace(/\n(\s+)?\n/g, '\n'));
|
||||
} else {
|
||||
pretty_arguments.push(value);
|
||||
}
|
||||
}
|
||||
f.apply(context, pretty_arguments);
|
||||
};
|
||||
};
|
||||
console.log = serialize_arguments(console.log, console);
|
||||
console.error = serialize_arguments(console.error, console);
|
||||
});
|
||||
|
||||
console.log('Editor loaded.')
|
||||
|
||||
}
|
||||
|
||||
casper.editor_test = function(test) {
|
||||
// Wrap a notebook test to reduce boilerplate.
|
||||
this.open_new_file();
|
||||
|
||||
// Echo whether or not we are running this test using SlimerJS
|
||||
if (this.evaluate(function(){
|
||||
return typeof InstallTrigger !== 'undefined'; // Firefox 1.0+
|
||||
})) {
|
||||
console.log('This test is running in SlimerJS.');
|
||||
this.slimerjs = true;
|
||||
}
|
||||
|
||||
// Make sure to remove the onbeforeunload callback. This callback is
|
||||
// responsible for the "Are you sure you want to quit?" type messages.
|
||||
// PhantomJS ignores these prompts, SlimerJS does not which causes hangs.
|
||||
this.then(function(){
|
||||
this.evaluate(function(){
|
||||
window.onbeforeunload = function(){};
|
||||
});
|
||||
});
|
||||
|
||||
this.then(test);
|
||||
|
||||
// This is required to clean up the page we just finished with. If we don't call this
|
||||
// casperjs will leak file descriptors of all the open WebSockets in that page. We
|
||||
// have to set this.page=null so that next time casper.start runs, it will create a
|
||||
// new page from scratch.
|
||||
this.then(function () {
|
||||
this.page.close();
|
||||
this.page = null;
|
||||
});
|
||||
|
||||
// Run the browser automation.
|
||||
this.run(function() {
|
||||
this.test.done();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// note that this will only work for UNIQUE events -- if you want to
|
||||
// listen for the same event twice, this will not work!
|
||||
casper.event_test = function (name, events, action, timeout) {
|
||||
|
Loading…
Reference in New Issue
Block a user