156 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			156 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
|  | /** | ||
|  |  * @license | ||
|  |  * Copyright Google Inc. All Rights Reserved. | ||
|  |  * | ||
|  |  * Use of this source code is governed by an MIT-style license that can be | ||
|  |  * found in the LICENSE file at https://angular.io/license
 | ||
|  |  */ | ||
|  | import {AbsoluteFsPath, FileSystem, absoluteFrom, getFileSystem} from '../../../src/ngtsc/file_system'; | ||
|  | import {runInEachFileSystem} from '../../../src/ngtsc/file_system/testing'; | ||
|  | import {loadTestFiles} from '../../../test/helpers'; | ||
|  | import {DirectPackageJsonUpdater, PackageJsonUpdater} from '../../src/writing/package_json_updater'; | ||
|  | 
 | ||
|  | runInEachFileSystem(() => { | ||
|  |   describe('DirectPackageJsonUpdater', () => { | ||
|  |     let _: typeof absoluteFrom; | ||
|  |     let fs: FileSystem; | ||
|  |     let updater: PackageJsonUpdater; | ||
|  | 
 | ||
|  |     // Helpers
 | ||
|  |     const readJson = (path: AbsoluteFsPath) => JSON.parse(fs.readFile(path)); | ||
|  | 
 | ||
|  |     beforeEach(() => { | ||
|  |       _ = absoluteFrom; | ||
|  |       fs = getFileSystem(); | ||
|  |       updater = new DirectPackageJsonUpdater(fs); | ||
|  |     }); | ||
|  | 
 | ||
|  |     it('should update a `package.json` file on disk', () => { | ||
|  |       const jsonPath = _('/foo/package.json'); | ||
|  |       loadTestFiles([ | ||
|  |         {name: jsonPath, contents: '{"foo": true, "bar": {"baz": "OK"}}'}, | ||
|  |       ]); | ||
|  | 
 | ||
|  |       const update = updater.createUpdate().addChange(['foo'], false).addChange(['bar', 'baz'], 42); | ||
|  | 
 | ||
|  |       // Not updated yet.
 | ||
|  |       expect(readJson(jsonPath)).toEqual({ | ||
|  |         foo: true, | ||
|  |         bar: {baz: 'OK'}, | ||
|  |       }); | ||
|  | 
 | ||
|  |       update.writeChanges(jsonPath); | ||
|  | 
 | ||
|  |       // Updated now.
 | ||
|  |       expect(readJson(jsonPath)).toEqual({ | ||
|  |         foo: false, | ||
|  |         bar: {baz: 42}, | ||
|  |       }); | ||
|  |     }); | ||
|  | 
 | ||
|  |     it('should update an in-memory representation (if provided)', () => { | ||
|  |       const jsonPath = _('/foo/package.json'); | ||
|  |       loadTestFiles([ | ||
|  |         {name: jsonPath, contents: '{"foo": true, "bar": {"baz": "OK"}}'}, | ||
|  |       ]); | ||
|  | 
 | ||
|  |       const pkg = readJson(jsonPath); | ||
|  |       const update = updater.createUpdate().addChange(['foo'], false).addChange(['bar', 'baz'], 42); | ||
|  | 
 | ||
|  |       // Not updated yet.
 | ||
|  |       expect(pkg).toEqual({ | ||
|  |         foo: true, | ||
|  |         bar: {baz: 'OK'}, | ||
|  |       }); | ||
|  | 
 | ||
|  |       update.writeChanges(jsonPath, pkg); | ||
|  | 
 | ||
|  |       // Updated now.
 | ||
|  |       expect(pkg).toEqual({ | ||
|  |         foo: false, | ||
|  |         bar: {baz: 42}, | ||
|  |       }); | ||
|  |     }); | ||
|  | 
 | ||
|  |     it('should create the `package.json` file, if it does not exist', () => { | ||
|  |       const jsonPath = _('/foo/package.json'); | ||
|  |       expect(fs.exists(jsonPath)).toBe(false); | ||
|  | 
 | ||
|  |       updater.createUpdate() | ||
|  |           .addChange(['foo'], false) | ||
|  |           .addChange(['bar', 'baz'], 42) | ||
|  |           .writeChanges(jsonPath); | ||
|  | 
 | ||
|  |       expect(fs.exists(jsonPath)).toBe(true); | ||
|  |       expect(readJson(jsonPath)).toEqual({ | ||
|  |         foo: false, | ||
|  |         bar: {baz: 42}, | ||
|  |       }); | ||
|  |     }); | ||
|  | 
 | ||
|  |     it('should create any missing ancestor objects', () => { | ||
|  |       const jsonPath = _('/foo/package.json'); | ||
|  |       loadTestFiles([ | ||
|  |         {name: jsonPath, contents: '{"foo": {}}'}, | ||
|  |       ]); | ||
|  | 
 | ||
|  |       const pkg = readJson(jsonPath); | ||
|  |       updater.createUpdate() | ||
|  |           .addChange(['foo', 'bar', 'baz', 'qux'], 'updated') | ||
|  |           .writeChanges(jsonPath, pkg); | ||
|  | 
 | ||
|  |       expect(readJson(jsonPath)).toEqual(pkg); | ||
|  |       expect(pkg).toEqual({ | ||
|  |         foo: { | ||
|  |           bar: { | ||
|  |             baz: { | ||
|  |               qux: 'updated', | ||
|  |             }, | ||
|  |           }, | ||
|  |         }, | ||
|  |       }); | ||
|  |     }); | ||
|  | 
 | ||
|  |     it('should throw, if no changes have been recorded', () => { | ||
|  |       const jsonPath = _('/foo/package.json'); | ||
|  | 
 | ||
|  |       expect(() => updater.createUpdate().writeChanges(jsonPath)) | ||
|  |           .toThrowError(`No changes to write to '${jsonPath}'.`); | ||
|  |     }); | ||
|  | 
 | ||
|  |     it('should throw, if a property-path is empty', () => { | ||
|  |       const jsonPath = _('/foo/package.json'); | ||
|  | 
 | ||
|  |       expect(() => updater.createUpdate().addChange([], 'missing').writeChanges(jsonPath)) | ||
|  |           .toThrowError(`Missing property path for writing value to '${jsonPath}'.`); | ||
|  |     }); | ||
|  | 
 | ||
|  |     it('should throw, if a property-path points to a non-object intermediate value', () => { | ||
|  |       const jsonPath = _('/foo/package.json'); | ||
|  |       loadTestFiles([ | ||
|  |         {name: jsonPath, contents: '{"foo": null, "bar": 42, "baz": {"qux": []}}'}, | ||
|  |       ]); | ||
|  | 
 | ||
|  |       const writeToProp = (propPath: string[]) => | ||
|  |           updater.createUpdate().addChange(propPath, 'updated').writeChanges(jsonPath); | ||
|  | 
 | ||
|  |       expect(() => writeToProp(['foo', 'child'])) | ||
|  |           .toThrowError('Property path \'foo.child\' does not point to an object.'); | ||
|  |       expect(() => writeToProp(['bar', 'child'])) | ||
|  |           .toThrowError('Property path \'bar.child\' does not point to an object.'); | ||
|  |       expect(() => writeToProp(['baz', 'qux', 'child'])) | ||
|  |           .toThrowError('Property path \'baz.qux.child\' does not point to an object.'); | ||
|  |     }); | ||
|  | 
 | ||
|  |     it('should throw, if trying to re-apply an already applied update', () => { | ||
|  |       const update = updater.createUpdate().addChange(['foo'], 'updated'); | ||
|  | 
 | ||
|  |       expect(() => update.writeChanges(_('/foo/package.json'))).not.toThrow(); | ||
|  |       expect(() => update.writeChanges(_('/foo/package.json'))) | ||
|  |           .toThrowError('Trying to apply a `PackageJsonUpdate` that has already been applied.'); | ||
|  |       expect(() => update.writeChanges(_('/bar/package.json'))) | ||
|  |           .toThrowError('Trying to apply a `PackageJsonUpdate` that has already been applied.'); | ||
|  |     }); | ||
|  |   }); | ||
|  | }); |