8
0

utils.js 21 KB

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