11import { describe , expect , it , afterEach , jest } from '@jest/globals' ;
2+ import fs from 'fs' ;
23import { defaultRemoteBranchName } from '../__fixtures__/gitDefaults' ;
34import { generateChangeFiles } from '../__fixtures__/changeFiles' ;
45import { initMockLogs } from '../__fixtures__/mockLogs' ;
@@ -9,6 +10,7 @@ import { publish } from '../commands/publish';
910import { getDefaultOptions } from '../options/getDefaultOptions' ;
1011import type { BeachballOptions } from '../types/BeachballOptions' ;
1112import { initNpmMock } from '../__fixtures__/mockNpm' ;
13+ import { removeTempDir , tmpdir } from '../__fixtures__/tmpdir' ;
1214
1315// Spawning actual npm to run commands against a fake registry is extremely slow, so mock it for
1416// this test (packagePublish covers the more complete npm registry scenario).
@@ -22,11 +24,12 @@ describe('publish command (registry)', () => {
2224
2325 let repositoryFactory : RepositoryFactory | undefined ;
2426 let repo : Repository | undefined ;
27+ let packToPath : string | undefined ;
2528
2629 // show error logs for these tests
2730 const logs = initMockLogs ( { alsoLog : [ 'error' ] } ) ;
2831
29- function getOptions ( ) : BeachballOptions {
32+ function getOptions ( options ?: Partial < BeachballOptions > ) : BeachballOptions {
3033 return {
3134 ...getDefaultOptions ( ) ,
3235 branch : defaultRemoteBranchName ,
@@ -41,13 +44,16 @@ describe('publish command (registry)', () => {
4144 tag : 'latest' ,
4245 yes : true ,
4346 access : 'public' ,
47+ ...options ,
4448 } ;
4549 }
4650
4751 afterEach ( ( ) => {
4852 repositoryFactory ?. cleanUp ( ) ;
4953 repositoryFactory = undefined ;
5054 repo = undefined ;
55+ packToPath && removeTempDir ( packToPath ) ;
56+ packToPath = undefined ;
5157 } ) ;
5258
5359 it ( 'publishes single package' , async ( ) => {
@@ -66,6 +72,21 @@ describe('publish command (registry)', () => {
6672 expect ( publishedPackage . versions ) . toHaveLength ( 1 ) ;
6773 } ) ;
6874
75+ it ( 'packs single package' , async ( ) => {
76+ repositoryFactory = new RepositoryFactory ( 'single' ) ;
77+ repo = repositoryFactory . cloneRepository ( ) ;
78+ packToPath = tmpdir ( { prefix : 'beachball-pack-' } ) ;
79+
80+ const options = getOptions ( { packToPath } ) ;
81+ generateChangeFiles ( [ 'foo' ] , options ) ;
82+ repo . push ( ) ;
83+
84+ await publish ( options ) ;
85+
86+ expect ( fs . readdirSync ( packToPath ) ) . toEqual ( [ '1-foo-1.1.0.tgz' ] ) ;
87+ await npmShow ( 'foo' , { shouldFail : true } ) ;
88+ } ) ;
89+
6990 it ( 'publishes in monorepo with mixed public and private packages' , async ( ) => {
7091 repositoryFactory = new RepositoryFactory ( {
7192 folders : {
@@ -115,6 +136,34 @@ describe('publish command (registry)', () => {
115136 expect ( showBar [ 'dist-tags' ] . latest ) . toEqual ( '1.1.0' ) ;
116137 } ) ;
117138
139+ it ( 'packs many packages' , async ( ) => {
140+ const packageNames = Array . from ( { length : 11 } , ( _ , i ) => `pkg-${ i + 1 } ` ) ;
141+ repositoryFactory = new RepositoryFactory ( {
142+ folders : {
143+ packages : Object . fromEntries (
144+ packageNames . map ( ( name , i ) => [
145+ name ,
146+ // Each package depends on the next one, so they must be published in reverse alphabetical order
147+ { version : '1.0.0' , dependencies : { [ packageNames [ i + 1 ] || 'other' ] : '^1.0.0' } } ,
148+ ] )
149+ ) ,
150+ } ,
151+ } ) ;
152+ repo = repositoryFactory . cloneRepository ( ) ;
153+ packToPath = tmpdir ( { prefix : 'beachball-pack-' } ) ;
154+
155+ const options = getOptions ( { packToPath, groupChanges : true } ) ;
156+ generateChangeFiles ( packageNames , options ) ;
157+ repo . push ( ) ;
158+
159+ await publish ( options ) ;
160+
161+ expect ( fs . readdirSync ( packToPath ) . sort ( ) ) . toEqual (
162+ [ ...packageNames ] . reverse ( ) . map ( ( name , i ) => `${ String ( i + 1 ) . padStart ( 2 , '0' ) } -${ name } -1.1.0.tgz` )
163+ ) ;
164+ await npmShow ( 'pkg-1' , { shouldFail : true } ) ;
165+ } ) ;
166+
118167 it ( 'succeeds even with a non-existent package listed in a change file' , async ( ) => {
119168 repositoryFactory = new RepositoryFactory ( {
120169 folders : {
0 commit comments