1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/devtools/scratchpad/test/browser_scratchpad_confirm_close.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,228 @@ 1.4 +/* vim: set ts=2 et sw=2 tw=80: */ 1.5 +/* Any copyright is dedicated to the Public Domain. 1.6 + http://creativecommons.org/publicdomain/zero/1.0/ */ 1.7 +/* Bug 653427 */ 1.8 + 1.9 +let tempScope = {}; 1.10 +Cu.import("resource://gre/modules/NetUtil.jsm", tempScope); 1.11 +Cu.import("resource://gre/modules/FileUtils.jsm", tempScope); 1.12 +let NetUtil = tempScope.NetUtil; 1.13 +let FileUtils = tempScope.FileUtils; 1.14 + 1.15 +// only finish() when correct number of tests are done 1.16 +const expected = 9; 1.17 +var count = 0; 1.18 +function done() 1.19 +{ 1.20 + if (++count == expected) { 1.21 + cleanup(); 1.22 + finish(); 1.23 + } 1.24 +} 1.25 + 1.26 +var gFile; 1.27 + 1.28 +var oldPrompt = Services.prompt; 1.29 +var promptButton = -1; 1.30 + 1.31 +function test() 1.32 +{ 1.33 + waitForExplicitFinish(); 1.34 + 1.35 + gFile = createTempFile("fileForBug653427.tmp"); 1.36 + writeFile(gFile, "text", testUnsaved.call(this)); 1.37 + 1.38 + Services.prompt = { 1.39 + confirmEx: function() { 1.40 + return promptButton; 1.41 + } 1.42 + }; 1.43 + 1.44 + testNew(); 1.45 + testSavedFile(); 1.46 + 1.47 + gBrowser.selectedTab = gBrowser.addTab(); 1.48 + content.location = "data:text/html,<p>test scratchpad save file prompt on closing"; 1.49 +} 1.50 + 1.51 +function testNew() 1.52 +{ 1.53 + openScratchpad(function(win) { 1.54 + win.Scratchpad.close(function() { 1.55 + ok(win.closed, "new scratchpad window should close without prompting") 1.56 + done(); 1.57 + }); 1.58 + }, {noFocus: true}); 1.59 +} 1.60 + 1.61 +function testSavedFile() 1.62 +{ 1.63 + openScratchpad(function(win) { 1.64 + win.Scratchpad.filename = "test.js"; 1.65 + win.Scratchpad.editor.dirty = false; 1.66 + win.Scratchpad.close(function() { 1.67 + ok(win.closed, "scratchpad from file with no changes should close") 1.68 + done(); 1.69 + }); 1.70 + }, {noFocus: true}); 1.71 +} 1.72 + 1.73 +function testUnsaved() 1.74 +{ 1.75 + function setFilename(aScratchpad, aFile) { 1.76 + aScratchpad.setFilename(aFile); 1.77 + } 1.78 + 1.79 + testUnsavedFileCancel(setFilename); 1.80 + testUnsavedFileSave(setFilename); 1.81 + testUnsavedFileDontSave(setFilename); 1.82 + testCancelAfterLoad(); 1.83 + 1.84 + function mockSaveFile(aScratchpad) { 1.85 + let SaveFileStub = function (aCallback) { 1.86 + /* 1.87 + * An argument for aCallback must pass Components.isSuccessCode 1.88 + * 1.89 + * A version of isSuccessCode in JavaScript: 1.90 + * function isSuccessCode(returnCode) { 1.91 + * return (returnCode & 0x80000000) == 0; 1.92 + * } 1.93 + */ 1.94 + aCallback(1); 1.95 + }; 1.96 + 1.97 + aScratchpad.saveFile = SaveFileStub; 1.98 + } 1.99 + 1.100 + // Run these tests again but this time without setting a filename to 1.101 + // test that Scratchpad always asks for confirmation on dirty editor. 1.102 + testUnsavedFileCancel(mockSaveFile); 1.103 + testUnsavedFileSave(mockSaveFile); 1.104 + testUnsavedFileDontSave(); 1.105 +} 1.106 + 1.107 +function testUnsavedFileCancel(aCallback=function () {}) 1.108 +{ 1.109 + openScratchpad(function(win) { 1.110 + aCallback(win.Scratchpad, "test.js"); 1.111 + win.Scratchpad.editor.dirty = true; 1.112 + 1.113 + promptButton = win.BUTTON_POSITION_CANCEL; 1.114 + 1.115 + win.Scratchpad.close(function() { 1.116 + ok(!win.closed, "cancelling dialog shouldn't close scratchpad"); 1.117 + win.close(); 1.118 + done(); 1.119 + }); 1.120 + }, {noFocus: true}); 1.121 +} 1.122 + 1.123 +// Test a regression where our confirmation dialog wasn't appearing 1.124 +// after openFile calls. See bug 801982. 1.125 +function testCancelAfterLoad() 1.126 +{ 1.127 + openScratchpad(function(win) { 1.128 + win.Scratchpad.setRecentFile(gFile); 1.129 + win.Scratchpad.openFile(0); 1.130 + win.Scratchpad.editor.dirty = true; 1.131 + promptButton = win.BUTTON_POSITION_CANCEL; 1.132 + 1.133 + let EventStub = { 1.134 + called: false, 1.135 + preventDefault: function() { 1.136 + EventStub.called = true; 1.137 + } 1.138 + }; 1.139 + 1.140 + win.Scratchpad.onClose(EventStub, function() { 1.141 + ok(!win.closed, "cancelling dialog shouldn't close scratchpad"); 1.142 + ok(EventStub.called, "aEvent.preventDefault was called"); 1.143 + 1.144 + win.Scratchpad.editor.dirty = false; 1.145 + win.close(); 1.146 + done(); 1.147 + }); 1.148 + }, {noFocus: true}); 1.149 +} 1.150 + 1.151 +function testUnsavedFileSave(aCallback=function () {}) 1.152 +{ 1.153 + openScratchpad(function(win) { 1.154 + win.Scratchpad.importFromFile(gFile, true, function(status, content) { 1.155 + aCallback(win.Scratchpad, gFile.path); 1.156 + 1.157 + let text = "new text"; 1.158 + win.Scratchpad.setText(text); 1.159 + 1.160 + promptButton = win.BUTTON_POSITION_SAVE; 1.161 + 1.162 + win.Scratchpad.close(function() { 1.163 + ok(win.closed, 'pressing "Save" in dialog should close scratchpad'); 1.164 + readFile(gFile, function(savedContent) { 1.165 + is(savedContent, text, 'prompted "Save" worked when closing scratchpad'); 1.166 + done(); 1.167 + }); 1.168 + }); 1.169 + }); 1.170 + }, {noFocus: true}); 1.171 +} 1.172 + 1.173 +function testUnsavedFileDontSave(aCallback=function () {}) 1.174 +{ 1.175 + openScratchpad(function(win) { 1.176 + aCallback(win.Scratchpad, gFile.path); 1.177 + win.Scratchpad.editor.dirty = true; 1.178 + 1.179 + promptButton = win.BUTTON_POSITION_DONT_SAVE; 1.180 + 1.181 + win.Scratchpad.close(function() { 1.182 + ok(win.closed, 'pressing "Don\'t Save" in dialog should close scratchpad'); 1.183 + done(); 1.184 + }); 1.185 + }, {noFocus: true}); 1.186 +} 1.187 + 1.188 +function cleanup() 1.189 +{ 1.190 + Services.prompt = oldPrompt; 1.191 + gFile.remove(false); 1.192 + gFile = null; 1.193 +} 1.194 + 1.195 +function createTempFile(name) 1.196 +{ 1.197 + let file = FileUtils.getFile("TmpD", [name]); 1.198 + file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666); 1.199 + file.QueryInterface(Ci.nsILocalFile) 1.200 + return file; 1.201 +} 1.202 + 1.203 +function writeFile(file, content, callback) 1.204 +{ 1.205 + let fout = Cc["@mozilla.org/network/file-output-stream;1"]. 1.206 + createInstance(Ci.nsIFileOutputStream); 1.207 + fout.init(file.QueryInterface(Ci.nsILocalFile), 0x02 | 0x08 | 0x20, 1.208 + 0644, fout.DEFER_OPEN); 1.209 + 1.210 + let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]. 1.211 + createInstance(Ci.nsIScriptableUnicodeConverter); 1.212 + converter.charset = "UTF-8"; 1.213 + let fileContentStream = converter.convertToInputStream(content); 1.214 + 1.215 + NetUtil.asyncCopy(fileContentStream, fout, callback); 1.216 +} 1.217 + 1.218 +function readFile(file, callback) 1.219 +{ 1.220 + let channel = NetUtil.newChannel(file); 1.221 + channel.contentType = "application/javascript"; 1.222 + 1.223 + NetUtil.asyncFetch(channel, function(inputStream, status) { 1.224 + ok(Components.isSuccessCode(status), 1.225 + "file was read successfully"); 1.226 + 1.227 + let content = NetUtil.readInputStreamToString(inputStream, 1.228 + inputStream.available()); 1.229 + callback(content); 1.230 + }); 1.231 +}