update.js 10 KB

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