utils.js 21 KB

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