utils.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794
  1. /**
  2. * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /* global describe, it, beforeEach, afterEach */
  6. 'use strict';
  7. const chai = require( 'chai' );
  8. const expect = chai.expect;
  9. const sinon = require( 'sinon' );
  10. const gulp = require( 'gulp' );
  11. const gutil = require( 'gulp-util' );
  12. const path = require( 'path' );
  13. const stream = require( 'stream' );
  14. const Vinyl = require( 'vinyl' );
  15. const through = require( 'through2' );
  16. const mainUtils = require( '../../tasks/utils' );
  17. describe( 'build-utils', () => {
  18. const utils = require( '../../tasks/build/utils' );
  19. let sandbox;
  20. beforeEach( () => {
  21. sandbox = sinon.sandbox.create();
  22. } );
  23. afterEach( () => {
  24. sandbox.restore();
  25. } );
  26. it( 'should be extended by top level utils', () => {
  27. expect( utils.clean ).to.be.equal( mainUtils.clean );
  28. } );
  29. describe( 'noop', () => {
  30. it( 'should return PassTrough stream', () => {
  31. const PassThrough = stream.PassThrough;
  32. const ret = utils.noop();
  33. expect( ret instanceof PassThrough ).to.equal( true );
  34. } );
  35. it( 'should return a duplex stream when given a callback and call that callback', () => {
  36. const spy = sinon.spy();
  37. const ret = utils.noop( spy );
  38. ret.write( 'foo' );
  39. expect( spy.called ).to.equal( true );
  40. expect( ret.writable ).to.equal( true );
  41. expect( ret.readable ).to.equal( true );
  42. } );
  43. } );
  44. describe( 'destBuild', () => {
  45. it( 'should return stream created with gulp.dest', () => {
  46. const buildDir = 'build/';
  47. const format = 'amd';
  48. const destSpy = sandbox.spy( gulp, 'dest' );
  49. const stream = utils.destBuild( buildDir, format );
  50. sinon.assert.calledOnce( destSpy );
  51. sinon.assert.calledWithExactly( destSpy, path.join( buildDir, format ) );
  52. expect( stream ).to.equal( destSpy.firstCall.returnValue );
  53. } );
  54. } );
  55. describe( 'transpile', () => {
  56. it( 'should return babel transform stream', ( done ) => {
  57. const Stream = stream.Stream;
  58. const modulePath = '../files/utils/lib';
  59. const appendModuleExtensionSpy = sandbox.spy( utils, 'appendModuleExtension' );
  60. const babelStream = utils.transpile( 'amd', utils.getBabelOptionsForTests( 'amd' ) );
  61. expect( babelStream instanceof Stream ).to.equal( true );
  62. expect( babelStream.readable ).to.equal( true );
  63. expect( babelStream.writable ).to.equal( true );
  64. babelStream.on( 'finish', () => {
  65. sinon.assert.calledOnce( appendModuleExtensionSpy );
  66. expect( appendModuleExtensionSpy.args[ 0 ][ 0 ] ).to.equal( modulePath );
  67. done();
  68. } );
  69. babelStream.pipe(
  70. utils.noop( ( file ) => {
  71. expect( file.contents.toString() ).to.match( /define\(\'tests\'/ );
  72. } )
  73. );
  74. babelStream.write( new Vinyl( {
  75. cwd: '/',
  76. base: '/test/',
  77. path: '/test/file.js',
  78. contents: new Buffer( `import * as lib from '${ modulePath }';` )
  79. } ) );
  80. babelStream.end();
  81. } );
  82. it( 'should report error when transpiling fails', ( done ) => {
  83. const babelStream = utils.transpile( 'amd' );
  84. const utilLogStub = sandbox.stub( gutil, 'log' );
  85. const consoleLogStub = sandbox.stub( console, 'log' );
  86. babelStream.once( 'finish', () => {
  87. sinon.assert.calledTwice( utilLogStub );
  88. sinon.assert.calledOnce( consoleLogStub );
  89. done();
  90. } );
  91. babelStream.write( new Vinyl( {
  92. cwd: '/',
  93. base: '/test/',
  94. path: '/test/file.js',
  95. contents: new Buffer( 'class ;' )
  96. } ) );
  97. babelStream.end();
  98. } );
  99. } );
  100. describe( 'getBabelOptionsForSource', () => {
  101. it( 'should return plugins for amd format', () => {
  102. const plugins = [ 'foo' ];
  103. sandbox.stub( utils, 'getBabelPlugins', () => plugins );
  104. const options = utils.getBabelOptionsForSource( 'amd' );
  105. expect( options ).to.have.property( 'plugins', plugins );
  106. expect( options ).to.have.property( 'resolveModuleSource' );
  107. expect( options.resolveModuleSource ).to.equal( utils.appendModuleExtension );
  108. } );
  109. it( 'should return plugins for cjs format', () => {
  110. const plugins = [ 'foo' ];
  111. sandbox.stub( utils, 'getBabelPlugins', () => plugins );
  112. const options = utils.getBabelOptionsForSource( 'cjs' );
  113. expect( options ).to.have.property( 'plugins', plugins );
  114. expect( options ).to.have.property( 'resolveModuleSource' );
  115. expect( options.resolveModuleSource ).to.equal( utils.resolveModuleSource );
  116. } );
  117. } );
  118. describe( 'getBabelOptionsForTests', () => {
  119. it( 'should return plugins for amd format', () => {
  120. const plugins = [ 'foo' ];
  121. sandbox.stub( utils, 'getBabelPlugins', () => plugins );
  122. const options = utils.getBabelOptionsForTests( 'amd' );
  123. expect( options ).to.have.property( 'plugins', plugins );
  124. expect( options ).to.have.property( 'resolveModuleSource' );
  125. expect( options ).to.have.property( 'moduleIds', true );
  126. expect( options ).to.have.property( 'moduleId', 'tests' );
  127. expect( options.resolveModuleSource ).to.equal( utils.appendModuleExtension );
  128. } );
  129. it( 'should return plugins for cjs format', () => {
  130. const plugins = [ 'foo' ];
  131. sandbox.stub( utils, 'getBabelPlugins', () => plugins );
  132. const options = utils.getBabelOptionsForTests( 'cjs' );
  133. expect( options ).to.have.property( 'plugins', plugins );
  134. expect( options ).to.have.property( 'resolveModuleSource' );
  135. expect( options ).to.have.property( 'moduleIds', true );
  136. expect( options ).to.have.property( 'moduleId', 'tests' );
  137. expect( options.resolveModuleSource ).to.equal( utils.resolveModuleSource );
  138. } );
  139. } );
  140. describe( 'getBabelPlugins', () => {
  141. it( 'should return plugins for amd format', () => {
  142. expect( utils.getBabelPlugins( 'amd' ) ).to.be.an( 'array' );
  143. } );
  144. it( 'should return plugins for cjs format', () => {
  145. expect( utils.getBabelPlugins( 'cjs' ) ).to.be.an( 'array' );
  146. } );
  147. it( 'should throw an exception when incorrect format is provided', () => {
  148. const format = 'incorrect-format';
  149. expect( () => {
  150. utils.getBabelPlugins( format );
  151. } ).to.throw( Error, `Incorrect format: ${ format }` );
  152. } );
  153. } );
  154. describe( 'getConversionStreamGenerator', () => {
  155. beforeEach( () => {
  156. sandbox.stub( utils, 'getBabelOptionsForSource', () => 'src' );
  157. sandbox.stub( utils, 'getBabelOptionsForTests', () => 'tests' );
  158. // Stub to avoid writing to the fs.
  159. sandbox.stub( utils, 'destBuild', () => utils.noop() );
  160. // The transpile converted with append to file contents what was
  161. // passed to it as an options object and that's a result of getBabelOptions*,
  162. // which is stubbed above (will return 'src' or 'tests').
  163. sandbox.stub( utils, 'transpile', ( format, options ) => {
  164. return through( { objectMode: true }, ( file, encoding, callback ) => {
  165. file.contents = new Buffer( file.contents.toString() + ';' + format + ';' + options );
  166. callback( null, file );
  167. } );
  168. } );
  169. sandbox.stub( utils, 'appendBenderLauncher', () => {
  170. return through( { objectMode: true }, ( file, encoding, callback ) => {
  171. file.contents = new Buffer( file.contents.toString() + ';launcher' );
  172. callback( null, file );
  173. } );
  174. } );
  175. } );
  176. it( 'should return function that can be used for creating conversion streams', () => {
  177. const buildDir = 'build/';
  178. const formats = [ 'amd', 'cjs', 'esnext' ];
  179. const fn = utils.getConversionStreamGenerator( buildDir );
  180. const streams = formats.reduce( fn, [] );
  181. expect( streams.length ).to.equal( formats.length );
  182. } );
  183. describe( 'created conversion stream', () => {
  184. it( 'should process source JS file', ( done ) => {
  185. const buildDir = 'build/';
  186. const formats = [ 'amd' ];
  187. const fn = utils.getConversionStreamGenerator( buildDir );
  188. const streams = formats.reduce( fn, [] );
  189. expect( streams ).to.have.length( 1 );
  190. const stream = streams[ 0 ];
  191. stream.pipe(
  192. utils.noop( ( file ) => {
  193. expect( file.contents.toString() ).to.equal( 'foo();amd;src' );
  194. done();
  195. } )
  196. );
  197. stream.write( new Vinyl( {
  198. cwd: './',
  199. path: 'ckeditor5/core/file.js',
  200. contents: new Buffer( 'foo()' )
  201. } ) );
  202. } );
  203. } );
  204. describe( 'created conversion stream', () => {
  205. it( 'should process test file in amd format', ( done ) => {
  206. const buildDir = 'build/';
  207. const formats = [ 'amd' ];
  208. const fn = utils.getConversionStreamGenerator( buildDir );
  209. const streams = formats.reduce( fn, [] );
  210. expect( streams ).to.have.length( 1 );
  211. const stream = streams[ 0 ];
  212. stream.pipe(
  213. utils.noop( ( file ) => {
  214. expect( file.contents.toString() ).to.equal( 'foo();amd;tests;launcher' );
  215. done();
  216. } )
  217. );
  218. stream.write( new Vinyl( {
  219. cwd: './',
  220. path: 'tests/core/file.js',
  221. contents: new Buffer( 'foo()' )
  222. } ) );
  223. } );
  224. it( 'should process test file in cjs format', ( done ) => {
  225. const buildDir = 'build/';
  226. const formats = [ 'cjs' ];
  227. const fn = utils.getConversionStreamGenerator( buildDir );
  228. const streams = formats.reduce( fn, [] );
  229. expect( streams ).to.have.length( 1 );
  230. const stream = streams[ 0 ];
  231. stream.pipe(
  232. utils.noop( ( file ) => {
  233. expect( file.contents.toString() ).to.equal( 'foo();cjs;tests' );
  234. done();
  235. } )
  236. );
  237. stream.write( new Vinyl( {
  238. cwd: './',
  239. path: 'tests/core/file.js',
  240. contents: new Buffer( 'foo()' )
  241. } ) );
  242. } );
  243. } );
  244. } );
  245. describe( 'pickVersionedFile', () => {
  246. it( 'should rename file for provided format', ( done ) => {
  247. const rename = utils.pickVersionedFile( 'amd' );
  248. rename.pipe(
  249. utils.noop( ( data ) => {
  250. expect( data.basename ).to.equal( 'load.js' );
  251. done();
  252. } )
  253. );
  254. rename.write( new Vinyl( {
  255. cwd: '/',
  256. base: '/test/',
  257. path: '/test/load__amd.js',
  258. contents: new Buffer( '' )
  259. } ) );
  260. rename.end();
  261. } );
  262. it( 'should remove files in other formats', ( done ) => {
  263. const rename = utils.pickVersionedFile( 'amd' );
  264. const spy = sandbox.spy( ( data ) => {
  265. expect( data.basename ).to.equal( 'load.js' );
  266. } );
  267. rename.pipe(
  268. utils.noop( spy )
  269. );
  270. rename.on( 'end', () => {
  271. sinon.assert.calledOnce( spy );
  272. done();
  273. } );
  274. const amd = new Vinyl( {
  275. cwd: '/',
  276. base: '/test/',
  277. path: '/test/load__amd.js',
  278. contents: new Buffer( '' )
  279. } );
  280. const cjs = new Vinyl( {
  281. cwd: '/',
  282. base: '/test/',
  283. path: '/test/load__cjs.js',
  284. contents: new Buffer( '' )
  285. } );
  286. const esnext = new Vinyl( {
  287. cwd: '/',
  288. base: '/test/',
  289. path: '/test/load__esnext.js',
  290. contents: new Buffer( '' )
  291. } );
  292. rename.write( cjs );
  293. rename.write( amd );
  294. rename.write( esnext );
  295. rename.end();
  296. } );
  297. } );
  298. describe( 'renamePackageFiles', () => {
  299. it( 'should move source files to correct directories', ( done ) => {
  300. const rename = utils.renamePackageFiles();
  301. rename.pipe(
  302. utils.noop( ( data ) => {
  303. expect( data.path ).to.equal( path.normalize( 'ckeditor5/core/foo/file.js' ) );
  304. done();
  305. } )
  306. );
  307. rename.write( new Vinyl( {
  308. cwd: './',
  309. path: path.normalize( 'ckeditor5-core/src/foo/file.js' ),
  310. contents: new Buffer( '' )
  311. } ) );
  312. rename.end();
  313. } );
  314. it( 'should move test files to correct directories', ( done ) => {
  315. const rename = utils.renamePackageFiles();
  316. rename.pipe(
  317. utils.noop( ( data ) => {
  318. expect( data.path ).to.equal( path.normalize( 'tests/core/foo/file.js' ) );
  319. done();
  320. } )
  321. );
  322. rename.write( new Vinyl( {
  323. cwd: './',
  324. path: path.normalize( 'ckeditor5-core/tests/foo/file.js' ),
  325. contents: new Buffer( '' )
  326. } ) );
  327. rename.end();
  328. } );
  329. it( 'should throw error when wrong path provided 1', () => {
  330. const rename = utils.renamePackageFiles();
  331. expect( () => {
  332. rename.write( new Vinyl( {
  333. cwd: './',
  334. path: 'plugin/src/file.js',
  335. contents: new Buffer( '' )
  336. } ) );
  337. } ).to.throw( Error );
  338. } );
  339. it( 'should throw error when wrong path provided 2', () => {
  340. const rename = utils.renamePackageFiles();
  341. expect( () => {
  342. rename.write( new Vinyl( {
  343. cwd: './',
  344. path: 'ckeditor5-core/file.js',
  345. contents: new Buffer( '' )
  346. } ) );
  347. } ).to.throw( Error );
  348. } );
  349. } );
  350. describe( 'renameCKEditor5Files', () => {
  351. it( 'should move source files to correct directories', ( done ) => {
  352. const rename = utils.renameCKEditor5Files();
  353. rename.pipe(
  354. utils.noop( ( data ) => {
  355. expect( data.path ).to.equal( path.normalize( 'ckeditor5/foo/file.js' ) );
  356. done();
  357. } )
  358. );
  359. rename.write( new Vinyl( {
  360. cwd: './',
  361. path: path.normalize( 'src/foo/file.js' ),
  362. contents: new Buffer( '' )
  363. } ) );
  364. rename.end();
  365. } );
  366. it( 'should move test files to correct directories', ( done ) => {
  367. const rename = utils.renameCKEditor5Files();
  368. rename.pipe(
  369. utils.noop( ( data ) => {
  370. expect( data.path ).to.equal( path.normalize( 'tests/ckeditor5/foo/file.js' ) );
  371. done();
  372. } )
  373. );
  374. rename.write( new Vinyl( {
  375. cwd: './',
  376. path: path.normalize( 'tests/foo/file.js' ),
  377. contents: new Buffer( '' )
  378. } ) );
  379. rename.end();
  380. } );
  381. it( 'should throw error when wrong path provided 1', () => {
  382. const rename = utils.renameCKEditor5Files();
  383. expect( () => {
  384. rename.write( new Vinyl( {
  385. cwd: './',
  386. path: 'plugin/src/file.js',
  387. contents: new Buffer( '' )
  388. } ) );
  389. } ).to.throw( Error );
  390. } );
  391. } );
  392. describe( 'appendModuleExtension', () => {
  393. it( 'appends module extension when path provided', () => {
  394. const filePath = './path/to/file';
  395. const source = utils.appendModuleExtension( filePath );
  396. expect( source ).to.equal( filePath + '.js' );
  397. } );
  398. it( 'appends module extension when URL is provided', () => {
  399. const url = 'http://example.com/lib';
  400. const source = utils.appendModuleExtension( url );
  401. expect( source ).to.equal( url + '.js' );
  402. } );
  403. it( 'returns unchanged if module is provided', () => {
  404. const module = 'lib/module';
  405. const source = utils.appendModuleExtension( module );
  406. expect( source ).to.equal( module );
  407. } );
  408. } );
  409. describe( 'appendBenderLauncher', () => {
  410. it( 'appends the launcher code to a file', ( done ) => {
  411. const stream = utils.appendBenderLauncher();
  412. stream.pipe(
  413. utils.noop( ( data ) => {
  414. expect( data.contents.toString() ).equal( 'foo();' + utils.benderLauncherCode );
  415. done();
  416. } )
  417. );
  418. stream.write( new Vinyl( {
  419. cwd: './',
  420. path: 'tests/file.js',
  421. contents: new Buffer( 'foo();' )
  422. } ) );
  423. stream.end();
  424. } );
  425. // #62
  426. it( 'does nothing to a null file', ( done ) => {
  427. const stream = utils.appendBenderLauncher();
  428. stream.pipe(
  429. utils.noop( ( data ) => {
  430. expect( data.contents ).to.equal( null );
  431. done();
  432. } )
  433. );
  434. stream.write( new Vinyl( {
  435. cwd: './',
  436. path: 'tests/file.js',
  437. contents: null
  438. } ) );
  439. stream.end();
  440. } );
  441. } );
  442. describe( 'isTestFile', () => {
  443. function test( path, expected ) {
  444. it( `returns ${ expected} for ${ path }`, () => {
  445. const file = new Vinyl( {
  446. cwd: './',
  447. path: path,
  448. contents: new Buffer( '' )
  449. } );
  450. expect( utils.isTestFile( file ) ).to.equal( expected );
  451. } );
  452. }
  453. test( 'tests/file.js', true );
  454. test( 'tests/foo/file.js', true );
  455. test( 'tests/tests.js', true );
  456. test( 'tests/_utils-tests/foo.js', true );
  457. test( 'foo/file.js', false );
  458. test( 'foo/tests/file.js', false );
  459. test( 'tests/_foo/file.js', false );
  460. } );
  461. describe( 'getPackages', () => {
  462. it( 'returns collected paths to ckeditor5-* packages', ( done ) => {
  463. const fs = require( 'fs' );
  464. const readDirStub = sandbox.stub( fs, 'readdirSync', () => {
  465. return [
  466. 'ckeditor5-core',
  467. 'ckeditor5-theme-default'
  468. ];
  469. } );
  470. const statStub = sandbox.stub( fs, 'lstatSync', () => {
  471. return {
  472. isDirectory() {
  473. return true;
  474. },
  475. isSymbolicLink() {
  476. return false;
  477. }
  478. };
  479. } );
  480. expect( utils.getPackages( '.' ) ).to.have.members( [
  481. 'node_modules/ckeditor5-core',
  482. 'node_modules/ckeditor5-theme-default'
  483. ] );
  484. sinon.assert.calledOnce( readDirStub );
  485. sinon.assert.calledTwice( statStub );
  486. done();
  487. } );
  488. } );
  489. describe( 'filterThemeEntryPoints', () => {
  490. it( 'returns a stream containing theme entry points only', ( done ) => {
  491. const stream = require( 'stream' );
  492. const entryPoints = [];
  493. function fakeInputStream() {
  494. const files = [
  495. new Vinyl( {
  496. cwd: './',
  497. path: 'foo/bar/_helper.scss',
  498. contents: new Buffer( '' )
  499. } ),
  500. new Vinyl( {
  501. cwd: './',
  502. path: 'foo/bar/component.scss',
  503. contents: new Buffer( '' )
  504. } ),
  505. new Vinyl( {
  506. cwd: './',
  507. path: 'foo/bar/theme.scss',
  508. contents: new Buffer( '' )
  509. } ),
  510. new Vinyl( {
  511. cwd: './',
  512. path: 'foo/bar/_theme.scss',
  513. contents: new Buffer( '' )
  514. } )
  515. ];
  516. const fake = new stream.Readable( { objectMode: true } );
  517. fake._read = () => {
  518. fake.push( files.pop() || null );
  519. };
  520. return fake;
  521. }
  522. fakeInputStream()
  523. .pipe( utils.filterThemeEntryPoints() )
  524. .pipe( through.obj( ( file, encoding, callback ) => {
  525. entryPoints.push( file.path );
  526. callback();
  527. }, () => {
  528. expect( entryPoints ).to.have.members( [ 'foo/bar/theme.scss' ] );
  529. done();
  530. } ) );
  531. } );
  532. } );
  533. describe( 'compileThemes', () => {
  534. it( 'returns a stream containing compiled CSS file', ( done ) => {
  535. const stream = require( 'stream' );
  536. let compiledThemePath;
  537. let compiledThemeCss;
  538. function fakeInputStream() {
  539. const files = [
  540. new Vinyl( {
  541. cwd: './',
  542. path: 'aaa/aaa/theme.scss',
  543. contents: new Buffer( '' )
  544. } ),
  545. new Vinyl( {
  546. cwd: './',
  547. path: 'zzz/ckeditor5-theme-quz/theme.scss',
  548. contents: new Buffer( '' )
  549. } ),
  550. new Vinyl( {
  551. cwd: './',
  552. path: 'C:\\win\\dows\\theme.scss',
  553. contents: new Buffer( '' )
  554. } )
  555. ];
  556. const fake = new stream.Readable( { objectMode: true } );
  557. fake._read = () => {
  558. fake.push( files.pop() || null );
  559. };
  560. return fake;
  561. }
  562. sandbox.stub( utils, 'getSassOptions', dataToRender => {
  563. return {
  564. data: dataToRender,
  565. outputStyle: 'expanded',
  566. importer: url => {
  567. return { file: url, contents: `/*! ${ url } */` };
  568. }
  569. };
  570. } );
  571. fakeInputStream()
  572. .pipe( utils.compileThemes( 'abc.css' ) )
  573. .pipe( through.obj( ( file, encoding, callback ) => {
  574. compiledThemePath = file.path;
  575. compiledThemeCss = file.contents;
  576. callback();
  577. }, () => {
  578. expect( compiledThemePath ).to.be.equal( 'abc.css' );
  579. expect( compiledThemeCss.toString() ).to.be.equal(
  580. // Note: Order matters. The first one should be ckeditor5-theme-* in order
  581. // to provide necessary dependencies (mixins, vars) for the following files.
  582. `/*! zzz/ckeditor5-theme-quz/theme.scss */
  583. /*! aaa/aaa/theme.scss */
  584. /*! C:\\win\\dows\\theme.scss */
  585. ` );
  586. done();
  587. } ) );
  588. } );
  589. } );
  590. describe( 'getSassOptions', () => {
  591. it( 'should return default options for SASS', () => {
  592. const options = utils.getSassOptions( 'foo' );
  593. expect( options ).to.have.property( 'data', 'foo' );
  594. expect( options ).to.have.property( 'sourceMap', true );
  595. expect( options ).to.have.property( 'sourceMapEmbed', true );
  596. expect( options ).to.have.property( 'outputStyle', 'expanded' );
  597. expect( options ).to.have.property( 'sourceComments', true );
  598. } );
  599. } );
  600. describe( 'parseArguments', () => {
  601. it( 'returns object with defaults', () => {
  602. const args = utils.parseArguments();
  603. expect( args.formats ).to.have.members( [ 'amd' ] );
  604. expect( args.watch ).to.be.equal( false );
  605. } );
  606. } );
  607. describe( 'getIconSpriteOptions', () => {
  608. it( 'returns object with defaults', () => {
  609. const options = utils.getIconSpriteOptions();
  610. expect( options ).to.have.all.keys( [ 'shape', 'svg', 'mode' ] );
  611. } );
  612. it( 'returns icon ids generator out of svg file names', () => {
  613. const options = utils.getIconSpriteOptions();
  614. expect( options.shape.id.generator( 'foo.svg' ) ).to.equal( 'ck-icon-foo' );
  615. expect( options.shape.id.generator( 'foo/bar/foo.svg' ) ).to.equal( 'ck-icon-foo' );
  616. expect( options.shape.id.generator( 'C:\\foo\\foo.svg' ) ).to.equal( 'ck-icon-foo' );
  617. } );
  618. it( 'returns configuration to output JavaScript sprite', () => {
  619. const options = utils.getIconSpriteOptions();
  620. expect( options.mode.symbol.render.js.dest ).to.equal( 'iconmanagermodel.js' );
  621. } );
  622. } );
  623. describe( 'getThemeFormatDestStreams', () => {
  624. it( 'returns array of streams for each format', () => {
  625. const streams = utils.getThemeFormatDestStreams( 'foo', [ 'a', 'b' ] );
  626. expect( streams ).to.be.an( 'array' );
  627. expect( streams ).to.have.length( 2 );
  628. } );
  629. } );
  630. describe( 'resolveModuleSource', () => {
  631. it( 'does not modify relative source paths', () => {
  632. const source = '../module';
  633. const resolved = utils.resolveModuleSource( source, '' );
  634. expect( resolved ).to.equal( source );
  635. } );
  636. it( 'resolves absolute source paths', () => {
  637. const source = '/ckeditor5/path/to/module.js';
  638. const file = path.join( process.cwd(), 'tests', 'module', 'module.js' );
  639. const resolved = utils.resolveModuleSource( source, file );
  640. expect( resolved ).to.equal( '../../ckeditor5/path/to/module.js' );
  641. } );
  642. } );
  643. } );