update.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /**
  2. * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /* global describe, it, beforeEach, afterEach */
  6. 'use strict';
  7. require( '../../tasks/dev/tasks' )( {} );
  8. const sinon = require( 'sinon' );
  9. const tools = require( '../../tasks/dev/utils/tools' );
  10. const git = require( '../../tasks/dev/utils/git' );
  11. const path = require( 'path' );
  12. const chai = require( 'chai' );
  13. const expect = chai.expect;
  14. const gulp = require( 'gulp' );
  15. describe( 'dev-update', () => {
  16. const updateTask = require( '../../tasks/dev/tasks/update' );
  17. const ckeditor5Path = 'path/to/ckeditor5';
  18. const workspaceRoot = '..';
  19. const workspaceAbsolutePath = path.join( ckeditor5Path, workspaceRoot );
  20. const spies = {};
  21. beforeEach( () => {
  22. spies.getDependencies = sinon.spy( tools, 'getCKEditorDependencies' );
  23. spies.checkout = sinon.stub( git, 'checkout' );
  24. spies.pull = sinon.stub( git, 'pull' );
  25. spies.fetchAll = sinon.stub( git, 'fetchAll' );
  26. spies.npmUpdate = sinon.stub( tools, 'npmUpdate' );
  27. spies.linkDirectories = sinon.stub( tools, 'linkDirectories' );
  28. spies.removeSymlink = sinon.stub( tools, 'removeSymlink' );
  29. } );
  30. afterEach( () => {
  31. Object.keys( spies ).forEach( ( spy ) => spies[ spy ].restore() );
  32. } );
  33. it( 'should update dev repositories', () => {
  34. const dirs = [ 'ckeditor5-core', 'ckeditor5-devtest' ];
  35. const installTask = sinon.spy();
  36. spies.getDirectories = sinon.stub( tools, 'getCKE5Directories' ).returns( dirs );
  37. spies.getCKE5Symlinks = sinon.stub( tools, 'getCKE5Symlinks' ).returns( [] );
  38. const json = {
  39. dependencies: {
  40. 'ckeditor5-core': 'ckeditor/ckeditor5-core',
  41. 'ckeditor5-devtest': 'ckeditor/ckeditor5-devtest#new-branch',
  42. 'other-plugin': '1.2.3'
  43. }
  44. };
  45. updateTask( installTask, ckeditor5Path, json, workspaceRoot, true );
  46. const repoPath1 = path.join( workspaceAbsolutePath, dirs[ 0 ] );
  47. const repoPath2 = path.join( workspaceAbsolutePath, dirs[ 1 ] );
  48. sinon.assert.calledThrice( spies.fetchAll );
  49. sinon.assert.calledWithExactly( spies.fetchAll.firstCall, ckeditor5Path );
  50. sinon.assert.calledWithExactly( spies.fetchAll.secondCall, repoPath1 );
  51. sinon.assert.calledWithExactly( spies.fetchAll.thirdCall, repoPath2 );
  52. sinon.assert.calledTwice( spies.checkout );
  53. sinon.assert.calledWithExactly( spies.checkout.firstCall, repoPath1, 'master' );
  54. sinon.assert.calledWithExactly( spies.checkout.secondCall, repoPath2, 'new-branch' );
  55. sinon.assert.calledTwice( spies.pull );
  56. sinon.assert.calledWithExactly( spies.pull.firstCall, repoPath1, 'master' );
  57. sinon.assert.calledWithExactly( spies.pull.secondCall, repoPath2, 'new-branch' );
  58. sinon.assert.calledThrice( spies.npmUpdate );
  59. sinon.assert.calledWithExactly( spies.npmUpdate.firstCall, path.join( workspaceAbsolutePath, dirs[ 0 ] ) );
  60. sinon.assert.calledWithExactly( spies.npmUpdate.secondCall, path.join( workspaceAbsolutePath, dirs[ 1 ] ) );
  61. sinon.assert.calledWithExactly( spies.npmUpdate.thirdCall, ckeditor5Path );
  62. sinon.assert.calledOnce( spies.getCKE5Symlinks );
  63. sinon.assert.notCalled( spies.removeSymlink );
  64. sinon.assert.notCalled( installTask );
  65. } );
  66. it( 'should install missing dependencies', () => {
  67. const dirs = [ 'ckeditor5-core', 'ckeditor5-devtest' ];
  68. const installTask = sinon.spy();
  69. spies.getDirectories = sinon.stub( tools, 'getCKE5Directories' ).returns( dirs );
  70. spies.getCKE5Symlinks = sinon.stub( tools, 'getCKE5Symlinks' ).returns( [] );
  71. const json = {
  72. dependencies: {
  73. 'ckeditor5-core': 'ckeditor/ckeditor5-core',
  74. 'ckeditor5-devtest': 'ckeditor/ckeditor5-devtest#new-branch',
  75. 'ckeditor5-ui': 'ckeditor/ckeditor5-ui',
  76. 'other-plugin': '1.2.3'
  77. }
  78. };
  79. updateTask( installTask, ckeditor5Path, json, workspaceRoot, true );
  80. const repoPath1 = path.join( workspaceAbsolutePath, dirs[ 0 ] );
  81. const repoPath2 = path.join( workspaceAbsolutePath, dirs[ 1 ] );
  82. sinon.assert.calledThrice( spies.fetchAll );
  83. sinon.assert.calledWithExactly( spies.fetchAll.firstCall, ckeditor5Path );
  84. sinon.assert.calledWithExactly( spies.fetchAll.secondCall, repoPath1 );
  85. sinon.assert.calledWithExactly( spies.fetchAll.thirdCall, repoPath2 );
  86. sinon.assert.calledTwice( spies.checkout );
  87. sinon.assert.calledWithExactly( spies.checkout.firstCall, repoPath1, 'master' );
  88. sinon.assert.calledWithExactly( spies.checkout.secondCall, repoPath2, 'new-branch' );
  89. sinon.assert.calledTwice( spies.pull );
  90. sinon.assert.calledWithExactly( spies.pull.firstCall, repoPath1, 'master' );
  91. sinon.assert.calledWithExactly( spies.pull.secondCall, repoPath2, 'new-branch' );
  92. sinon.assert.calledThrice( spies.npmUpdate );
  93. sinon.assert.calledWithExactly( spies.npmUpdate.firstCall, path.join( workspaceAbsolutePath, dirs[ 0 ] ) );
  94. sinon.assert.calledWithExactly( spies.npmUpdate.secondCall, path.join( workspaceAbsolutePath, dirs[ 1 ] ) );
  95. sinon.assert.calledWithExactly( spies.npmUpdate.thirdCall, ckeditor5Path );
  96. sinon.assert.calledOnce( installTask );
  97. sinon.assert.calledWithExactly( installTask, ckeditor5Path, workspaceRoot, 'ckeditor/ckeditor5-ui' );
  98. sinon.assert.calledOnce( spies.getCKE5Symlinks );
  99. sinon.assert.notCalled( spies.removeSymlink );
  100. } );
  101. it( 'should remove symlinks that are not needed', () => {
  102. const dirs = [ 'ckeditor5-core', 'ckeditor5-devtest' ];
  103. const installTask = sinon.spy();
  104. spies.getDirectories = sinon.stub( tools, 'getCKE5Directories' ).returns( dirs );
  105. spies.getCKE5Symlinks = sinon.stub( tools, 'getCKE5Symlinks' ).returns( [ 'ckeditor5-unused' ] );
  106. const json = {
  107. dependencies: {
  108. 'ckeditor5-core': 'ckeditor/ckeditor5-core',
  109. 'ckeditor5-devtest': 'ckeditor/ckeditor5-devtest#new-branch',
  110. 'other-plugin': '1.2.3'
  111. }
  112. };
  113. updateTask( installTask, ckeditor5Path, json, workspaceRoot, true );
  114. const repoPath1 = path.join( workspaceAbsolutePath, dirs[ 0 ] );
  115. const repoPath2 = path.join( workspaceAbsolutePath, dirs[ 1 ] );
  116. sinon.assert.calledThrice( spies.fetchAll );
  117. sinon.assert.calledWithExactly( spies.fetchAll.firstCall, ckeditor5Path );
  118. sinon.assert.calledWithExactly( spies.fetchAll.secondCall, repoPath1 );
  119. sinon.assert.calledWithExactly( spies.fetchAll.thirdCall, repoPath2 );
  120. sinon.assert.calledTwice( spies.checkout );
  121. sinon.assert.calledWithExactly( spies.checkout.firstCall, repoPath1, 'master' );
  122. sinon.assert.calledWithExactly( spies.checkout.secondCall, repoPath2, 'new-branch' );
  123. sinon.assert.calledTwice( spies.pull );
  124. sinon.assert.calledWithExactly( spies.pull.firstCall, repoPath1, 'master' );
  125. sinon.assert.calledWithExactly( spies.pull.secondCall, repoPath2, 'new-branch' );
  126. sinon.assert.calledThrice( spies.npmUpdate );
  127. sinon.assert.calledWithExactly( spies.npmUpdate.firstCall, path.join( workspaceAbsolutePath, dirs[ 0 ] ) );
  128. sinon.assert.calledWithExactly( spies.npmUpdate.secondCall, path.join( workspaceAbsolutePath, dirs[ 1 ] ) );
  129. sinon.assert.calledWithExactly( spies.npmUpdate.thirdCall, ckeditor5Path );
  130. sinon.assert.calledOnce( spies.getCKE5Symlinks );
  131. sinon.assert.notCalled( installTask );
  132. sinon.assert.calledOnce( spies.removeSymlink );
  133. sinon.assert.calledWithExactly( spies.removeSymlink, path.join( ckeditor5Path, 'node_modules', 'ckeditor5-unused' ) );
  134. } );
  135. it( 'should catch linking errors', () => {
  136. const log = require( '../../tasks/dev/utils/log' );
  137. const dirs = [ 'ckeditor5-core', 'ckeditor5-devtest' ];
  138. const installTask = sinon.spy();
  139. const outSpy = sinon.spy();
  140. const errSpy = sinon.spy();
  141. spies.getDirectories = sinon.stub( tools, 'getCKE5Directories' ).returns( dirs );
  142. spies.getCKE5Symlinks = sinon.stub( tools, 'getCKE5Symlinks' ).returns( [ 'ckeditor5-unused' ] );
  143. spies.linkDirectories.throws();
  144. log.configure( outSpy, errSpy );
  145. const json = {
  146. dependencies: {
  147. 'ckeditor5-core': 'ckeditor/ckeditor5-core',
  148. 'ckeditor5-devtest': 'ckeditor/ckeditor5-devtest#new-branch',
  149. 'other-plugin': '1.2.3'
  150. }
  151. };
  152. updateTask( installTask, ckeditor5Path, json, workspaceRoot, false );
  153. const repoPath1 = path.join( workspaceAbsolutePath, dirs[ 0 ] );
  154. const repoPath2 = path.join( workspaceAbsolutePath, dirs[ 1 ] );
  155. sinon.assert.calledThrice( spies.fetchAll );
  156. sinon.assert.calledWithExactly( spies.fetchAll.firstCall, ckeditor5Path );
  157. sinon.assert.calledWithExactly( spies.fetchAll.secondCall, repoPath1 );
  158. sinon.assert.calledWithExactly( spies.fetchAll.thirdCall, repoPath2 );
  159. sinon.assert.calledTwice( spies.checkout );
  160. sinon.assert.calledWithExactly( spies.checkout.firstCall, repoPath1, 'master' );
  161. sinon.assert.calledWithExactly( spies.checkout.secondCall, repoPath2, 'new-branch' );
  162. sinon.assert.calledTwice( spies.pull );
  163. sinon.assert.calledWithExactly( spies.pull.firstCall, repoPath1, 'master' );
  164. sinon.assert.calledWithExactly( spies.pull.secondCall, repoPath2, 'new-branch' );
  165. sinon.assert.notCalled( spies.npmUpdate );
  166. sinon.assert.calledOnce( spies.getCKE5Symlinks );
  167. sinon.assert.notCalled( installTask );
  168. sinon.assert.calledOnce( spies.removeSymlink );
  169. sinon.assert.calledWithExactly( spies.removeSymlink, path.join( ckeditor5Path, 'node_modules', 'ckeditor5-unused' ) );
  170. sinon.assert.calledTwice( errSpy );
  171. } );
  172. it( 'should skip updating if no dependencies found and fetch only main repository', () => {
  173. spies.getDependencies.restore();
  174. spies.getDependencies = sinon.stub( tools, 'getCKEditorDependencies' ).returns( null );
  175. const dirs = [ 'ckeditor5-core', 'ckeditor5-devtest' ];
  176. const installTask = sinon.spy();
  177. spies.getDirectories = sinon.stub( tools, 'getCKE5Directories' ).returns( dirs );
  178. spies.getCKE5Symlinks = sinon.stub( tools, 'getCKE5Symlinks' ).returns( [] );
  179. const json = {
  180. dependencies: {
  181. 'ckeditor5-core': 'ckeditor/ckeditor5-core',
  182. 'ckeditor5-devtest': 'ckeditor/ckeditor5-devtest#new-branch',
  183. 'other-plugin': '1.2.3'
  184. }
  185. };
  186. updateTask( installTask, ckeditor5Path, json, workspaceRoot, false );
  187. sinon.assert.calledOnce( spies.fetchAll );
  188. sinon.assert.calledWithExactly( spies.fetchAll.firstCall, ckeditor5Path );
  189. sinon.assert.notCalled( spies.checkout );
  190. sinon.assert.notCalled( spies.pull );
  191. sinon.assert.notCalled( spies.npmUpdate );
  192. sinon.assert.calledOnce( spies.getCKE5Symlinks );
  193. sinon.assert.notCalled( installTask );
  194. sinon.assert.notCalled( spies.removeSymlink );
  195. } );
  196. } );
  197. describe( 'gulp task update', () => {
  198. const tasks = gulp.tasks;
  199. it( 'should be available', () => {
  200. expect( tasks ).to.have.property( 'update' );
  201. expect( tasks.update.fn ).to.be.a( 'function' );
  202. } );
  203. it( 'should have an alias', () => {
  204. expect( tasks ).to.have.property( 'pull' );
  205. expect( tasks.pull.fn ).to.be.a( 'function' );
  206. expect( tasks.pull.fn ).to.equal( tasks.update.fn );
  207. } );
  208. } );