-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve version parsing - parse Xcode version from version plist (#10)
* rework xcode version retrieving * debug logs * fix version parsing * rebuild task * more debug * more debug * Update test.yml * improve logging * Update test.yml
- Loading branch information
1 parent
cfeae3d
commit dfa1339
Showing
10 changed files
with
315 additions
and
200 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>BuildAliasOf</key> | ||
<string>IDEFrameworks</string> | ||
<key>BuildVersion</key> | ||
<string>4</string> | ||
<key>CFBundleShortVersionString</key> | ||
<string>12.0.1</string> | ||
<key>CFBundleVersion</key> | ||
<string>17220</string> | ||
<key>ProductBuildVersion</key> | ||
<string>12A7300</string> | ||
<key>ProjectName</key> | ||
<string>IDEFrameworks</string> | ||
<key>SourceVersion</key> | ||
<string>17220000000000000</string> | ||
</dict> | ||
</plist> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,173 @@ | ||
import * as path from "path"; | ||
import { getXcodeReleaseType, XcodeReleaseType } from "../src/xcode-utils"; | ||
import fs from "fs"; | ||
import path from "path"; | ||
import * as xcodeUtils from "../src/xcode-utils"; | ||
|
||
jest.mock("path"); | ||
let pathJoinSpy: jest.SpyInstance; | ||
let readdirSyncSpy: jest.SpyInstance; | ||
let getXcodeReleaseTypeSpy: jest.SpyInstance; | ||
let parsePlistFileSpy: jest.SpyInstance; | ||
|
||
describe("getXcodeReleaseType", () => { | ||
const buildPlistPath = (plistName: string) => { | ||
return `${__dirname}/data/${plistName}`; | ||
}; | ||
const buildPlistPath = (plistName: string) => { | ||
return `${__dirname}/data/${plistName}`; | ||
}; | ||
|
||
const buildFsDirentItem = (name: string, opt: { isSymbolicLink: boolean; isDirectory: boolean }): fs.Dirent => { | ||
return { | ||
name, | ||
isSymbolicLink: () => opt.isSymbolicLink, | ||
isDirectory: () => opt.isDirectory | ||
} as fs.Dirent; | ||
}; | ||
|
||
let pathJoinSpy: jest.SpyInstance; | ||
const fakeReadDirResults = [ | ||
buildFsDirentItem("Xcode_2.app", { isSymbolicLink: true, isDirectory: false }), | ||
buildFsDirentItem("Xcode.app", { isSymbolicLink: false, isDirectory: true }), | ||
buildFsDirentItem("Xcode_11.1.app", { isSymbolicLink: false, isDirectory: true }), | ||
buildFsDirentItem("Xcode_11.1_beta.app", { isSymbolicLink: true, isDirectory: false }), | ||
buildFsDirentItem("Xcode_11.2.1.app", { isSymbolicLink: false, isDirectory: true }), | ||
buildFsDirentItem("Xcode_11.4.app", { isSymbolicLink: true, isDirectory: false }), | ||
buildFsDirentItem("Xcode_11.4_beta.app", { isSymbolicLink: false, isDirectory: true }), | ||
buildFsDirentItem("Xcode_11.app", { isSymbolicLink: false, isDirectory: true }), | ||
buildFsDirentItem("Xcode_12_beta.app", { isSymbolicLink: false, isDirectory: true }), | ||
buildFsDirentItem("third_party_folder", { isSymbolicLink: false, isDirectory: true }), | ||
]; | ||
|
||
describe("getInstalledXcodeApps", () => { | ||
beforeEach(() => { | ||
pathJoinSpy = jest.spyOn(path, "join"); | ||
readdirSyncSpy = jest.spyOn(fs, "readdirSync"); | ||
}); | ||
|
||
it("stable release", () => { | ||
const plistPath = buildPlistPath("xcode-stable.plist"); | ||
pathJoinSpy.mockImplementation(() => plistPath); | ||
const releaseType = getXcodeReleaseType(""); | ||
expect(releaseType).toBe(XcodeReleaseType.GM); | ||
it("versions are filtered correctly", () => { | ||
readdirSyncSpy.mockImplementation(() => fakeReadDirResults); | ||
const expectedVersions: string[] = [ | ||
"/Applications/Xcode_11.1.app", | ||
"/Applications/Xcode_11.2.1.app", | ||
"/Applications/Xcode_11.4_beta.app", | ||
"/Applications/Xcode_11.app", | ||
"/Applications/Xcode_12_beta.app", | ||
]; | ||
|
||
const installedXcodeApps = xcodeUtils.getInstalledXcodeApps(); | ||
expect(installedXcodeApps).toEqual(expectedVersions); | ||
}); | ||
|
||
it("beta release", () => { | ||
const plistPath = buildPlistPath("xcode-beta.plist"); | ||
pathJoinSpy.mockImplementation(() => plistPath); | ||
const releaseType = getXcodeReleaseType(""); | ||
expect(releaseType).toBe(XcodeReleaseType.Beta); | ||
afterEach(() => { | ||
jest.resetAllMocks(); | ||
jest.clearAllMocks(); | ||
}); | ||
}); | ||
|
||
it("unknown release", () => { | ||
const plistPath = buildPlistPath("xcode-empty-license.plist"); | ||
pathJoinSpy.mockImplementation(() => plistPath); | ||
const releaseType = getXcodeReleaseType(""); | ||
expect(releaseType).toBe(XcodeReleaseType.Unknown); | ||
describe("getXcodeReleaseType", () => { | ||
beforeEach(() => { | ||
pathJoinSpy = jest.spyOn(path, "join"); | ||
}); | ||
|
||
it("non-existent plist", () => { | ||
const plistPath = buildPlistPath("xcode-fake.plist"); | ||
it.each([ | ||
["xcode-stable-license.plist", "GM"], | ||
["xcode-beta-license.plist", "Beta"], | ||
["xcode-empty-license.plist", "Unknown"], | ||
["xcode-fake.plist", "Unknown"], | ||
] as [string, xcodeUtils.XcodeVersionReleaseType][])("%s -> %s", (plistName: string, expected: xcodeUtils.XcodeVersionReleaseType) => { | ||
const plistPath = buildPlistPath(plistName); | ||
pathJoinSpy.mockImplementation(() => plistPath); | ||
const releaseType = getXcodeReleaseType(""); | ||
expect(releaseType).toBe(XcodeReleaseType.Unknown); | ||
const releaseType = xcodeUtils.getXcodeReleaseType(""); | ||
expect(releaseType).toBe(expected); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.resetAllMocks(); | ||
jest.clearAllMocks(); | ||
}); | ||
}); | ||
|
||
describe("getXcodeVersionInfo", () => { | ||
beforeEach(() => { | ||
pathJoinSpy = jest.spyOn(path, "join"); | ||
getXcodeReleaseTypeSpy = jest.spyOn(xcodeUtils, "getXcodeReleaseType"); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.resetAllMocks(); | ||
jest.clearAllMocks(); | ||
}); | ||
}); | ||
|
||
it("read version from plist", () => { | ||
const plistPath = buildPlistPath("xcode-version.plist"); | ||
pathJoinSpy.mockImplementation(() => plistPath); | ||
getXcodeReleaseTypeSpy.mockImplementation(() => "GM"); | ||
|
||
const expected: xcodeUtils.XcodeVersion = { | ||
version: "12.0.1", | ||
buildNumber: "12A7300", | ||
path: "fake_path", | ||
releaseType: "GM", | ||
stable: true | ||
}; | ||
|
||
const xcodeInfo = xcodeUtils.getXcodeVersionInfo("fake_path"); | ||
expect(xcodeInfo).toEqual(expected); | ||
}); | ||
|
||
describe("'stable' property", () => { | ||
it.each([ | ||
["GM", true], | ||
["Beta", false], | ||
["Unknown", false] | ||
])("%s -> %s", (releaseType: string, expected: boolean) => { | ||
const plistPath = buildPlistPath("xcode-version.plist"); | ||
pathJoinSpy.mockImplementation(() => plistPath); | ||
getXcodeReleaseTypeSpy.mockImplementation(() => releaseType); | ||
|
||
const xcodeInfo = xcodeUtils.getXcodeVersionInfo("fake_path"); | ||
expect(xcodeInfo).toBeTruthy(); | ||
expect(xcodeInfo?.stable).toBe(expected); | ||
}); | ||
}); | ||
|
||
describe("coerce validation", () => { | ||
beforeEach(() => { | ||
parsePlistFileSpy = jest.spyOn(xcodeUtils, "parsePlistFile"); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.resetAllMocks(); | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it("full version", () => { | ||
parsePlistFileSpy.mockImplementation(() => { | ||
return { | ||
CFBundleShortVersionString: "12.0.1", ProductBuildVersion: "2FF" | ||
}; | ||
}); | ||
getXcodeReleaseTypeSpy.mockImplementation(() => "GM"); | ||
|
||
const xcodeInfo = xcodeUtils.getXcodeVersionInfo("fake_path"); | ||
expect(xcodeInfo?.version).toBe("12.0.1"); | ||
}); | ||
|
||
it("partial version", () => { | ||
parsePlistFileSpy.mockImplementation(() => { | ||
return { | ||
CFBundleShortVersionString: "10.3", ProductBuildVersion: "2FF" | ||
}; | ||
}); | ||
getXcodeReleaseTypeSpy.mockImplementation(() => "GM"); | ||
|
||
const xcodeInfo = xcodeUtils.getXcodeVersionInfo("fake_path"); | ||
expect(xcodeInfo?.version).toBe("10.3.0"); | ||
}); | ||
|
||
it("invalid version", () => { | ||
parsePlistFileSpy.mockImplementation(() => { | ||
return { | ||
CFBundleShortVersionString: "fake_version", ProductBuildVersion: "2FF" | ||
}; | ||
}); | ||
getXcodeReleaseTypeSpy.mockImplementation(() => "GM"); | ||
|
||
const xcodeInfo = xcodeUtils.getXcodeVersionInfo("fake_path"); | ||
expect(xcodeInfo).toBeNull(); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.