瀏覽代碼

Wip adding more tests using dialog

Steven Silvester 9 年之前
父節點
當前提交
e91d217ee0

+ 0 - 1
src/dialog/index.ts

@@ -184,7 +184,6 @@ function showDialog(options?: IDialogOptions): Promise<IButtonItem>{
   // Focus the ok button if given.
   let index = buttons.indexOf(okButton);
   if (index !== -1) buttonNodes[index].focus();
-
   return new Promise<IButtonItem>((resolve, reject) => {
     buttonNodes.map(node => {
       node.addEventListener('click', evt => {

+ 7 - 2
src/filehandler/creator.ts

@@ -114,7 +114,13 @@ class FileCreator {
       host: this._host,
       okText: 'CREATE'
     }).then(value => {
+      if (value === null) {
+        return this.manager.delete(contents.path).then(() => void 0);
+      }
       if (value.text === 'CREATE') {
+        if (edit.value === contents.name) {
+          return contents;
+        }
         return this.manager.rename(contents.path, `${dname}/${edit.value}`);
       } else {
         return this.manager.delete(contents.path).then(() => void 0);
@@ -124,8 +130,7 @@ class FileCreator {
         return this.handleExisting(edit.value, contents);
       }
       return this.showErrorMessage(error);
-    }
-    );
+    });
   }
 
   /**

+ 2 - 1
src/filehandler/handler.ts

@@ -312,10 +312,11 @@ abstract class AbstractFileHandler<T extends Widget> implements IMessageFilter {
    * Ask the user whether to close an unsaved file.
    */
   private _maybeClose(widget: T): Promise<boolean> {
+    let host = widget.isAttached ? widget.node : document.body;
     return showDialog({
       title: 'Close without saving?',
       body: `File "${widget.title.text}" has unsaved changes, close without saving?`,
-      host: widget.node
+      host
     }).then(value => {
       if (value.text === 'OK') {
         this._close(widget);

+ 80 - 80
test/src/dialog/dialog.spec.ts

@@ -9,7 +9,7 @@ import {
 } from '../../../lib/dialog';
 
 import {
-  triggerMouseEvent, triggerKeyEvent, acceptDialog
+  triggerMouseEvent, triggerKeyEvent, acceptDialog, dismissDialog
 } from '../utils';
 
 
@@ -29,85 +29,85 @@ describe('jupyter-ui', () => {
       });
     });
 
-  //   it('should accept dialog options', (done) => {
-  //     let node = document.createElement('div');
-  //     document.body.appendChild(node);
-  //     let options = {
-  //       title: 'foo',
-  //       body: 'Hello',
-  //       host: node,
-  //       buttons: [okButton],
-  //       okText: 'Yep'
-  //     }
-  //     showDialog(options).then(result => {
-  //       expect(result).to.be(null);
-  //       done();
-  //     });
-  //     Promise.resolve().then(() => {
-  //       let target = document.body.getElementsByClassName('jp-Dialog')[0];
-  //       triggerKeyEvent(target as HTMLElement, 'keydown', { keyCode: 27 });
-  //     });
-  //   });
-
-  //   it('should accept an html body', (done) => {
-  //     let body = document.createElement('div');
-  //     let input = document.createElement('input');
-  //     let select = document.createElement('select');
-  //     body.appendChild(input);
-  //     body.appendChild(select);
-  //     showDialog({ body, okText: 'CONFIRM' }).then(result => {
-  //       expect(result.text).to.be('CONFIRM');
-  //       done();
-  //     });
-  //     acceptDialog();
-  //   });
-
-  //   it('should accept an input body', (done) => {
-  //     let body = document.createElement('input');
-  //     showDialog({ body }).then(result => {
-  //       expect(result.text).to.be('OK');
-  //       done();
-  //     });
-  //     acceptDialog();
-  //   });
-
-  //   it('should accept a select body', (done) => {
-  //     let body = document.createElement('select');
-  //     showDialog({ body }).then(result => {
-  //       expect(result.text).to.be('OK');
-  //       done();
-  //     });
-  //     acceptDialog();
-  //   });
-
-  //   it('should resolve with the clicked button result', (done) => {
-  //     let button = {
-  //       text: 'foo',
-  //       className: 'bar',
-  //       icon: 'baz'
-  //     }
-  //     showDialog({ buttons: [button] }).then(result => {
-  //       expect(result.text).to.be('foo');
-  //       done();
-  //     });
-  //     Promise.resolve().then(() => {
-  //       let node = document.body.getElementsByClassName('bar')[0];
-  //       (node as HTMLElement).click();
-  //     });
-  //   });
-
-  //   it('should ignore context menu events', (done) => {
-  //     let body = document.createElement('div');
-  //     showDialog({ body }).then(result => {
-  //       expect(result).to.be(null);
-  //       done();
-  //     });
-  //     Promise.resolve().then(() => {
-  //       let node = document.body.getElementsByClassName('jp-Dialog')[0];
-  //       triggerMouseEvent(node as HTMLElement, 'contextmenu');
-  //       triggerKeyEvent(node as HTMLElement, 'keydown', { keyCode: 27 });
-  //     });
-  //   });
+    it('should accept dialog options', (done) => {
+      let node = document.createElement('div');
+      document.body.appendChild(node);
+      let options = {
+        title: 'foo',
+        body: 'Hello',
+        host: node,
+        buttons: [okButton],
+        okText: 'Yep'
+      }
+      showDialog(options).then(result => {
+        expect(result).to.be(null);
+        done();
+      });
+      Promise.resolve().then(() => {
+        let target = document.body.getElementsByClassName('jp-Dialog')[0];
+        triggerKeyEvent(target as HTMLElement, 'keydown', { keyCode: 27 });
+      });
+    });
+
+    it('should accept an html body', (done) => {
+      let body = document.createElement('div');
+      let input = document.createElement('input');
+      let select = document.createElement('select');
+      body.appendChild(input);
+      body.appendChild(select);
+      showDialog({ body, okText: 'CONFIRM' }).then(result => {
+        expect(result.text).to.be('CONFIRM');
+        done();
+      });
+      acceptDialog();
+    });
+
+    it('should accept an input body', (done) => {
+      let body = document.createElement('input');
+      showDialog({ body }).then(result => {
+        expect(result).to.be(null);
+        done();
+      });
+      dismissDialog();
+    });
+
+    it('should accept a select body', (done) => {
+      let body = document.createElement('select');
+      showDialog({ body }).then(result => {
+        expect(result.text).to.be('OK');
+        done();
+      });
+      acceptDialog();
+    });
+
+    it('should resolve with the clicked button result', (done) => {
+      let button = {
+        text: 'foo',
+        className: 'bar',
+        icon: 'baz'
+      }
+      showDialog({ buttons: [button] }).then(result => {
+        expect(result.text).to.be('foo');
+        done();
+      });
+      Promise.resolve().then(() => {
+        let node = document.body.getElementsByClassName('bar')[0];
+        (node as HTMLElement).click();
+      });
+    });
+
+    it('should ignore context menu events', (done) => {
+      let body = document.createElement('div');
+      showDialog({ body }).then(result => {
+        expect(result).to.be(null);
+        done();
+      });
+      Promise.resolve().then(() => {
+        let node = document.body.getElementsByClassName('jp-Dialog')[0];
+        triggerMouseEvent(node as HTMLElement, 'contextmenu');
+        triggerKeyEvent(node as HTMLElement, 'keydown', { keyCode: 27 });
+      });
+    });
 
   });
 

+ 56 - 0
test/src/filehandler/creator.spec.ts

@@ -16,11 +16,19 @@ import {
   MockContentsManager
 } from '../mock';
 
+import {
+  acceptDialog, dismissDialog, waitForDialog
+} from '../utils';
+
 
 class MyFileCreator extends FileCreator {
 
   methods: string[] = [];
 
+  getFileNode(): HTMLInputElement {
+    return this.fileNode;
+  }
+
   doRename(contents: IContentsModel): Promise<IContentsModel> {
     this.methods.push('doRename');
     return super.doRename(contents);
@@ -74,6 +82,54 @@ describe('jupyter-ui', () => {
 
     });
 
+    describe('#createNew', () => {
+
+      it('should do nothing if the dialog is dismissed', (done) => {
+        let manager = new MockContentsManager();
+        let creator = new FileCreator(manager);
+        creator.createNew('foo').then(contents => {
+          expect(contents).to.be(void 0);
+          done();
+        });
+        dismissDialog();
+      });
+
+      it('should create the untitled file if dialog is accepted', (done) => {
+        let manager = new MockContentsManager();
+        let creator = new FileCreator(manager);
+        creator.createNew('foo').then(contents => {
+          expect(contents.content).to.be(manager.DEFAULT_TEXT);
+          done();
+        });
+        acceptDialog();
+      });
+
+      it('should create the untitled file if dialog is accepted', (done) => {
+        let manager = new MockContentsManager();
+        let creator = new FileCreator(manager);
+        creator.createNew('foo').then(contents => {
+          expect(contents.content).to.be(manager.DEFAULT_TEXT);
+          done();
+        });
+        acceptDialog();
+      });
+
+      it('should support an accepted rename', (done) => {
+        let manager = new MockContentsManager();
+        let creator = new MyFileCreator(manager);
+        creator.createNew('foo').then(contents => {
+          expect(contents.name).to.be('bar.txt');
+          done();
+        });
+        waitForDialog().then(() => {
+          let node = creator.getFileNode();
+          node.value = 'bar.txt';
+          acceptDialog();
+        });
+      });
+
+    });
+
     describe('#createUntitled()', () => {
 
       it('should create a new untitled file on the given path', (done) => {

+ 14 - 2
test/src/filehandler/filehandler.spec.ts

@@ -25,6 +25,10 @@ import {
   MockContentsManager
 } from '../mock';
 
+import {
+  acceptDialog
+} from '../utils';
+
 
 class FileHandler extends AbstractFileHandler<Widget> {
 
@@ -290,8 +294,16 @@ describe('jupyter-ui', () => {
         });
       });
 
-      it('should prompt the user if the file is dirty', () => {
-        // TODO
+      it('should prompt the user if the file is dirty', (done) => {
+        let manager = new MockContentsManager();
+        let handler = new FileHandler(manager);
+        handler.open('foo.txt');
+        handler.setDirty('foo.txt', true);
+        handler.close('foo.txt').then(result => {
+          expect(result).to.be(true);
+          done();
+        });
+        acceptDialog();
       });
 
     });

+ 29 - 2
test/src/utils.ts

@@ -21,10 +21,37 @@ function triggerKeyEvent(node: HTMLElement, eventType: string, options: any = {}
 }
 
 
+export
+function waitForDialog(host: HTMLElement = document.body): Promise<void> {
+  return new Promise<void>((resolve, reject) => {
+    let refresh = () => {
+      let node = host.getElementsByClassName('jp-Dialog')[0];
+      if (node) {
+        resolve(void 0);
+        return;
+      }
+      setTimeout(refresh, 100);
+    }
+    refresh();
+  });
+}
+
+
 export
 function acceptDialog(host: HTMLElement = document.body): Promise<void> {
-  return Promise.resolve().then(() => {
+  return waitForDialog().then(() => {
     let node = host.getElementsByClassName('jp-Dialog-okButton')[0];
-    (node as HTMLElement).click();
+    if (node) (node as HTMLElement).click();
+  });
+}
+
+
+export
+function dismissDialog(host: HTMLElement = document.body): Promise<void> {
+  return waitForDialog().then(() => {
+    let node = host.getElementsByClassName('jp-Dialog')[0];
+    if (node) {
+      triggerKeyEvent(node as HTMLElement, 'keydown', { keyCode: 27 });
+    }
   });
 }