Selaa lähdekoodia

Clean up and update tests

Steven Silvester 8 vuotta sitten
vanhempi
commit
9ca7d1b805

+ 3 - 3
src/notebook/output-area/widget.ts

@@ -702,12 +702,12 @@ class OutputWidget extends Widget {
    *
    * @param trusted - Whether the output is trusted.
    */
-  render(output: OutputAreaModel.Output, trusted=false): Promise<void> {
+  render(output: OutputAreaModel.Output, trusted=false): void {
     // Handle an input request.
     if (output.output_type === 'input_request') {
       let child = new InputWidget(output as OutputAreaModel.IInputRequest);
       this.setOutput(child);
-      return Promise.resolve(void 0);
+      return;
     }
 
     // Extract the data from the output and sanitize if necessary.
@@ -722,7 +722,7 @@ class OutputWidget extends Widget {
     let msg = 'Did not find renderer for output mimebundle.';
     if (!data) {
       console.log(msg);
-      return Promise.resolve(void 0);
+      return;
     }
 
     // Create the output result area.

+ 10 - 4
src/renderers/index.ts

@@ -100,7 +100,9 @@ class HTMLWidget extends Widget {
       source = options.sanitizer.sanitize(source);
     }
     appendHtml(this.node, source);
-    resolveUrls(this.node, options.resolver);
+    if (options.resolver) {
+      resolveUrls(this.node, options.resolver);
+    }
   }
 
   /**
@@ -135,11 +137,13 @@ class MarkdownWidget extends Widget {
         content = options.sanitizer.sanitize(content);
       }
       appendHtml(this.node, content);
-      resolveUrls(this.node, options.resolver);
+      if (options.resolver) {
+        resolveUrls(this.node, options.resolver);
+      }
       this.fit();
+      this._rendered = true;
       if (this.isAttached) {
         typeset(this.node);
-        this._rendered = true;
       }
     });
   }
@@ -366,7 +370,9 @@ class SVGRenderer implements RenderMime.IRenderer {
     if (!svgElement) {
       throw new Error('SVGRender: Error: Failed to create <svg> element');
     }
-    resolveUrls(w.node, options.resolver);
+    if (options.resolver) {
+      resolveUrls(w.node, options.resolver);
+    }
     w.addClass(RENDERED_CLASS);
     return w;
   }

+ 2 - 2
src/rendermime/index.ts

@@ -241,9 +241,9 @@ namespace RenderMime {
     source: string;
 
     /**
-     * The url resolver.
+     * An optional url resolver.
      */
-    resolver: IResolver;
+    resolver?: IResolver;
 
     /**
      * An optional html santizer.

+ 4 - 0
test/src/docmanager/mockcontext.ts

@@ -118,6 +118,10 @@ class MockContext<T extends IDocumentModel> implements IDocumentContext<T> {
     return Promise.resolve([] as ISession.IModel[]);
   }
 
+  resolveUrl(url: string): string {
+    return url;
+  }
+
   addSibling(widget: Widget): IDisposable {
     this.methods.push('addSibling');
     return void 0;

+ 14 - 10
test/src/markdownwidget/widget.spec.ts

@@ -19,10 +19,6 @@ import {
   MarkdownWidget, MarkdownWidgetFactory
 } from '../../../lib/markdownwidget/widget';
 
-import {
-  MarkdownRenderer
-} from '../../../lib/renderers';
-
 import {
   DocumentModel
 } from '../../../lib/docregistry';
@@ -31,6 +27,10 @@ import {
   MockContext
 } from '../docmanager/mockcontext';
 
+import {
+  defaultRenderMime
+} from '../rendermime/rendermime.spec';
+
 
 class LogWidget extends MarkdownWidget {
   methods: string[] = [];
@@ -47,15 +47,19 @@ class LogWidget extends MarkdownWidget {
 
 }
 
+
+const RENDERMIME = defaultRenderMime();
+
+
 describe('markdownwidget/widget', () => {
 
   describe('MarkdownWidgetFactory', () => {
 
     describe('#createNew()', () => {
-    
+
       it('should require a context parameter', () => {
         let context = new MockContext(new DocumentModel());
-        let widgetFactory = new MarkdownWidgetFactory();
+        let widgetFactory = new MarkdownWidgetFactory(RENDERMIME);
         expect(widgetFactory.createNew(context)).to.be.a(MarkdownWidget);
       });
 
@@ -69,7 +73,7 @@ describe('markdownwidget/widget', () => {
 
       it('should require a context parameter', () => {
         let context = new MockContext(new DocumentModel());
-        let widget = new MarkdownWidget(context);
+        let widget = new MarkdownWidget(context, RENDERMIME);
         expect(widget).to.be.a(MarkdownWidget);
       });
 
@@ -79,7 +83,7 @@ describe('markdownwidget/widget', () => {
 
       it('should update the widget', () => {
         let context = new MockContext(new DocumentModel());
-        let widget = new LogWidget(context);
+        let widget = new LogWidget(context, RENDERMIME);
         expect(widget.methods).to.not.contain('onAfterAttach');
         widget.attach(document.body);
         expect(widget.methods).to.contain('onAfterAttach');
@@ -92,7 +96,7 @@ describe('markdownwidget/widget', () => {
 
       it('should update rendered markdown', () => {
         let context = new MockContext(new DocumentModel());
-        let widget = new LogWidget(context);
+        let widget = new LogWidget(context, RENDERMIME);
         expect(widget.methods).to.not.contain('onUpdateRequest');
         context.model.contentChanged.emit(void 0);
         sendMessage(widget, Widget.MsgUpdateRequest);
@@ -102,7 +106,7 @@ describe('markdownwidget/widget', () => {
 
       it('should replace children on subsequent updates', () => {
         let context = new MockContext(new DocumentModel());
-        let widget = new LogWidget(context);
+        let widget = new LogWidget(context, RENDERMIME);
         context.model.contentChanged.emit(void 0);
         sendMessage(widget, Widget.MsgUpdateRequest);
 

+ 1 - 1
test/src/notebook/cells/widget.spec.ts

@@ -133,7 +133,7 @@ class LogRenderer extends CodeCellWidget.Renderer {
     return super.createInputArea(editor);
   }
 
-  createOutputArea(rendermime: RenderMime<Widget>): OutputAreaWidget {
+  createOutputArea(rendermime: RenderMime): OutputAreaWidget {
     this.methods.push('createOutputArea');
     return super.createOutputArea(rendermime);
   }

+ 6 - 7
test/src/notebook/output-area/widget.spec.ts

@@ -416,14 +416,13 @@ describe('notebook/output-area/widget', () => {
 
     describe('#clear()', () => {
 
-      it('should clear the current output', (done) => {
+      it('should clear the current output', () => {
         let widget = new OutputWidget({ rendermime });
-        widget.render(DEFAULT_OUTPUTS[0], true).then(() => {
-          let output = widget.output;
-          widget.clear();
-          expect(widget.output).to.not.be(output);
-          expect(widget.output).to.be.a(Widget);
-        }).then(done, done);
+        widget.render(DEFAULT_OUTPUTS[0], true);
+        let output = widget.output;
+        widget.clear();
+        expect(widget.output).to.not.be(output);
+        expect(widget.output).to.be.a(Widget);
       });
 
     });

+ 87 - 129
test/src/renderers/renderers.spec.ts

@@ -8,6 +8,13 @@ import {
   SVGRenderer, MarkdownRenderer, TextRenderer, HTMLRenderer, ImageRenderer
 } from '../../../lib/renderers';
 
+import {
+  defaultSanitizer
+} from '../../../lib/sanitizer';
+
+
+const EXPECTED_MD = `<h1>Title first level</h1>\n<h2>Title second Level</h2>\n<h3>Title third level</h3>\n<h4>h4</h4>\n<h5>h5</h5>\n<h6>h6</h6>\n<h1>h1</h1>\n<h2>h2</h2>\n<h3>h3</h3>\n<h4>h4</h4>\n<h5>h6</h5>\n<p>This is just a sample paragraph<br>You can look at different level of nested unorderd list ljbakjn arsvlasc asc asc awsc asc ascd ascd ascd asdc asc</p>\n<ul>\n<li>level 1<ul>\n<li>level 2</li>\n<li>level 2</li>\n<li>level 2<ul>\n<li>level 3</li>\n<li>level 3<ul>\n<li>level 4<ul>\n<li>level 5<ul>\n<li>level 6</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n<li>level 2</li>\n</ul>\n</li>\n<li>level 1</li>\n<li>level 1</li>\n<li>level 1<br>Ordered list</li>\n<li>level 1<ol>\n<li>level 1</li>\n<li>level 1<ol>\n<li>level 1</li>\n<li>level 1</li>\n<li>level 1<ol>\n<li>level 1</li>\n<li>level 1<ol>\n<li>level 1</li>\n<li>level 1</li>\n<li>level 1</li>\n</ol>\n</li>\n</ol>\n</li>\n</ol>\n</li>\n</ol>\n</li>\n<li>level 1</li>\n<li>level 1<br>some Horizontal line</li>\n</ul>\n<hr>\n<h2>and another one</h2>\n<p>Colons can be used to align columns.</p>\n<table>\n<thead>\n<tr>\n<th>Tables</th>\n<th>Are</th>\n<th>Cool</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>col 3 is</td>\n<td>right-aligned</td>\n<td>1600</td>\n</tr>\n<tr>\n<td>col 2 is</td>\n<td>centered</td>\n<td>12</td>\n</tr>\n<tr>\n<td>zebra stripes</td>\n<td>are neat</td>\n<td>1</td>\n</tr>\n</tbody>\n</table>\n<p>There must be at least 3 dashes separating each header cell.<br>The outer pipes (|) are optional, and you don\'t need to make the<br>raw Markdown line up prettily. You can also use inline Markdown.</p>\n`;
+
 
 describe('renderers', () => {
 
@@ -43,37 +50,30 @@ describe('renderers', () => {
 
     });
 
-    describe('#transform()', () => {
+    describe('#render()', () => {
 
       it('should output the correct HTML', () => {
         let t = new TextRenderer();
-        let text = t.transform('text/plain', 'x = 2 ** a');
-        expect(text).to.be('<pre>x = 2 ** a</pre>');
+        let widget = t.render({ mimetype: 'text/plain', source: 'x = 2 ** a' });
+        expect(widget.node.innerHTML).to.be('<pre>x = 2 ** a</pre>');
       });
 
       it('should output the correct HTML with ansi colors', () => {
         let t = new TextRenderer();
-        let text = 'There is no text but \x1b[01;41;32mtext\x1b[00m.\nWoo.';
-        text = t.transform('application/vnd.jupyter.console-text', text);
-        expect(text).to.be('<pre>There is no text but <span style="color:rgb(0, 255, 0);background-color:rgb(187, 0, 0)">text</span>.\nWoo.</pre>');
+        let source = 'There is no text but \x1b[01;41;32mtext\x1b[00m.\nWoo.';
+        let widget = t.render({
+          mimetype: 'application/vnd.jupyter.console-text', source
+        });
+        expect(widget.node.innerHTML).to.be('<pre>There is no text but <span style="color:rgb(0, 255, 0);background-color:rgb(187, 0, 0)">text</span>.\nWoo.</pre>');
       });
 
       it('should escape inline html', () => {
         let t = new TextRenderer();
-        let text = 'There is no text <script>window.x=1</script> but \x1b[01;41;32mtext\x1b[00m.\nWoo.';
-        text = t.transform('application/vnd.jupyter.console-text', text);
-        expect(text).to.be('<pre>There is no text &lt;script&gt;window.x=1&lt;/script&gt; but <span style="color:rgb(0, 255, 0);background-color:rgb(187, 0, 0)">text</span>.\nWoo.</pre>');
-      });
-
-    });
-
-    describe('#render()', () => {
-
-      it('should set the inner html of the widget', () => {
-        let t = new TextRenderer();
-        let html = '<pre>Hello</pre>';
-        let widget = t.render('text/plain', html);
-        expect(widget.node.innerHTML).to.be(html);
+        let source = 'There is no text <script>window.x=1</script> but \x1b[01;41;32mtext\x1b[00m.\nWoo.';
+        let widget = t.render({
+          mimetype: 'application/vnd.jupyter.console-text', source
+        });
+        expect(widget.node.innerHTML).to.be('<pre>There is no text &lt;script&gt;window.x=1&lt;/script&gt; but <span style="color:rgb(0, 255, 0);background-color:rgb(187, 0, 0)">text</span>.\nWoo.</pre>');
       });
 
     });
@@ -109,24 +109,13 @@ describe('renderers', () => {
 
     });
 
-    describe('#transform()', () => {
-
-      it('should be a no-op', () => {
-        let mathJaxScript = '<script type="math/tex">\sum\limits_{i=0}^{\infty} \frac{1}{n^2}</script>';
-        let t = new LatexRenderer();
-        let text = t.transform('text/latex', mathJaxScript);
-        expect(text).to.be(mathJaxScript);
-      });
-
-    });
-
     describe('#render()', () => {
 
       it('should set the textContent of the widget', () => {
-        let mathJaxScript = '\sum\limits_{i=0}^{\infty} \frac{1}{n^2}';
+        let source = '\sum\limits_{i=0}^{\infty} \frac{1}{n^2}';
         let t = new LatexRenderer();
-        let widget = t.render('text/latex', mathJaxScript);
-        expect(widget.node.textContent).to.be(mathJaxScript);
+        let widget = t.render({ mimetype: 'text/latex', source });
+        expect(widget.node.textContent).to.be(source);
       });
 
     });
@@ -162,23 +151,12 @@ describe('renderers', () => {
 
     });
 
-    describe('#transform()', () => {
-
-      it('should be a no-op', () => {
-        let base64PDF = "I don't have a b64'd PDF";
-        let t = new PDFRenderer();
-        let text = t.transform('application/pdf', base64PDF);
-        expect(text).to.be(base64PDF);
-      });
-
-    });
-
     describe('#render()', () => {
 
       it('should render the correct HTML', () => {
-        let base64PDF = "I don't have a b64'd PDF";
+        let source = "I don't have a b64'd PDF";
         let t = new PDFRenderer();
-        let w = t.render('application/pdf', base64PDF);
+        let w = t.render({ mimetype: 'application/pdf', source });
         expect(w.node.innerHTML.indexOf('data:application/pdf')).to.not.be(-1);
       });
 
@@ -216,24 +194,15 @@ describe('renderers', () => {
 
     });
 
-    describe('#transform()', () => {
-
-      it('should be a no-op', () => {
-        let t = new PDFRenderer();
-        let text = t.transform('text/javascript', 'window.x = 1');
-        expect(text).to.be('window.x = 1');
-      });
-
-    });
-
     describe('#render()', () => {
 
       it('should create a script tag', () => {
         let t = new JavascriptRenderer();
-        let w = t.render('text/javascript', 'window.x = 1');
+        let source = 'window.x = 1';
+        let w = t.render({ mimetype: 'text/javascript', source });
         let el = w.node.firstChild as HTMLElement;
         expect(el.localName).to.be('script');
-        expect(el.textContent).to.be('window.x = 1');
+        expect(el.textContent).to.be(source);
 
         // Ensure script has not been run yet
         expect((window as any).x).to.be(void 0);
@@ -277,36 +246,25 @@ describe('renderers', () => {
 
     });
 
-    describe('#transform()', () => {
-
-      it('should be a no-op', () => {
-        const svg = `
-            <?xml version="1.0" standalone="no"?>
-            <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
-            SYSTEM "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-            <svg></svg>`;
-        let t = new SVGRenderer();
-        let text = t.transform('image/svg+xml', svg);
-        expect(text).to.be(svg);
-      });
-
-    });
-
     describe('#render()', () => {
 
       it('should create an svg tag', () => {
-        const svg = `
-            <?xml version="1.0" standalone="no"?>
-            <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
-            SYSTEM "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-            <svg></svg>
-        `;
+        const source = '<svg></svg>';
         let t = new SVGRenderer();
-        let w = t.render('image/svg+xml', svg);
+        let w = t.render({ mimetype: 'image/svg+xml', source });
         let svgEl = w.node.getElementsByTagName('svg')[0];
         expect(svgEl).to.be.ok();
       });
 
+      it('should sanitize when a sanitizer is given', () => {
+        const source = '<svg><script>window.x = 1</script></svg>';
+        let t = new SVGRenderer();
+        let w = t.render({
+          mimetype: 'image/svg+xml', source, sanitizer: defaultSanitizer
+        });
+        expect(w.node.innerHTML).to.be('<svg></svg>');
+      });
+
     });
 
   });
@@ -340,25 +298,38 @@ describe('renderers', () => {
 
     });
 
-    describe('#transform()', () => {
-
-      it('should create nice markup', (done) => {
-        let md = require('../../../examples/filebrowser/sample.md');
-        let t = new MarkdownRenderer();
-        t.transform('text/markdown', md as string).then(text => {
-          expect(text).to.be(`<h1 id="title-first-level">Title first level</h1>\n<h2 id="title-second-level">Title second Level</h2>\n<h3 id="title-third-level">Title third level</h3>\n<h4 id="h4">h4</h4>\n<h5 id="h5">h5</h5>\n<h6 id="h6">h6</h6>\n<h1 id="h1">h1</h1>\n<h2 id="h2">h2</h2>\n<h3 id="h3">h3</h3>\n<h4 id="h4">h4</h4>\n<h5 id="h6">h6</h5>\n<p>This is just a sample paragraph<br>You can look at different level of nested unorderd list ljbakjn arsvlasc asc asc awsc asc ascd ascd ascd asdc asc</p>\n<ul>\n<li>level 1<ul>\n<li>level 2</li>\n<li>level 2</li>\n<li>level 2<ul>\n<li>level 3</li>\n<li>level 3<ul>\n<li>level 4<ul>\n<li>level 5<ul>\n<li>level 6</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n<li>level 2</li>\n</ul>\n</li>\n<li>level 1</li>\n<li>level 1</li>\n<li>level 1<br>Ordered list</li>\n<li>level 1<ol>\n<li>level 1</li>\n<li>level 1<ol>\n<li>level 1</li>\n<li>level 1</li>\n<li>level 1<ol>\n<li>level 1</li>\n<li>level 1<ol>\n<li>level 1</li>\n<li>level 1</li>\n<li>level 1</li>\n</ol>\n</li>\n</ol>\n</li>\n</ol>\n</li>\n</ol>\n</li>\n<li>level 1</li>\n<li>level 1<br>some Horizontal line</li>\n</ul>\n<hr>\n<h2 id="and-another-one">and another one</h2>\n<p>Colons can be used to align columns.</p>\n<table>\n<thead>\n<tr>\n<th>Tables</th>\n<th style="text-align:center">Are</th>\n<th style="text-align:right">Cool</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>col 3 is</td>\n<td style="text-align:center">right-aligned</td>\n<td style="text-align:right">1600</td>\n</tr>\n<tr>\n<td>col 2 is</td>\n<td style="text-align:center">centered</td>\n<td style="text-align:right">12</td>\n</tr>\n<tr>\n<td>zebra stripes</td>\n<td style="text-align:center">are neat</td>\n<td style="text-align:right">1</td>\n</tr>\n</tbody>\n</table>\n<p>There must be at least 3 dashes separating each header cell.<br>The outer pipes (|) are optional, and you don&#39;t need to make the<br>raw Markdown line up prettily. You can also use inline Markdown.</p>\n`);
-        }).then(done, done);
-      });
-
-    });
-
     describe('#render()', () => {
 
-      it('should set the inner html', () => {
+      it('should set the inner html', (done) => {
         let t = new MarkdownRenderer();
-        let html = '<p>hello</p>';
-        let w = t.render('text/markdown', html);
-        expect(w.node.innerHTML).to.be(html);
+        let source = '<p>hello</p>';
+        let widget = t.render({ mimetype: 'text/markdown', source });
+        let loop = () => {
+          if ((widget as any)._rendered) {
+            expect(widget.node.innerHTML).to.be(source);
+            done();
+            return;
+          }
+          setTimeout(loop, 100);
+        };
+        setTimeout(loop, 100);
+      });
+
+      it('should sanitize if a sanitizer is given', (done) => {
+        let source = require('../../../examples/filebrowser/sample.md') as string;
+        let r = new MarkdownRenderer();
+        let widget = r.render({
+          mimetype: 'text/markdown', source, sanitizer: defaultSanitizer
+        });
+        let loop = () => {
+          if ((widget as any)._rendered) {
+            expect(widget.node.innerHTML).to.be(EXPECTED_MD);
+            done();
+            return;
+          }
+          setTimeout(loop, 100);
+        };
+        setTimeout(loop, 100);
       });
 
     });
@@ -394,36 +365,34 @@ describe('renderers', () => {
 
     });
 
-    describe('#transform()', () => {
-
-      it('should be a no-op', () => {
-        let t = new HTMLRenderer();
-        const htmlText = '<h1>This is great</h1>';
-        let text = t.transform('text/html', htmlText);
-        expect(text).to.be(htmlText);
-      });
-
-    });
-
     describe('#render()', () => {
 
       it('should set the inner HTML', () => {
         let t = new HTMLRenderer();
-        const htmlText = '<h1>This is great</h1>';
-        let w = t.render('text/html', htmlText);
+        const source = '<h1>This is great</h1>';
+        let w = t.render({ mimetype: 'text/html', source });
         expect(w.node.innerHTML).to.be('<h1>This is great</h1>');
       });
 
       it('should execute a script tag when attached', () => {
-        const htmlText = '<script>window.y=3;</script>';
+        const source = '<script>window.y=3;</script>';
         let t = new HTMLRenderer();
-        let w = t.render('text/html', htmlText);
+        let w = t.render({ mimetype: 'text/html', source });
         expect((window as any).y).to.be(void 0);
         w.attach(document.body);
         expect((window as any).y).to.be(3);
         w.dispose();
       });
 
+      it('should sanitize when a sanitizer is given', () => {
+        const source = '<pre><script>window.y=3;</script></pre>';
+        let t = new HTMLRenderer();
+        let w = t.render({
+          mimetype: 'text/html', source, sanitizer: defaultSanitizer
+        });
+        expect(w.node.innerHTML).to.be('<pre></pre>');
+      });
+
     });
 
   });
@@ -457,32 +426,21 @@ describe('renderers', () => {
 
     });
 
-    describe('#transform()', () => {
-
-      it('should be a no-op', () => {
-        let t = new ImageRenderer();
-        const imageData = 'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
-        let text = t.transform('image/png', imageData);
-        expect(text).to.be(imageData);
-      });
-
-    });
-
     describe('#render()', () => {
 
       it('should create an <img> with the right mimetype', () => {
-        const imageData = 'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
+        let source = 'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
         let t = new ImageRenderer();
-        let w = t.render('image/png', imageData);
+        let w = t.render({ mimetype: 'image/png', source });
         let el = w.node.firstChild as HTMLImageElement;
-        expect(el.src).to.be('data:image/png;base64,' + imageData);
+        expect(el.src).to.be('data:image/png;base64,' + source);
         expect(el.localName).to.be('img');
         expect(el.innerHTML).to.be('');
 
-        const imageData2 = 'R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=';
-        w = t.render('image/gif', imageData2);
+        source = 'R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=';
+        w = t.render({ mimetype: 'image/gif', source });
         el = w.node.firstChild as HTMLImageElement;
-        expect(el.src).to.be('data:image/gif;base64,' + imageData2);
+        expect(el.src).to.be('data:image/gif;base64,' + source);
         expect(el.localName).to.be('img');
         expect(el.innerHTML).to.be('');
       });

+ 34 - 44
test/src/rendermime/rendermime.spec.ts

@@ -16,6 +16,10 @@ import {
   RenderMime
 } from '../../../lib/rendermime';
 
+import {
+  defaultSanitizer
+} from '../../../lib/sanitizer';
+
 
 const TRANSFORMERS = [
   new JavascriptRenderer(),
@@ -30,8 +34,8 @@ const TRANSFORMERS = [
 
 
 export
-function defaultRenderMime(): RenderMime<Widget> {
-  let renderers: RenderMime.MimeMap<RenderMime.IRenderer<Widget>> = {};
+function defaultRenderMime(): RenderMime {
+  let renderers: RenderMime.MimeMap<RenderMime.IRenderer> = {};
   let order: string[] = [];
   for (let t of TRANSFORMERS) {
     for (let m of t.mimetypes) {
@@ -39,11 +43,12 @@ function defaultRenderMime(): RenderMime<Widget> {
       order.push(m);
     }
   }
-  return new RenderMime<Widget>({ renderers, order });
+  let sanitizer = defaultSanitizer;
+  return new RenderMime({ renderers, order, sanitizer });
 }
 
 
-describe('jupyter-ui', () => {
+describe('rendermime/index', () => {
 
   describe('RenderMime', () => {
 
@@ -58,84 +63,69 @@ describe('jupyter-ui', () => {
 
     describe('#render()', () => {
 
-      it('should render a mimebundle', (done) => {
+      it('should render a mimebundle', () => {
         let r = defaultRenderMime();
-        r.render({ 'text/plain': 'foo' }).then(w => {
-          expect(w instanceof Widget).to.be(true);
-        }).then(done, done);
+        let w = r.render({ 'text/plain': 'foo' });
+        expect(w instanceof Widget).to.be(true);
       });
 
-      it('should return `undefined` for an unregistered mime type', (done) => {
+      it('should return `undefined` for an unregistered mime type', () => {
         let r = defaultRenderMime();
-        r.render({ 'text/fizz': 'buzz' }).then(value => {
-          expect(value).to.be(void 0);
-        }).then(done, done);
+        let value = r.render({ 'text/fizz': 'buzz' });
+        expect(value).to.be(void 0);
       });
 
-      it('should render with the mimetype of highest precidence', (done) => {
+      it('should render with the mimetype of highest precidence', () => {
         let bundle: RenderMime.MimeMap<string> = {
           'text/plain': 'foo',
           'text/html': '<h1>foo</h1>'
         };
         let r = defaultRenderMime();
-        r.render(bundle, true).then(w => {
-          let el = w.node.firstChild as HTMLElement;
-          expect(el.localName).to.be('h1');
-        }).then(done, done);
+        let w = r.render(bundle, true);
+        let el = w.node.firstChild as HTMLElement;
+        expect(el.localName).to.be('h1');
       });
 
-      it('should render the mimetype that is safe', (done) => {
+      it('should render the mimetype that is safe', () => {
         let bundle: RenderMime.MimeMap<string> = {
           'text/plain': 'foo',
           'text/javascript': 'window.x = 1',
           'image/png': 'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
         };
         let r = defaultRenderMime();
-        r.render(bundle, false).then(w => {
-          let el = w.node.firstChild as HTMLElement;
-          expect(el.localName).to.be('img');
-        }).then(done, done);
+        let w = r.render(bundle, false);
+        let el = w.node.firstChild as HTMLElement;
+        expect(el.localName).to.be('img');
       });
 
-      it('should render the mimetype that is sanitizable', (done) => {
+      it('should render the mimetype that is sanitizable', () => {
         let bundle: RenderMime.MimeMap<string> = {
           'text/plain': 'foo',
           'text/html': '<h1>foo</h1>'
         };
         let r = defaultRenderMime();
-        r.render(bundle, false).then(w => {
-          let el = w.node.firstChild as HTMLElement;
-          expect(el.localName).to.be('h1');
-        }).then(done, done);
-      });
-
-      it('should sanitize markdown', (done) => {
-        let md = require('../../../examples/filebrowser/sample.md');
-        let r = defaultRenderMime();
-        r.render({ 'text/markdown': md as string }).then(widget => {
-          expect(widget.node.innerHTML).to.be(`<h1>Title first level</h1>\n<h2>Title second Level</h2>\n<h3>Title third level</h3>\n<h4>h4</h4>\n<h5>h5</h5>\n<h6>h6</h6>\n<h1>h1</h1>\n<h2>h2</h2>\n<h3>h3</h3>\n<h4>h4</h4>\n<h5>h6</h5>\n<p>This is just a sample paragraph<br>You can look at different level of nested unorderd list ljbakjn arsvlasc asc asc awsc asc ascd ascd ascd asdc asc</p>\n<ul>\n<li>level 1<ul>\n<li>level 2</li>\n<li>level 2</li>\n<li>level 2<ul>\n<li>level 3</li>\n<li>level 3<ul>\n<li>level 4<ul>\n<li>level 5<ul>\n<li>level 6</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n<li>level 2</li>\n</ul>\n</li>\n<li>level 1</li>\n<li>level 1</li>\n<li>level 1<br>Ordered list</li>\n<li>level 1<ol>\n<li>level 1</li>\n<li>level 1<ol>\n<li>level 1</li>\n<li>level 1</li>\n<li>level 1<ol>\n<li>level 1</li>\n<li>level 1<ol>\n<li>level 1</li>\n<li>level 1</li>\n<li>level 1</li>\n</ol>\n</li>\n</ol>\n</li>\n</ol>\n</li>\n</ol>\n</li>\n<li>level 1</li>\n<li>level 1<br>some Horizontal line</li>\n</ul>\n<hr>\n<h2>and another one</h2>\n<p>Colons can be used to align columns.</p>\n<table>\n<thead>\n<tr>\n<th>Tables</th>\n<th>Are</th>\n<th>Cool</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>col 3 is</td>\n<td>right-aligned</td>\n<td>1600</td>\n</tr>\n<tr>\n<td>col 2 is</td>\n<td>centered</td>\n<td>12</td>\n</tr>\n<tr>\n<td>zebra stripes</td>\n<td>are neat</td>\n<td>1</td>\n</tr>\n</tbody>\n</table>\n<p>There must be at least 3 dashes separating each header cell.<br>The outer pipes (|) are optional, and you don\'t need to make the<br>raw Markdown line up prettily. You can also use inline Markdown.</p>\n`);
-        }).then(done, done);
+        let w = r.render(bundle, false);
+        let el = w.node.firstChild as HTMLElement;
+        expect(el.localName).to.be('h1');
       });
 
-      it('should sanitize html', (done) => {
+      it('should sanitize html', () => {
         let bundle: RenderMime.MimeMap<string> = {
           'text/html': '<h1>foo <script>window.x=1></scrip></h1>'
         };
         let r = defaultRenderMime();
-        r.render(bundle).then(widget => {
-          expect(widget.node.innerHTML).to.be('<h1>foo </h1>');
-        }).then(done, done);
+        let widget = r.render(bundle);
+        expect(widget.node.innerHTML).to.be('<h1>foo </h1>');
       });
 
-      it('should sanitize svg', (done) => {
+      it('should sanitize svg', () => {
         let bundle: RenderMime.MimeMap<string> = {
           'image/svg+xml': '<svg><script>windox.x=1</script></svg>'
         };
         let r = defaultRenderMime();
-        r.render(bundle).then(widget => {
-          expect(widget.node.innerHTML.indexOf('svg')).to.not.be(-1);
-          expect(widget.node.innerHTML.indexOf('script')).to.be(-1);
-        }).then(done, done);
+        let widget = r.render(bundle);
+        expect(widget.node.innerHTML.indexOf('svg')).to.not.be(-1);
+        expect(widget.node.innerHTML.indexOf('script')).to.be(-1);
       });
 
     });