import { codeBlock } from 'common-tags';
import { XmlDocument } from 'xmldoc';
import { fs } from '~test/util.ts';
import type { Registry } from './types.ts';
import { bumpPackageVersion } from './update.ts';
import {
applyRegistries,
findGlobalJson,
findVersion,
getConfiguredRegistries,
} from './util.ts';
vi.mock('../../../util/fs/index.ts');
describe('modules/manager/nuget/util', () => {
describe('findVersion', () => {
it('finds the version in a later property group', () => {
const content =
'net6.00.0.1';
const { bumpedContent } = bumpPackageVersion(content, '0.0.1', 'patch');
const project = new XmlDocument(bumpedContent!);
const versionNode = findVersion(project);
const newVersion = versionNode!.val;
expect(newVersion).toBe('0.0.2');
});
it('picks version over versionprefix', () => {
const content =
'0.0.50.0.1';
const { bumpedContent } = bumpPackageVersion(content, '0.0.1', 'patch');
const project = new XmlDocument(bumpedContent!);
const versionNode = findVersion(project);
const newVersion = versionNode!.val;
expect(newVersion).toBe('0.0.2');
});
});
describe('getConfiguredRegistries', () => {
it('reads nuget config file', async () => {
fs.findUpLocal.mockResolvedValue('NuGet.config');
fs.readLocalFile.mockResolvedValueOnce(
codeBlock`
`,
);
const registries = await getConfiguredRegistries('NuGet.config');
expect(registries).toEqual([
{
name: 'nuget.org',
url: 'https://api.nuget.org/v3/index.json',
sourceMappedPackagePatterns: ['*'],
},
{
name: 'contoso.com',
url: 'https://contoso.com/packages/',
sourceMappedPackagePatterns: ['Contoso.*', 'NuGet.Common'],
},
]);
});
it('deduplicates registries', async () => {
fs.findUpLocal.mockResolvedValue('NuGet.config');
fs.readLocalFile.mockResolvedValueOnce(
codeBlock`
`,
);
const registries = await getConfiguredRegistries('NuGet.config');
expect(registries).toEqual([
{
name: 'nuget.org',
url: 'https://api.nuget.org/v3/index.json#protocolVersion=3',
},
]);
});
it('reads nuget config file with default registry', async () => {
fs.findUpLocal.mockResolvedValue('NuGet.config');
fs.readLocalFile.mockResolvedValueOnce(
codeBlock`
`,
);
const registries = await getConfiguredRegistries('NuGet.config');
expect(registries).toEqual([
{
name: 'nuget.org',
url: 'https://api.nuget.org/v3/index.json',
sourceMappedPackagePatterns: ['*'],
},
{
name: 'contoso.com',
url: 'https://contoso.com/packages/',
sourceMappedPackagePatterns: ['Contoso.*', 'NuGet.Common'],
},
]);
});
it('reads nuget config file with default registry disabled and added sources', async () => {
fs.findUpLocal.mockResolvedValue('NuGet.config');
fs.readLocalFile.mockResolvedValueOnce(
codeBlock`
`,
);
const registries = await getConfiguredRegistries('NuGet.config');
expect(registries).toEqual([
{
name: 'contoso.com',
url: 'https://contoso.com/packages/',
},
]);
});
it('reads nuget config file with default registry disabled given default registry added', async () => {
fs.findUpLocal.mockResolvedValue('NuGet.config');
fs.readLocalFile.mockResolvedValueOnce(
codeBlock`
`,
);
const registries = await getConfiguredRegistries('NuGet.config');
expect(registries).toEqual([
{
name: 'contoso.com',
url: 'https://contoso.com/packages/',
},
]);
});
it('reads nuget config file with unknown disabled source', async () => {
fs.findUpLocal.mockResolvedValue('NuGet.config');
fs.readLocalFile.mockResolvedValueOnce(
codeBlock`
`,
);
const registries = await getConfiguredRegistries('NuGet.config');
expect(registries).toEqual([
{
name: 'nuget.org',
url: 'https://api.nuget.org/v3/index.json',
},
{
name: 'contoso.com',
url: 'https://contoso.com/packages/',
},
]);
});
it('reads nuget config file with disabled source with value false', async () => {
fs.findUpLocal.mockResolvedValue('NuGet.config');
fs.readLocalFile.mockResolvedValueOnce(
codeBlock`
`,
);
const registries = await getConfiguredRegistries('NuGet.config');
expect(registries).toEqual([
{
name: 'nuget.org',
url: 'https://api.nuget.org/v3/index.json',
},
{
name: 'contoso.com',
url: 'https://contoso.com/packages/',
},
]);
});
it('reads nuget config file without packageSources and ignores disabledPackageSources', async () => {
fs.findUpLocal.mockResolvedValue('NuGet.config');
fs.readLocalFile.mockResolvedValueOnce(
codeBlock`
`,
);
const registries = await getConfiguredRegistries('NuGet.config');
expect(registries).toBeUndefined();
});
});
describe('applyRegistries', () => {
it('applies registry to package name via source mapping', () => {
const registries: Registry[] = [
{
name: 'nuget.org',
url: 'https://api.nuget.org/v3/index.json',
sourceMappedPackagePatterns: ['*'],
},
{
name: 'contoso.com',
url: 'https://contoso.com/packages/',
sourceMappedPackagePatterns: [
'Contoso.*',
'NuGet.Common',
'AdventureWorks*',
],
},
{
name: 'contoso.test',
url: 'https://contoso.test/packages/',
sourceMappedPackagePatterns: [
'Contoso.*',
'Contoso.Test.*',
'NuGet.*',
'NuGet.Common*',
'AdventureWorks.Test.*',
],
},
];
expect(
applyRegistries({ depName: 'Newtonsoft.Json' }, registries),
).toEqual({
depName: 'Newtonsoft.Json',
registryUrls: ['https://api.nuget.org/v3/index.json'],
});
expect(
applyRegistries({ depName: 'Contoso.SomePackage' }, registries),
).toEqual({
depName: 'Contoso.SomePackage',
registryUrls: [
'https://contoso.com/packages/',
'https://contoso.test/packages/',
],
});
expect(applyRegistries({ depName: 'NuGet.Some' }, registries)).toEqual({
depName: 'NuGet.Some',
registryUrls: ['https://contoso.test/packages/'],
});
expect(
applyRegistries({ depName: 'Contoso.Test.SomePackage' }, registries),
).toEqual({
depName: 'Contoso.Test.SomePackage',
registryUrls: ['https://contoso.test/packages/'],
});
expect(
applyRegistries(
{ depName: 'AdventureWorks.Test.SomePackage' },
registries,
),
).toEqual({
depName: 'AdventureWorks.Test.SomePackage',
registryUrls: ['https://contoso.test/packages/'],
});
});
it('applies registry to package name case insensitive', () => {
const registries: Registry[] = [
{
name: 'nuget.org',
url: 'https://api.nuget.org/v3/index.json',
sourceMappedPackagePatterns: ['*'],
},
{
name: 'contoso.com',
url: 'https://contoso.com/packages/',
sourceMappedPackagePatterns: ['Contoso.*', 'Nuget.common'],
},
];
expect(applyRegistries({ depName: 'NuGet.Common' }, registries)).toEqual({
depName: 'NuGet.Common',
registryUrls: ['https://contoso.com/packages/'],
});
});
it('applies all registries to package name', () => {
const registries: Registry[] = [
{
name: 'nuget.org',
url: 'https://api.nuget.org/v3/index.json',
},
{
name: 'contoso.com',
url: 'https://contoso.com/packages/',
},
];
expect(
applyRegistries(
{
depName: 'Newtonsoft.Json',
},
registries,
),
).toEqual({
depName: 'Newtonsoft.Json',
registryUrls: [
'https://api.nuget.org/v3/index.json',
'https://contoso.com/packages/',
],
});
});
it('applies nothing', () => {
expect(
applyRegistries(
{
depName: 'Newtonsoft.Json',
},
undefined,
),
).toEqual({
depName: 'Newtonsoft.Json',
});
});
});
describe('findGlobalJson', () => {
it('not found', async () => {
fs.findLocalSiblingOrParent.mockResolvedValueOnce(null);
const globalJson = await findGlobalJson('project.csproj');
expect(globalJson).toBeNull();
});
it('no content', async () => {
fs.findLocalSiblingOrParent.mockResolvedValueOnce('global.json');
const globalJson = await findGlobalJson('project.csproj');
expect(globalJson).toBeNull();
});
it('fails to parse', async () => {
fs.findLocalSiblingOrParent.mockResolvedValueOnce('global.json');
fs.readLocalFile.mockResolvedValueOnce('{');
const globalJson = await findGlobalJson('project.csproj');
expect(globalJson).toBeNull();
});
it('parses', async () => {
fs.findLocalSiblingOrParent.mockResolvedValueOnce('global.json');
fs.readLocalFile.mockResolvedValueOnce(
'{ /* This is comment */ "sdk": { "version": "5.0.100" }, "some": true }',
);
const globalJson = await findGlobalJson('project.csproj');
expect(globalJson).toEqual({ sdk: { version: '5.0.100' } });
});
});
});