registry.spec.ts 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. import {
  4. ABCWidgetFactory,
  5. Base64ModelFactory,
  6. DocumentRegistry,
  7. DocumentWidget,
  8. IDocumentWidget
  9. } from '@jupyterlab/docregistry';
  10. import { toArray } from '@lumino/algorithm';
  11. import { UUID } from '@lumino/coreutils';
  12. import { DisposableDelegate, IDisposable } from '@lumino/disposable';
  13. import { Widget } from '@lumino/widgets';
  14. class WidgetFactory extends ABCWidgetFactory<IDocumentWidget> {
  15. protected createNewWidget(
  16. context: DocumentRegistry.Context
  17. ): IDocumentWidget {
  18. const content = new Widget();
  19. const widget = new DocumentWidget({ content, context });
  20. widget.addClass('WidgetFactory');
  21. return widget;
  22. }
  23. }
  24. class WidgetExtension implements DocumentRegistry.WidgetExtension {
  25. createNew(widget: Widget, context: DocumentRegistry.Context): IDisposable {
  26. return new DisposableDelegate(() => undefined);
  27. }
  28. }
  29. function createFactory(modelName?: string) {
  30. return new WidgetFactory({
  31. name: UUID.uuid4(),
  32. modelName: modelName || 'text',
  33. fileTypes: ['text', 'foobar', 'baz'],
  34. defaultFor: ['text', 'foobar'],
  35. defaultRendered: ['baz']
  36. });
  37. }
  38. describe('docregistry/registry', () => {
  39. describe('DocumentRegistry', () => {
  40. let registry: DocumentRegistry;
  41. beforeEach(() => {
  42. registry = new DocumentRegistry();
  43. registry.addFileType({
  44. name: 'foobar',
  45. extensions: ['.foo.bar']
  46. });
  47. registry.addFileType({
  48. name: 'baz',
  49. extensions: ['.baz']
  50. });
  51. });
  52. afterEach(() => {
  53. registry.dispose();
  54. });
  55. describe('#isDisposed', () => {
  56. it('should get whether the registry has been disposed', () => {
  57. expect(registry.isDisposed).toBe(false);
  58. registry.dispose();
  59. expect(registry.isDisposed).toBe(true);
  60. });
  61. });
  62. describe('#dispose()', () => {
  63. it('should dispose of the resources held by the registry', () => {
  64. registry.addFileType({ name: 'notebook', extensions: ['.ipynb'] });
  65. registry.dispose();
  66. expect(registry.isDisposed).toBe(true);
  67. });
  68. it('should be safe to call multiple times', () => {
  69. registry.dispose();
  70. registry.dispose();
  71. expect(registry.isDisposed).toBe(true);
  72. });
  73. });
  74. describe('#addWidgetFactory()', () => {
  75. it('should add the widget factory to the registry', () => {
  76. const factory = createFactory();
  77. registry.addWidgetFactory(factory);
  78. expect(registry.getWidgetFactory(factory.name)).toBe(factory);
  79. expect(registry.getWidgetFactory(factory.name.toUpperCase())).toBe(
  80. factory
  81. );
  82. });
  83. it('should become the global default if `*` is given as a defaultFor', () => {
  84. const factory = new WidgetFactory({
  85. name: 'global',
  86. fileTypes: ['*'],
  87. defaultFor: ['*']
  88. });
  89. registry.addWidgetFactory(factory);
  90. expect(registry.defaultWidgetFactory('*').name).toBe('global');
  91. });
  92. it('should override an existing global default', () => {
  93. registry.addWidgetFactory(
  94. new WidgetFactory({
  95. name: 'global',
  96. fileTypes: ['*'],
  97. defaultFor: ['*']
  98. })
  99. );
  100. const factory = new WidgetFactory({
  101. name: 'bar',
  102. fileTypes: ['*'],
  103. defaultFor: ['*']
  104. });
  105. registry.addWidgetFactory(factory);
  106. expect(registry.defaultWidgetFactory('*').name).toBe('bar');
  107. });
  108. it('should override an existing extension default', () => {
  109. registry.addWidgetFactory(createFactory());
  110. const factory = createFactory();
  111. registry.addWidgetFactory(factory);
  112. expect(registry.defaultWidgetFactory('a.foo.bar')).toBe(factory);
  113. });
  114. it('should be removed from the registry when disposed', () => {
  115. const factory = createFactory();
  116. const disposable = registry.addWidgetFactory(factory);
  117. disposable.dispose();
  118. expect(registry.getWidgetFactory('test')).toBeUndefined();
  119. });
  120. it('should throw for an invalid factory name', () => {
  121. expect(() => {
  122. registry.addWidgetFactory(
  123. new WidgetFactory({
  124. name: 'default',
  125. fileTypes: [],
  126. defaultFor: []
  127. })
  128. );
  129. }).toThrowError(/Invalid/);
  130. expect(() => {
  131. registry.addWidgetFactory(
  132. new WidgetFactory({
  133. name: '',
  134. fileTypes: [],
  135. defaultFor: []
  136. })
  137. );
  138. }).toThrowError(/Invalid/);
  139. });
  140. });
  141. describe('#addModelFactory()', () => {
  142. it('should add the model factory to the registry', () => {
  143. const factory = new Base64ModelFactory();
  144. registry.addModelFactory(factory);
  145. });
  146. it('should be a no-op a factory with the given `name` is already registered', () => {
  147. const factory = new Base64ModelFactory();
  148. registry.addModelFactory(factory);
  149. const disposable = registry.addModelFactory(new Base64ModelFactory());
  150. disposable.dispose();
  151. });
  152. it('should be a no-op if the same factory is already registered', () => {
  153. const factory = new Base64ModelFactory();
  154. registry.addModelFactory(factory);
  155. const disposable = registry.addModelFactory(factory);
  156. disposable.dispose();
  157. });
  158. it('should be removed from the registry when disposed', () => {
  159. const factory = new Base64ModelFactory();
  160. const disposable = registry.addModelFactory(factory);
  161. disposable.dispose();
  162. });
  163. });
  164. describe('#addWidgetExtension()', () => {
  165. it('should add a widget extension to the registry', () => {
  166. const extension = new WidgetExtension();
  167. registry.addWidgetExtension('foo', extension);
  168. expect(registry.widgetExtensions('foo').next()).toBe(extension);
  169. });
  170. it('should be a no-op if the extension is already registered for a given widget factory', () => {
  171. const extension = new WidgetExtension();
  172. registry.addWidgetExtension('foo', extension);
  173. const disposable = registry.addWidgetExtension('foo', extension);
  174. disposable.dispose();
  175. expect(registry.widgetExtensions('foo').next()).toBe(extension);
  176. });
  177. it('should be removed from the registry when disposed', () => {
  178. const extension = new WidgetExtension();
  179. const disposable = registry.addWidgetExtension('foo', extension);
  180. disposable.dispose();
  181. expect(toArray(registry.widgetExtensions('foo')).length).toBe(0);
  182. });
  183. });
  184. describe('#addFileType()', () => {
  185. it('should add a file type to the document registry', () => {
  186. registry = new DocumentRegistry({ initialFileTypes: [] });
  187. const fileType = { name: 'notebook', extensions: ['.ipynb'] };
  188. registry.addFileType(fileType);
  189. expect(registry.fileTypes().next()!.name).toBe(fileType.name);
  190. });
  191. it('should be removed from the registry when disposed', () => {
  192. registry = new DocumentRegistry({ initialFileTypes: [] });
  193. const fileType = { name: 'notebook', extensions: ['.ipynb'] };
  194. const disposable = registry.addFileType(fileType);
  195. disposable.dispose();
  196. expect(toArray(registry.fileTypes()).length).toBe(0);
  197. });
  198. it('should be a no-op if a file type of the same name is registered', () => {
  199. registry = new DocumentRegistry({ initialFileTypes: [] });
  200. const fileType = { name: 'notebook', extensions: ['.ipynb'] };
  201. registry.addFileType(fileType);
  202. const disposable = registry.addFileType(fileType);
  203. disposable.dispose();
  204. expect(registry.fileTypes().next()!.name).toBe(fileType.name);
  205. });
  206. });
  207. describe('#preferredWidgetFactories()', () => {
  208. beforeEach(() => {
  209. registry.addFileType({
  210. name: 'tablejson',
  211. extensions: ['.table.json']
  212. });
  213. });
  214. it('should give the valid registered widget factories', () => {
  215. expect(toArray(registry.preferredWidgetFactories('foo.txt'))).toEqual(
  216. []
  217. );
  218. const factory = createFactory();
  219. registry.addWidgetFactory(factory);
  220. const gFactory = new WidgetFactory({
  221. name: 'global',
  222. fileTypes: ['*'],
  223. defaultFor: ['*']
  224. });
  225. registry.addWidgetFactory(gFactory);
  226. const factories = registry.preferredWidgetFactories('a.foo.bar');
  227. expect(toArray(factories)).toEqual([factory, gFactory]);
  228. });
  229. it('should not list a factory whose model is not registered', () => {
  230. registry.addWidgetFactory(createFactory('foobar'));
  231. expect(registry.preferredWidgetFactories('a.foo.bar').length).toEqual(
  232. 0
  233. );
  234. });
  235. it('should select the factory for a given extension', () => {
  236. const factory = createFactory();
  237. registry.addWidgetFactory(factory);
  238. const mdFactory = new WidgetFactory({
  239. name: 'markdown',
  240. fileTypes: ['markdown']
  241. });
  242. registry.addWidgetFactory(mdFactory);
  243. expect(registry.preferredWidgetFactories('a.txt')[0]).toBe(factory);
  244. expect(registry.preferredWidgetFactories('a.md')[0]).toBe(mdFactory);
  245. });
  246. it('should respect the priority order', () => {
  247. const factory = createFactory();
  248. registry.addWidgetFactory(factory);
  249. const gFactory = new WidgetFactory({
  250. name: 'global',
  251. fileTypes: ['*'],
  252. defaultFor: ['*']
  253. });
  254. registry.addWidgetFactory(gFactory);
  255. const mdFactory = new WidgetFactory({
  256. name: 'markdown',
  257. fileTypes: ['markdown']
  258. });
  259. registry.addWidgetFactory(mdFactory);
  260. const factories = registry.preferredWidgetFactories('a.txt');
  261. expect(toArray(factories)).toEqual([factory, gFactory]);
  262. });
  263. it('should list a default rendered factory after the default factory', () => {
  264. const factory = createFactory();
  265. registry.addWidgetFactory(factory);
  266. const gFactory = new WidgetFactory({
  267. name: 'global',
  268. fileTypes: ['*'],
  269. defaultFor: ['*']
  270. });
  271. registry.addWidgetFactory(gFactory);
  272. const mdFactory = new WidgetFactory({
  273. name: 'markdown',
  274. fileTypes: ['markdown'],
  275. defaultRendered: ['markdown']
  276. });
  277. registry.addWidgetFactory(mdFactory);
  278. const factories = registry.preferredWidgetFactories('a.md');
  279. expect(factories).toEqual([mdFactory, gFactory]);
  280. });
  281. it('should handle multi-part extensions', () => {
  282. const factory = createFactory();
  283. registry.addWidgetFactory(factory);
  284. const tFactory = new WidgetFactory({
  285. name: 'table',
  286. fileTypes: ['tablejson']
  287. });
  288. registry.addWidgetFactory(tFactory);
  289. const jFactory = new WidgetFactory({
  290. name: 'json',
  291. fileTypes: ['json']
  292. });
  293. registry.addWidgetFactory(jFactory);
  294. let factories = registry.preferredWidgetFactories('foo.table.json');
  295. expect(toArray(factories)).toEqual([tFactory, jFactory]);
  296. factories = registry.preferredWidgetFactories('foo.json');
  297. expect(toArray(factories)).toEqual([jFactory]);
  298. });
  299. it('should handle just a multi-part extension', () => {
  300. const factory = new WidgetFactory({
  301. name: 'table',
  302. fileTypes: ['tablejson']
  303. });
  304. registry.addWidgetFactory(factory);
  305. let factories = registry.preferredWidgetFactories('foo.table.json');
  306. expect(toArray(factories)).toEqual([factory]);
  307. factories = registry.preferredWidgetFactories('foo.json');
  308. expect(toArray(factories)).toEqual([]);
  309. });
  310. });
  311. describe('#defaultWidgetFactory()', () => {
  312. it('should get the default widget factory for a given extension', () => {
  313. const factory = createFactory();
  314. registry.addWidgetFactory(factory);
  315. const gFactory = new WidgetFactory({
  316. name: 'global',
  317. fileTypes: ['*'],
  318. defaultFor: ['*']
  319. });
  320. registry.addWidgetFactory(gFactory);
  321. const mdFactory = new WidgetFactory({
  322. name: 'markdown',
  323. fileTypes: ['markdown'],
  324. defaultFor: ['markdown']
  325. });
  326. registry.addWidgetFactory(mdFactory);
  327. expect(registry.defaultWidgetFactory('a.foo.bar')).toBe(factory);
  328. expect(registry.defaultWidgetFactory('a.md')).toBe(mdFactory);
  329. expect(registry.defaultWidgetFactory()).toBe(gFactory);
  330. });
  331. });
  332. describe('#setDefaultWidgetFactory()', () => {
  333. it('should override the default widget factory for a file type', () => {
  334. const mdFactory = new WidgetFactory({
  335. name: 'markdown',
  336. fileTypes: ['markdown', 'foobar'],
  337. defaultFor: []
  338. });
  339. registry.addWidgetFactory(mdFactory);
  340. registry.setDefaultWidgetFactory('foobar', 'markdown');
  341. expect(registry.defaultWidgetFactory('a.foo.bar')).toBe(mdFactory);
  342. });
  343. it('should revert to the default widget factory when unset', () => {
  344. const factory = createFactory();
  345. registry.addWidgetFactory(factory);
  346. const mdFactory = new WidgetFactory({
  347. name: 'markdown',
  348. fileTypes: ['markdown', 'foobar'],
  349. defaultFor: []
  350. });
  351. registry.addWidgetFactory(mdFactory);
  352. registry.setDefaultWidgetFactory('foobar', 'markdown');
  353. registry.setDefaultWidgetFactory('foobar', undefined);
  354. expect(registry.defaultWidgetFactory('a.foo.bar')).toBe(factory);
  355. });
  356. it('should throw if the factory or file type do not exist', () => {
  357. const factory = createFactory();
  358. registry.addWidgetFactory(factory);
  359. expect(() => {
  360. registry.setDefaultWidgetFactory('foobar', 'fake');
  361. }).toThrowError(/Cannot find/);
  362. expect(() => {
  363. registry.setDefaultWidgetFactory('fake', undefined);
  364. }).toThrowError(/Cannot find/);
  365. });
  366. it('should throw if the factory cannot render a file type', () => {
  367. const mdFactory = new WidgetFactory({
  368. name: 'markdown',
  369. fileTypes: ['markdown'],
  370. defaultFor: []
  371. });
  372. registry.addWidgetFactory(mdFactory);
  373. expect(() => {
  374. registry.setDefaultWidgetFactory('foobar', 'markdown');
  375. }).toThrowError(/cannot view/);
  376. });
  377. it('should revert to the default widget factory if the override is removed', () => {
  378. const factory = createFactory();
  379. registry.addWidgetFactory(factory);
  380. const mdFactory = new WidgetFactory({
  381. name: 'markdown',
  382. fileTypes: ['markdown', 'foobar'],
  383. defaultFor: []
  384. });
  385. const disposable = registry.addWidgetFactory(mdFactory);
  386. registry.setDefaultWidgetFactory('foobar', 'markdown');
  387. disposable.dispose();
  388. expect(registry.defaultWidgetFactory('a.foo.bar')).toBe(factory);
  389. });
  390. });
  391. describe('#defaultRenderedWidgetFactory()', () => {
  392. it('should get the default rendered widget factory for a given extension', () => {
  393. const factory = createFactory();
  394. registry.addWidgetFactory(factory);
  395. const mdFactory = new WidgetFactory({
  396. name: 'markdown',
  397. fileTypes: ['markdown'],
  398. defaultRendered: ['markdown']
  399. });
  400. registry.addWidgetFactory(mdFactory);
  401. expect(registry.defaultRenderedWidgetFactory('a.baz')).toBe(factory);
  402. expect(registry.defaultRenderedWidgetFactory('a.md')).toBe(mdFactory);
  403. });
  404. it('should get the default widget factory if no default rendered factory is registered', () => {
  405. const gFactory = new WidgetFactory({
  406. name: 'global',
  407. fileTypes: ['*'],
  408. defaultFor: ['*']
  409. });
  410. registry.addWidgetFactory(gFactory);
  411. expect(registry.defaultRenderedWidgetFactory('a.md')).toBe(gFactory);
  412. });
  413. });
  414. describe('#fileTypes()', () => {
  415. it('should get the registered file types', () => {
  416. registry = new DocumentRegistry({ initialFileTypes: [] });
  417. expect(toArray(registry.fileTypes()).length).toBe(0);
  418. const fileTypes = [
  419. { name: 'notebook', extensions: ['.ipynb'] },
  420. { name: 'python', extensions: ['.py'] },
  421. { name: 'table', extensions: ['.table.json'] }
  422. ];
  423. registry.addFileType(fileTypes[0]);
  424. registry.addFileType(fileTypes[1]);
  425. registry.addFileType(fileTypes[2]);
  426. const values = registry.fileTypes();
  427. expect(values.next()!.name).toBe(fileTypes[0].name);
  428. expect(values.next()!.name).toBe(fileTypes[1].name);
  429. expect(values.next()!.name).toBe(fileTypes[2].name);
  430. });
  431. });
  432. describe('#getFileType()', () => {
  433. it('should get a file type by name', () => {
  434. expect(registry.getFileType('notebook')).toBeTruthy();
  435. expect(registry.getFileType('python')).toBeTruthy();
  436. expect(registry.getFileType('fizzbuzz')).toBeUndefined();
  437. });
  438. });
  439. describe('#getKernelPreference()', () => {
  440. it('should get a kernel preference', () => {
  441. registry.addWidgetFactory(createFactory());
  442. registry.addWidgetFactory(
  443. new WidgetFactory({
  444. name: 'python',
  445. fileTypes: ['python'],
  446. preferKernel: true,
  447. canStartKernel: true
  448. })
  449. );
  450. registry.addWidgetFactory(
  451. new WidgetFactory({
  452. name: 'global',
  453. fileTypes: ['*'],
  454. defaultFor: ['*']
  455. })
  456. );
  457. let pref = registry.getKernelPreference('.c', 'global');
  458. expect(pref!.language).toBe('clike');
  459. expect(pref!.shouldStart).toBe(false);
  460. expect(pref!.canStart).toBe(false);
  461. pref = registry.getKernelPreference('.py', 'python');
  462. expect(pref!.language).toBe('python');
  463. expect(pref!.shouldStart).toBe(true);
  464. expect(pref!.canStart).toBe(true);
  465. pref = registry.getKernelPreference('.py', 'baz');
  466. expect(pref).toBeUndefined();
  467. });
  468. });
  469. describe('#getModelFactory()', () => {
  470. it('should get a registered model factory by name', () => {
  471. const mFactory = new Base64ModelFactory();
  472. registry.addModelFactory(mFactory);
  473. expect(registry.getModelFactory('base64')).toBe(mFactory);
  474. });
  475. });
  476. describe('#getWidgetFactory()', () => {
  477. it('should get a widget factory by name', () => {
  478. registry.addModelFactory(new Base64ModelFactory());
  479. const factory = createFactory();
  480. registry.addWidgetFactory(factory);
  481. const mdFactory = new WidgetFactory({
  482. name: 'markdown',
  483. fileTypes: ['markdown']
  484. });
  485. registry.addWidgetFactory(mdFactory);
  486. expect(registry.getWidgetFactory(factory.name)).toBe(factory);
  487. expect(registry.getWidgetFactory('markdown')).toBe(mdFactory);
  488. expect(registry.getWidgetFactory('baz')).toBeUndefined();
  489. });
  490. });
  491. describe('#widgetExtensions()', () => {
  492. it('should get the registered extensions for a given widget', () => {
  493. const foo = new WidgetExtension();
  494. const bar = new WidgetExtension();
  495. registry.addWidgetExtension('fizz', foo);
  496. registry.addWidgetExtension('fizz', bar);
  497. registry.addWidgetExtension('buzz', foo);
  498. const fizz = toArray(registry.widgetExtensions('fizz'));
  499. expect(fizz[0]).toBe(foo);
  500. expect(fizz[1]).toBe(bar);
  501. expect(fizz.length).toBe(2);
  502. const buzz = toArray(registry.widgetExtensions('buzz'));
  503. expect(buzz[0]).toBe(foo);
  504. expect(toArray(buzz).length).toBe(1);
  505. expect(registry.widgetExtensions('baz').next()).toBeUndefined();
  506. });
  507. });
  508. describe('#getFileTypeForModel()', () => {
  509. beforeEach(() => {
  510. DocumentRegistry.getDefaultFileTypes().forEach(ft => {
  511. registry.addFileType(ft);
  512. });
  513. });
  514. it('should handle a directory', () => {
  515. const ft = registry.getFileTypeForModel({
  516. type: 'directory'
  517. });
  518. expect(ft.name).toBe('directory');
  519. });
  520. it('should handle a notebook', () => {
  521. const ft = registry.getFileTypeForModel({
  522. type: 'notebook'
  523. });
  524. expect(ft.name).toBe('notebook');
  525. });
  526. it('should handle a python file', () => {
  527. const ft = registry.getFileTypeForModel({
  528. name: 'foo.py'
  529. });
  530. expect(ft.name).toBe('python');
  531. });
  532. it('should handle an unknown file', () => {
  533. const ft = registry.getFileTypeForModel({
  534. name: 'foo.bar'
  535. });
  536. expect(ft.name).toBe('text');
  537. });
  538. it('should get the most specific extension', () => {
  539. [
  540. { name: 'json', extensions: ['.json'] },
  541. { name: 'vega', extensions: ['.vg.json'] }
  542. ].forEach(ft => {
  543. registry.addFileType(ft);
  544. });
  545. const ft = registry.getFileTypeForModel({
  546. name: 'foo.vg.json'
  547. });
  548. expect(ft.name).toBe('vega');
  549. });
  550. it('should be case insensitive', () => {
  551. const ft = registry.getFileTypeForModel({
  552. name: 'foo.PY'
  553. });
  554. expect(ft.name).toBe('python');
  555. });
  556. });
  557. describe('#getFileTypesForPath()', () => {
  558. beforeEach(() => {
  559. DocumentRegistry.getDefaultFileTypes().forEach(ft => {
  560. registry.addFileType(ft);
  561. });
  562. });
  563. it('should handle a notebook', () => {
  564. const ft = registry.getFileTypesForPath('foo/bar/baz.ipynb');
  565. expect(ft[0].name).toBe('notebook');
  566. });
  567. it('should handle a python file', () => {
  568. const ft = registry.getFileTypesForPath('foo/bar/baz.py');
  569. expect(ft[0].name).toBe('python');
  570. });
  571. it('should return an empty list for an unknown file', () => {
  572. const ft = registry.getFileTypesForPath('foo/bar/baz.weird');
  573. expect(ft.length).toBe(0);
  574. });
  575. it('should get the most specific extension first', () => {
  576. [
  577. { name: 'json', extensions: ['.json'] },
  578. { name: 'vega', extensions: ['.vg.json'] }
  579. ].forEach(ft => {
  580. registry.addFileType(ft);
  581. });
  582. const ft = registry.getFileTypesForPath('foo/bar/baz.vg.json');
  583. expect(ft[0].name).toBe('vega');
  584. expect(ft[1].name).toBe('json');
  585. });
  586. it.each([
  587. ['python', null, 'foo/bar/baz.PY'],
  588. ['r-markdown', ['.Rmd'], 'foo/bar/baz.Rmd']
  589. ])('should be case insensitive', (name, extensions, filename) => {
  590. if (extensions) {
  591. registry.addFileType({ name, extensions });
  592. }
  593. const ft = registry.getFileTypesForPath(filename);
  594. expect(ft[0].name).toBe(name);
  595. });
  596. it('should support pattern matching', () => {
  597. registry.addFileType({
  598. name: 'test',
  599. extensions: ['.temp'],
  600. pattern: '.*\\.test$'
  601. });
  602. const ft = registry.getFileTypesForPath('foo/bar/baz.test');
  603. expect(ft[0].name).toBe('test');
  604. const ft2 = registry.getFileTypesForPath('foo/bar/baz.temp');
  605. expect(ft2[0].name).toBe('test');
  606. });
  607. });
  608. });
  609. });