8
0

amd.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /**
  2. * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /* global require */
  6. 'use strict';
  7. bender.tools.createSinonSandbox();
  8. describe( 'bender.amd', () => {
  9. const getModulePath = bender.amd.getModulePath;
  10. describe( 'getModulePath()', () => {
  11. // Thanks to this we'll check whether all paths are relative to ckeditor.js path.
  12. const basePath = getModulePath( 'ckeditor' ).replace( /\/ckeditor\.js$/, '/' );
  13. it( 'generates path for the main file', () => {
  14. const path = getModulePath( 'ckeditor' );
  15. expect( path ).to.match( /\/ckeditor.js$/, 'ends with /ckeditor.js' );
  16. expect( path ).to.match( /^\//, 'is absolute' );
  17. } );
  18. it( 'generates path for modules within ckeditor5 package', () => {
  19. const path = getModulePath( 'ckeditor5/foo' );
  20. expect( path ).to.equal( basePath + 'ckeditor5/foo.js' );
  21. } );
  22. it( 'generates path for modules within the core package', () => {
  23. const path = getModulePath( 'core/ui/controller' );
  24. expect( path ).to.equal( basePath + 'ckeditor5-core/ui/controller.js' );
  25. } );
  26. it( 'generates path for modules within some package', () => {
  27. const path = getModulePath( 'some/ba' );
  28. expect( path ).to.equal( basePath + 'ckeditor5-some/ba.js' );
  29. } );
  30. it( 'generates path from simplified feature name', () => {
  31. const path = getModulePath( 'foo' );
  32. expect( path ).to.equal( basePath + 'ckeditor5-foo/foo.js' );
  33. } );
  34. } );
  35. describe( 'define()', () => {
  36. it( 'defines a module by using global define()', () => {
  37. const spy = bender.sinon.spy( window, 'define' );
  38. const expectedDeps = [ 'exports' ].concat( [ 'bar', 'ckeditor' ].map( getModulePath ) );
  39. bender.amd.define( 'test1', [ 'bar', 'ckeditor' ], () => {} );
  40. expect( spy.calledOnce ).to.be.true;
  41. expect( spy.args[ 0 ][ 0 ] ).to.equal( getModulePath( 'test1' ) );
  42. expect( spy.args[ 0 ][ 1 ] ).to.deep.equal( expectedDeps );
  43. } );
  44. it( 'maps body args and returned value', () => {
  45. const spy = bender.sinon.spy( window, 'define' );
  46. const bodySpy = sinon.spy( () => 'ret' );
  47. bender.amd.define( 'test2', [ 'bar', 'ckeditor' ], bodySpy );
  48. const realBody = spy.args[ 0 ][ 2 ];
  49. const exportsObj = {};
  50. expect( realBody ).to.be.a( 'function' );
  51. realBody( exportsObj, { default: 'arg' } );
  52. expect( exportsObj ).to.have.property( 'default', 'ret', 'it wraps the ret value with an ES6 module obj' );
  53. expect( bodySpy.calledOnce ).to.be.true;
  54. expect( bodySpy.args[ 0 ][ 0 ] ).to.equal( 'arg', 'it unwraps the args' );
  55. } );
  56. it( 'works with module name and body', () => {
  57. const spy = bender.sinon.spy( window, 'define' );
  58. bender.amd.define( 'test1', () => {} );
  59. expect( spy.calledOnce ).to.be.true;
  60. expect( spy.args[ 0 ][ 0 ] ).to.equal( getModulePath( 'test1' ) );
  61. expect( spy.args[ 0 ][ 1 ] ).to.deep.equal( [ 'exports' ] );
  62. expect( spy.args[ 0 ][ 2 ] ).to.be.a( 'function' );
  63. } );
  64. // Note: this test only checks whether Require.JS doesn't totally fail when creating a circular dependency.
  65. // The value of dependencies are not available anyway inside the bender.amd.define() callbacks because
  66. // we lose the late-binding by immediately mapping modules to their default exports.
  67. it( 'works with circular dependencies', ( done ) => {
  68. bender.amd.define( 'test-circular-a', [ 'test-circular-b' ], () => {
  69. return 'a';
  70. } );
  71. bender.amd.define( 'test-circular-b', [ 'test-circular-a' ], () => {
  72. return 'b';
  73. } );
  74. require( [ 'test-circular-a', 'test-circular-b' ].map( bender.amd.getModulePath ), ( a, b ) => {
  75. expect( a ).to.have.property( 'default', 'a' );
  76. expect( b ).to.have.property( 'default', 'b' );
  77. done();
  78. } );
  79. } );
  80. } );
  81. describe( 'require', () => {
  82. it( 'blocks Bender and loads modules through global require()', () => {
  83. let requireCb;
  84. const deferCbSpy = sinon.spy();
  85. bender.sinon.stub( bender, 'defer', () => deferCbSpy );
  86. bender.sinon.stub( window, 'require', ( deps, cb ) => {
  87. requireCb = cb;
  88. } );
  89. const modules = bender.amd.require( 'foo', 'bar' );
  90. expect( deferCbSpy.called ).to.be.false;
  91. requireCb( { default: 1 }, { default: 2 } );
  92. expect( deferCbSpy.calledOnce ).to.be.true;
  93. expect( modules ).to.have.property( 'foo', 1 );
  94. expect( modules ).to.have.property( 'bar', 2 );
  95. } );
  96. } );
  97. } );