@@ -10,6 +10,9 @@ import {
1010 __resetDistTagsCache ,
1111 checkForUpdate ,
1212 compareVersions ,
13+ isUnstampedVersion ,
14+ isUpdateAvailable ,
15+ resolveComparisonChannel ,
1316 resolveDistTags ,
1417 resolveUpdateChannel ,
1518} from "./update-check" ;
@@ -53,6 +56,73 @@ describe("resolveUpdateChannel", () => {
5356 } ) ;
5457} ) ;
5558
59+ describe ( "isUnstampedVersion" , ( ) => {
60+ it ( "flags 0.0.0, with or without a prerelease suffix" , ( ) => {
61+ expect ( isUnstampedVersion ( "0.0.0" ) ) . toBe ( true ) ;
62+ expect ( isUnstampedVersion ( "0.0.0-dev" ) ) . toBe ( true ) ;
63+ } ) ;
64+
65+ it ( "leaves any published version alone" , ( ) => {
66+ expect ( isUnstampedVersion ( "1.5.22" ) ) . toBe ( false ) ;
67+ expect ( isUnstampedVersion ( "0.0.1" ) ) . toBe ( false ) ;
68+ } ) ;
69+
70+ it ( "is false for unparseable input" , ( ) => {
71+ expect ( isUnstampedVersion ( "not-a-version" ) ) . toBe ( false ) ;
72+ } ) ;
73+ } ) ;
74+
75+ describe ( "resolveComparisonChannel" , ( ) => {
76+ it ( "suppresses unstamped build-time fallback versions" , ( ) => {
77+ expect ( resolveComparisonChannel ( "0.0.0" ) ) . toBeNull ( ) ;
78+ expect ( resolveComparisonChannel ( "0.0.0-dev" ) ) . toBeNull ( ) ;
79+ } ) ;
80+
81+ it ( "suppresses unparseable input" , ( ) => {
82+ expect ( resolveComparisonChannel ( "not-a-version" ) ) . toBeNull ( ) ;
83+ } ) ;
84+
85+ it ( "routes a release version to the latest tag" , ( ) => {
86+ expect ( resolveComparisonChannel ( "1.6.0" ) ) . toBe ( "latest" ) ;
87+ } ) ;
88+
89+ it ( "routes a beta prerelease to the beta tag" , ( ) => {
90+ expect ( resolveComparisonChannel ( "1.6.0-beta.1" ) ) . toBe ( "beta" ) ;
91+ } ) ;
92+
93+ it ( "suppresses prereleases with no matching dist-tag" , ( ) => {
94+ // rc, alpha, next, dev, ... — none of these publish a dist-tag, so
95+ // comparing against `latest` would nag forever.
96+ expect ( resolveComparisonChannel ( "1.6.0-rc.1" ) ) . toBeNull ( ) ;
97+ expect ( resolveComparisonChannel ( "1.6.0-alpha.1" ) ) . toBeNull ( ) ;
98+ expect ( resolveComparisonChannel ( "1.6.0-next.1" ) ) . toBeNull ( ) ;
99+ } ) ;
100+ } ) ;
101+
102+ describe ( "isUpdateAvailable" , ( ) => {
103+ it ( "is false with no current version" , ( ) => {
104+ expect ( isUpdateAvailable ( undefined , "1.6.0" ) ) . toBe ( false ) ;
105+ } ) ;
106+
107+ it ( "is false with no comparison channel" , ( ) => {
108+ expect ( isUpdateAvailable ( "0.0.0-dev" , "1.6.0" ) ) . toBe ( false ) ;
109+ expect ( isUpdateAvailable ( "1.6.0-rc.1" , "1.6.0" ) ) . toBe ( false ) ;
110+ } ) ;
111+
112+ it ( "is false with no published tag" , ( ) => {
113+ expect ( isUpdateAvailable ( "1.5.22" , null ) ) . toBe ( false ) ;
114+ } ) ;
115+
116+ it ( "is false when already current" , ( ) => {
117+ expect ( isUpdateAvailable ( "1.6.0" , "1.6.0" ) ) . toBe ( false ) ;
118+ } ) ;
119+
120+ it ( "is true when a newer version is published on the matching channel" , ( ) => {
121+ expect ( isUpdateAvailable ( "1.6.0" , "1.6.1" ) ) . toBe ( true ) ;
122+ expect ( isUpdateAvailable ( "1.6.0-beta.1" , "1.6.0-beta.2" ) ) . toBe ( true ) ;
123+ } ) ;
124+ } ) ;
125+
56126describe ( "resolveDistTags" , ( ) => {
57127 it ( "returns nothing when the check is disabled" , async ( ) => {
58128 const tags = await resolveDistTags ( {
@@ -126,6 +196,14 @@ describe("checkForUpdate", () => {
126196 expect ( status . updateAvailable ) . toBe ( false ) ;
127197 } ) ;
128198
199+ it ( "flags a patch release on the latest channel" , async ( ) => {
200+ const status = await checkForUpdate ( "1.6.0" , {
201+ env : { EXECUTOR_NPM_DIST_TAGS : JSON . stringify ( { latest : "1.6.1" } ) } ,
202+ } ) ;
203+ expect ( status . updateAvailable ) . toBe ( true ) ;
204+ expect ( status . latestVersion ) . toBe ( "1.6.1" ) ;
205+ } ) ;
206+
129207 it ( "compares a beta build against the beta tag" , async ( ) => {
130208 const status = await checkForUpdate ( "1.6.0-beta.1" , {
131209 env : { EXECUTOR_NPM_DIST_TAGS : JSON . stringify ( { latest : "1.5.22" , beta : "1.6.0-beta.2" } ) } ,
@@ -136,10 +214,33 @@ describe("checkForUpdate", () => {
136214 expect ( status . command ) . toBe ( "npm i -g executor@beta" ) ;
137215 } ) ;
138216
139- it ( "treats the dev build as upgradeable to any release" , async ( ) => {
217+ it ( "stays quiet on an unstamped dev build" , async ( ) => {
218+ // 0.0.0-dev is the build-time fallback, not a real release. It must never
219+ // claim an update is available, and — because there is no dist-tag it
220+ // could legitimately compare against — must not even hit the registry.
140221 const status = await checkForUpdate ( "0.0.0-dev" , {
141222 env : { EXECUTOR_FORCE_LATEST_VERSION : "1.5.22" } ,
223+ fetchImpl : fetchThatFails ( ) ,
142224 } ) ;
143- expect ( status . updateAvailable ) . toBe ( true ) ;
225+ expect ( status . updateAvailable ) . toBe ( false ) ;
226+ expect ( status . latestVersion ) . toBeNull ( ) ;
227+ } ) ;
228+
229+ it ( "stays quiet on the desktop's unstamped fallback (plain 0.0.0)" , async ( ) => {
230+ const status = await checkForUpdate ( "0.0.0" , {
231+ env : { EXECUTOR_FORCE_LATEST_VERSION : "1.5.22" } ,
232+ fetchImpl : fetchThatFails ( ) ,
233+ } ) ;
234+ expect ( status . updateAvailable ) . toBe ( false ) ;
235+ expect ( status . latestVersion ) . toBeNull ( ) ;
236+ } ) ;
237+
238+ it ( "stays quiet on a prerelease channel with no matching dist-tag" , async ( ) => {
239+ const status = await checkForUpdate ( "1.6.0-rc.1" , {
240+ env : { EXECUTOR_NPM_DIST_TAGS : JSON . stringify ( { latest : "1.6.0" } ) } ,
241+ fetchImpl : fetchThatFails ( ) ,
242+ } ) ;
243+ expect ( status . updateAvailable ) . toBe ( false ) ;
244+ expect ( status . latestVersion ) . toBeNull ( ) ;
144245 } ) ;
145246} ) ;
0 commit comments