123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- // Copyright (c) Jupyter Development Team.
- // Distributed under the terms of the Modified BSD License.
- import { MessageLoop, Message } from '@lumino/messaging';
- import { Widget } from '@lumino/widgets';
- import { simulate } from 'simulate-event';
- import { UUID } from '@lumino/coreutils';
- import { ServiceManager } from '@jupyterlab/services';
- import {
- CodeMirrorEditorFactory,
- CodeMirrorMimeTypeService
- } from '@jupyterlab/codemirror';
- import {
- Context,
- DocumentRegistry,
- TextModelFactory,
- DocumentWidget
- } from '@jupyterlab/docregistry';
- import {
- FileEditor,
- FileEditorCodeWrapper,
- FileEditorFactory
- } from '@jupyterlab/fileeditor';
- import { framePromise } from '@jupyterlab/testutils';
- import * as Mock from '@jupyterlab/testutils/lib/mock';
- class LogFileEditor extends FileEditor {
- events: string[] = [];
- methods: string[] = [];
- handleEvent(event: Event): void {
- this.events.push(event.type);
- super.handleEvent(event);
- }
- protected onAfterAttach(msg: Message): void {
- super.onAfterAttach(msg);
- this.methods.push('onAfterAttach');
- }
- protected onBeforeDetach(msg: Message): void {
- super.onBeforeDetach(msg);
- this.methods.push('onBeforeDetach');
- }
- protected onActivateRequest(msg: Message): void {
- super.onActivateRequest(msg);
- this.methods.push('onActivateRequest');
- }
- }
- describe('fileeditorcodewrapper', () => {
- const factoryService = new CodeMirrorEditorFactory();
- const modelFactory = new TextModelFactory();
- const mimeTypeService = new CodeMirrorMimeTypeService();
- let context: Context<DocumentRegistry.ICodeModel>;
- let manager: ServiceManager.IManager;
- beforeAll(() => {
- manager = new Mock.ServiceManagerMock();
- return manager.ready;
- });
- describe('FileEditorCodeWrapper', () => {
- let widget: FileEditorCodeWrapper;
- beforeEach(() => {
- const path = UUID.uuid4() + '.py';
- context = new Context({ manager, factory: modelFactory, path });
- widget = new FileEditorCodeWrapper({
- factory: options => factoryService.newDocumentEditor(options),
- mimeTypeService,
- context
- });
- });
- afterEach(() => {
- widget.dispose();
- });
- describe('#constructor()', () => {
- it('should create an editor wrapper widget', () => {
- expect(widget).toBeInstanceOf(FileEditorCodeWrapper);
- });
- it('should update the editor text when the model changes', async () => {
- await context.initialize(true);
- await context.ready;
- widget.context.model.fromString('foo');
- expect(widget.editor.model.value.text).toBe('foo');
- });
- });
- describe('#context', () => {
- it('should be the context used by the widget', () => {
- expect(widget.context).toBe(context);
- });
- });
- });
- describe('FileEditor', () => {
- let widget: LogFileEditor;
- beforeEach(() => {
- const path = UUID.uuid4() + '.py';
- context = new Context({ manager, factory: modelFactory, path });
- widget = new LogFileEditor({
- factory: options => factoryService.newDocumentEditor(options),
- mimeTypeService,
- context
- });
- });
- afterEach(() => {
- widget.dispose();
- });
- describe('#constructor()', () => {
- it('should create an editor widget', () => {
- expect(widget).toBeInstanceOf(FileEditor);
- });
- it('should update the editor text when the model changes', async () => {
- await context.initialize(true);
- await context.ready;
- widget.context.model.fromString('foo');
- expect(widget.editor.model.value.text).toBe('foo');
- });
- it('should set the mime type for the path', () => {
- expect(widget.editor.model.mimeType).toBe('text/x-python');
- });
- it('should update the mime type when the path changes', async () => {
- let called = false;
- context.pathChanged.connect((sender, args) => {
- expect(widget.editor.model.mimeType).toBe('text/x-julia');
- called = true;
- });
- await context.initialize(true);
- await manager.contents.rename(context.path, UUID.uuid4() + '.jl');
- expect(called).toBe(true);
- });
- });
- describe('#context', () => {
- it('should be the context used by the widget', () => {
- expect(widget.context).toBe(context);
- });
- });
- describe('#handleEvent()', () => {
- beforeEach(() => {
- Widget.attach(widget, document.body);
- return framePromise();
- });
- afterEach(() => {
- widget.dispose();
- });
- describe('mousedown', () => {
- it('should focus the editor', () => {
- simulate(widget.node, 'mousedown');
- expect(widget.events).toContain('mousedown');
- expect(widget.editor.hasFocus()).toBe(true);
- });
- });
- });
- describe('#onAfterAttach()', () => {
- it('should add event listeners', async () => {
- Widget.attach(widget, document.body);
- await framePromise();
- expect(widget.methods).toContain('onAfterAttach');
- simulate(widget.node, 'mousedown');
- expect(widget.events).toContain('mousedown');
- });
- });
- describe('#onBeforeDetach()', () => {
- it('should remove event listeners', async () => {
- Widget.attach(widget, document.body);
- await framePromise();
- Widget.detach(widget);
- expect(widget.methods).toContain('onBeforeDetach');
- widget.events = [];
- simulate(widget.node, 'mousedown');
- expect(widget.events).not.toContain('mousedown');
- });
- });
- describe('#onActivateRequest()', () => {
- it('should focus the node after an update', async () => {
- Widget.attach(widget, document.body);
- MessageLoop.sendMessage(widget, Widget.Msg.ActivateRequest);
- expect(widget.methods).toContain('onActivateRequest');
- await framePromise();
- expect(widget.editor.hasFocus()).toBe(true);
- });
- });
- });
- describe('FileEditorFactory', () => {
- const widgetFactory = new FileEditorFactory({
- editorServices: {
- factoryService,
- mimeTypeService
- },
- factoryOptions: {
- name: 'editor',
- fileTypes: ['*'],
- defaultFor: ['*']
- }
- });
- describe('#constructor()', () => {
- it('should create an FileEditorFactory', () => {
- expect(widgetFactory).toBeInstanceOf(FileEditorFactory);
- });
- });
- describe('#createNewWidget()', () => {
- it('should create a document widget', () => {
- const d = widgetFactory.createNew(context);
- expect(d).toBeInstanceOf(DocumentWidget);
- expect(d.content).toBeInstanceOf(FileEditor);
- });
- });
- });
- });
|