- add extension kind property
- add web extension property - include all files as web resources - cap web resources to 25 - add tests
This commit is contained in:
parent
3b10000ad4
commit
dc49ab513c
3 changed files with 321 additions and 123 deletions
|
@ -12,6 +12,7 @@
|
||||||
<Property Id="Microsoft.VisualStudio.Code.Engine" Value="<%- engine %>" />
|
<Property Id="Microsoft.VisualStudio.Code.Engine" Value="<%- engine %>" />
|
||||||
<Property Id="Microsoft.VisualStudio.Code.ExtensionDependencies" Value="<%- extensionDependencies %>" />
|
<Property Id="Microsoft.VisualStudio.Code.ExtensionDependencies" Value="<%- extensionDependencies %>" />
|
||||||
<Property Id="Microsoft.VisualStudio.Code.ExtensionPack" Value="<%- extensionPack %>" />
|
<Property Id="Microsoft.VisualStudio.Code.ExtensionPack" Value="<%- extensionPack %>" />
|
||||||
|
<Property Id="Microsoft.VisualStudio.Code.ExtensionKind" Value="<%- extensionKind %>" />
|
||||||
<Property Id="Microsoft.VisualStudio.Code.LocalizedLanguages" Value="<%- localizedLanguages %>" />
|
<Property Id="Microsoft.VisualStudio.Code.LocalizedLanguages" Value="<%- localizedLanguages %>" />
|
||||||
<% if (links.repository) { %>
|
<% if (links.repository) { %>
|
||||||
<Property Id="Microsoft.VisualStudio.Services.Links.Source" Value="<%- links.repository %>" />
|
<Property Id="Microsoft.VisualStudio.Services.Links.Source" Value="<%- links.repository %>" />
|
||||||
|
@ -29,6 +30,7 @@
|
||||||
<Property Id="Microsoft.VisualStudio.Services.GitHubFlavoredMarkdown" Value="<%- githubMarkdown %>" />
|
<Property Id="Microsoft.VisualStudio.Services.GitHubFlavoredMarkdown" Value="<%- githubMarkdown %>" />
|
||||||
<% if (typeof enableMarketplaceQnA === 'boolean') { %><Property Id="Microsoft.VisualStudio.Services.EnableMarketplaceQnA" Value="<%- enableMarketplaceQnA %>" /><% } %>
|
<% if (typeof enableMarketplaceQnA === 'boolean') { %><Property Id="Microsoft.VisualStudio.Services.EnableMarketplaceQnA" Value="<%- enableMarketplaceQnA %>" /><% } %>
|
||||||
<% if (customerQnALink) { %><Property Id="Microsoft.VisualStudio.Services.CustomerQnALink" Value="<%- customerQnALink %>" /><% } %>
|
<% if (customerQnALink) { %><Property Id="Microsoft.VisualStudio.Services.CustomerQnALink" Value="<%- customerQnALink %>" /><% } %>
|
||||||
|
<% if (typeof webExtension === 'boolean') { %><Property Id="Microsoft.VisualStudio.Code.WebExtension" Value="<%- webExtension %>" /><% } %>
|
||||||
</Properties>
|
</Properties>
|
||||||
<% if (license) { %><License><%- license %></License><% } %>
|
<% if (license) { %><License><%- license %></License><% } %>
|
||||||
<% if (icon) { %><Icon><%- icon %></Icon><% } %>
|
<% if (icon) { %><Icon><%- icon %></Icon><% } %>
|
||||||
|
|
|
@ -211,6 +211,8 @@ class ManifestProcessor extends BaseProcessor {
|
||||||
enableMarketplaceQnA = false;
|
enableMarketplaceQnA = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const extensionKind = getExtensionKind(manifest);
|
||||||
|
|
||||||
this.vsix = {
|
this.vsix = {
|
||||||
...this.vsix,
|
...this.vsix,
|
||||||
id: manifest.name,
|
id: manifest.name,
|
||||||
|
@ -233,6 +235,7 @@ class ManifestProcessor extends BaseProcessor {
|
||||||
customerQnALink,
|
customerQnALink,
|
||||||
extensionDependencies: _(manifest.extensionDependencies || []).uniq().join(','),
|
extensionDependencies: _(manifest.extensionDependencies || []).uniq().join(','),
|
||||||
extensionPack: _(manifest.extensionPack || []).uniq().join(','),
|
extensionPack: _(manifest.extensionPack || []).uniq().join(','),
|
||||||
|
extensionKind: extensionKind.join(','),
|
||||||
localizedLanguages: (manifest.contributes && manifest.contributes.localizations) ?
|
localizedLanguages: (manifest.contributes && manifest.contributes.localizations) ?
|
||||||
manifest.contributes.localizations.map(loc => loc.localizedLanguageName || loc.languageName || loc.languageId).join(',') : ''
|
manifest.contributes.localizations.map(loc => loc.localizedLanguageName || loc.languageName || loc.languageId).join(',') : ''
|
||||||
};
|
};
|
||||||
|
@ -665,33 +668,35 @@ function getExtensionKind(manifest: Manifest): ExtensionKind[] {
|
||||||
export class WebExtensionProcessor extends BaseProcessor {
|
export class WebExtensionProcessor extends BaseProcessor {
|
||||||
|
|
||||||
private readonly isWebKind: boolean = false;
|
private readonly isWebKind: boolean = false;
|
||||||
private readonly licenseProcessor: LicenseProcessor;
|
|
||||||
|
|
||||||
constructor(manifest: Manifest, options: IPackageOptions) {
|
constructor(manifest: Manifest, options: IPackageOptions) {
|
||||||
super(manifest);
|
super(manifest);
|
||||||
this.isWebKind = options.web && isWebKind(manifest);
|
this.isWebKind = options.web && isWebKind(manifest);
|
||||||
this.licenseProcessor = new LicenseProcessor(manifest);
|
if (this.isWebKind) {
|
||||||
|
this.vsix = {
|
||||||
|
...this.vsix,
|
||||||
|
webExtension: true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onFile(file: IFile): Promise<IFile> {
|
onFile(file: IFile): Promise<IFile> {
|
||||||
if (this.isWebKind) {
|
if (this.isWebKind) {
|
||||||
const path = util.normalize(file.path);
|
const path = util.normalize(file.path);
|
||||||
if (/\.svg$/i.test(path)) {
|
if (/\.svg$/i.test(path)) {
|
||||||
throw new Error(`SVGs can't be used in web extensions: ${path}`);
|
throw new Error(`SVGs can't be used in a web extension: ${path}`);
|
||||||
}
|
|
||||||
if (
|
|
||||||
!/^extension\/readme.md$/i.test(path) // exclude read me
|
|
||||||
&& !/^extension\/changelog.md$/i.test(path) // exclude changelog
|
|
||||||
&& !/^extension\/package.json$/i.test(path) // exclude package.json
|
|
||||||
&& !this.licenseProcessor.filter(path) // exclude licenses
|
|
||||||
&& !/^extension\/*node_modules\/*/i.test(path) // exclude node_modules
|
|
||||||
) {
|
|
||||||
this.assets.push({ type: `Microsoft.VisualStudio.Code.WebResources/${path}`, path });
|
|
||||||
}
|
}
|
||||||
|
this.assets.push({ type: `Microsoft.VisualStudio.Code.WebResources/${path}`, path });
|
||||||
}
|
}
|
||||||
return Promise.resolve(file);
|
return Promise.resolve(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async onEnd(): Promise<void> {
|
||||||
|
if (this.assets.length > 25) {
|
||||||
|
throw new Error('Cannot pack more than 25 files in a web extension. Use `vsce -ls` to see all the files that will be packed and exclude those which are not needed in .vscodeignore.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class NLSProcessor extends BaseProcessor {
|
export class NLSProcessor extends BaseProcessor {
|
||||||
|
@ -955,11 +960,6 @@ export function processFiles(processors: IProcessor[], files: IFile[]): Promise<
|
||||||
return Promise.all(processedFiles).then(files => {
|
return Promise.all(processedFiles).then(files => {
|
||||||
return util.sequence(processors.map(p => () => p.onEnd())).then(() => {
|
return util.sequence(processors.map(p => () => p.onEnd())).then(() => {
|
||||||
const assets = _.flatten(processors.map(p => p.assets));
|
const assets = _.flatten(processors.map(p => p.assets));
|
||||||
|
|
||||||
if (assets.length >= 50) {
|
|
||||||
throw new Error('Cannot have more than 50 assets');
|
|
||||||
}
|
|
||||||
|
|
||||||
const vsix = processors.reduce((r, p) => ({ ...r, ...p.vsix }), { assets });
|
const vsix = processors.reduce((r, p) => ({ ...r, ...p.vsix }), { assets });
|
||||||
|
|
||||||
return Promise.all([toVsixManifest(vsix), toContentTypes(files)]).then(result => {
|
return Promise.all([toVsixManifest(vsix), toContentTypes(files)]).then(result => {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {
|
import {
|
||||||
readManifest, collect, toContentTypes, ReadmeProcessor,
|
readManifest, collect, toContentTypes, ReadmeProcessor,
|
||||||
read, processFiles, createDefaultProcessors,
|
read, processFiles, createDefaultProcessors,
|
||||||
toVsixManifest, IFile, validateManifest, isSupportedWebExtension, WebExtensionProcessor, IAsset
|
toVsixManifest, IFile, validateManifest, isSupportedWebExtension, WebExtensionProcessor, IAsset, IPackageOptions
|
||||||
} from '../package';
|
} from '../package';
|
||||||
import { Manifest } from '../manifest';
|
import { Manifest } from '../manifest';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
@ -66,8 +66,8 @@ type ContentTypes = {
|
||||||
const parseXmlManifest = createXMLParser<XMLManifest>();
|
const parseXmlManifest = createXMLParser<XMLManifest>();
|
||||||
const parseContentTypes = createXMLParser<ContentTypes>();
|
const parseContentTypes = createXMLParser<ContentTypes>();
|
||||||
|
|
||||||
function _toVsixManifest(manifest: Manifest, files: IFile[]): Promise<string> {
|
function _toVsixManifest(manifest: Manifest, files: IFile[], options: IPackageOptions = {}): Promise<string> {
|
||||||
const processors = createDefaultProcessors(manifest);
|
const processors = createDefaultProcessors(manifest, options);
|
||||||
return processFiles(processors, files).then(() => {
|
return processFiles(processors, files).then(() => {
|
||||||
const assets = _.flatten(processors.map(p => p.assets));
|
const assets = _.flatten(processors.map(p => p.assets));
|
||||||
const vsix = processors.reduce((r, p) => ({ ...r, ...p.vsix }), { assets });
|
const vsix = processors.reduce((r, p) => ({ ...r, ...p.vsix }), { assets });
|
||||||
|
@ -1267,84 +1267,191 @@ describe('toVsixManifest', () => {
|
||||||
throw new Error('Should not reach here');
|
throw new Error('Should not reach here');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('qna', () => {
|
it('should expose web extension assets and properties', async () => {
|
||||||
it('should use marketplace qna by default', async () => {
|
const manifest = createManifest({
|
||||||
const xmlManifest = await toXMLManifest({
|
browser: 'browser.js',
|
||||||
name: 'test',
|
extensionKind: ['web'],
|
||||||
publisher: 'mocha',
|
});
|
||||||
version: '0.0.1',
|
const files = [
|
||||||
engines: Object.create(null)
|
{ path: 'extension/browser.js', contents: Buffer.from('') },
|
||||||
});
|
];
|
||||||
|
|
||||||
assertMissingProperty(xmlManifest, 'Microsoft.VisualStudio.Services.EnableMarketplaceQnA');
|
const vsixManifest = await _toVsixManifest(manifest, files, { web: true })
|
||||||
assertMissingProperty(xmlManifest, 'Microsoft.VisualStudio.Services.CustomerQnALink');
|
const result = await parseXmlManifest(vsixManifest);
|
||||||
|
const assets = result.PackageManifest.Assets[0].Asset;
|
||||||
|
assert(assets.some(asset => asset.$.Type === 'Microsoft.VisualStudio.Code.WebResources/extension/browser.js' && asset.$.Path === 'extension/browser.js'));
|
||||||
|
|
||||||
|
const properties = result.PackageManifest.Metadata[0].Properties[0].Property;
|
||||||
|
const webExtensionProps = properties.filter(p => p.$.Id === 'Microsoft.VisualStudio.Code.WebExtension');
|
||||||
|
assert.equal(webExtensionProps.length, 1);
|
||||||
|
assert.equal(webExtensionProps[0].$.Value, 'true');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should expose web extension assets and properties when extension kind is not provided', async () => {
|
||||||
|
const manifest = createManifest({
|
||||||
|
browser: 'browser.js',
|
||||||
|
});
|
||||||
|
const files = [
|
||||||
|
{ path: 'extension/browser.js', contents: Buffer.from('') },
|
||||||
|
];
|
||||||
|
|
||||||
|
const vsixManifest = await _toVsixManifest(manifest, files, { web: true })
|
||||||
|
const result = await parseXmlManifest(vsixManifest);
|
||||||
|
const assets = result.PackageManifest.Assets[0].Asset;
|
||||||
|
assert(assets.some(asset => asset.$.Type === 'Microsoft.VisualStudio.Code.WebResources/extension/browser.js' && asset.$.Path === 'extension/browser.js'));
|
||||||
|
|
||||||
|
const properties = result.PackageManifest.Metadata[0].Properties[0].Property;
|
||||||
|
const webExtensionProps = properties.filter(p => p.$.Id === 'Microsoft.VisualStudio.Code.WebExtension');
|
||||||
|
assert.equal(webExtensionProps.length, 1);
|
||||||
|
assert.equal(webExtensionProps[0].$.Value, 'true');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not expose web extension assets and properties for web extension when not asked for', async () => {
|
||||||
|
const manifest = createManifest({
|
||||||
|
browser: 'browser.js',
|
||||||
|
extensionKind: ['web'],
|
||||||
|
});
|
||||||
|
const files = [
|
||||||
|
{ path: 'extension/browser.js', contents: Buffer.from('') },
|
||||||
|
];
|
||||||
|
|
||||||
|
const vsixManifest = await _toVsixManifest(manifest, files)
|
||||||
|
const result = await parseXmlManifest(vsixManifest);
|
||||||
|
const assets = result.PackageManifest.Assets[0].Asset;
|
||||||
|
assert(assets.every(asset => !asset.$.Type.startsWith('Microsoft.VisualStudio.Code.WebResources')));
|
||||||
|
|
||||||
|
const properties = result.PackageManifest.Metadata[0].Properties[0].Property;
|
||||||
|
const webExtensionProps = properties.filter(p => p.$.Id === 'Microsoft.VisualStudio.Code.WebExtension');
|
||||||
|
assert.equal(webExtensionProps.length, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not expose web extension assets and properties for non web extension', async () => {
|
||||||
|
const manifest = createManifest({
|
||||||
|
main: 'main.js',
|
||||||
|
});
|
||||||
|
const files = [
|
||||||
|
{ path: 'extension/main.js', contents: Buffer.from('') },
|
||||||
|
];
|
||||||
|
|
||||||
|
const vsixManifest = await _toVsixManifest(manifest, files, { web: true })
|
||||||
|
const result = await parseXmlManifest(vsixManifest);
|
||||||
|
const assets = result.PackageManifest.Assets[0].Asset;
|
||||||
|
assert(assets.every(asset => !asset.$.Type.startsWith('Microsoft.VisualStudio.Code.WebResources')));
|
||||||
|
|
||||||
|
const properties = result.PackageManifest.Metadata[0].Properties[0].Property;
|
||||||
|
const webExtensionProps = properties.filter(p => p.$.Id === 'Microsoft.VisualStudio.Code.WebExtension');
|
||||||
|
assert.equal(webExtensionProps.length, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should expose extension kind properties when providedd', async () => {
|
||||||
|
const manifest = createManifest({
|
||||||
|
extensionKind: ['ui', 'workspace', 'web'],
|
||||||
|
});
|
||||||
|
const files = [
|
||||||
|
{ path: 'extension/main.js', contents: Buffer.from('') },
|
||||||
|
];
|
||||||
|
|
||||||
|
const vsixManifest = await _toVsixManifest(manifest, files, { web: true })
|
||||||
|
const result = await parseXmlManifest(vsixManifest);
|
||||||
|
const properties = result.PackageManifest.Metadata[0].Properties[0].Property;
|
||||||
|
const extensionKindProps = properties.filter(p => p.$.Id === 'Microsoft.VisualStudio.Code.ExtensionKind');
|
||||||
|
assert.equal(extensionKindProps[0].$.Value, ['ui', 'workspace', 'web'].join(','));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should expose extension kind properties when derived', async () => {
|
||||||
|
const manifest = createManifest({
|
||||||
|
main: 'main.js',
|
||||||
|
});
|
||||||
|
const files = [
|
||||||
|
{ path: 'extension/main.js', contents: Buffer.from('') },
|
||||||
|
];
|
||||||
|
|
||||||
|
const vsixManifest = await _toVsixManifest(manifest, files, { web: true })
|
||||||
|
const result = await parseXmlManifest(vsixManifest);
|
||||||
|
const properties = result.PackageManifest.Metadata[0].Properties[0].Property;
|
||||||
|
const extensionKindProps = properties.filter(p => p.$.Id === 'Microsoft.VisualStudio.Code.ExtensionKind');
|
||||||
|
assert.equal(extensionKindProps[0].$.Value, 'workspace');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('qna', () => {
|
||||||
|
it('should use marketplace qna by default', async () => {
|
||||||
|
const xmlManifest = await toXMLManifest({
|
||||||
|
name: 'test',
|
||||||
|
publisher: 'mocha',
|
||||||
|
version: '0.0.1',
|
||||||
|
engines: Object.create(null)
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not use marketplace in a github repo, without specifying it', async () => {
|
assertMissingProperty(xmlManifest, 'Microsoft.VisualStudio.Services.EnableMarketplaceQnA');
|
||||||
const xmlManifest = await toXMLManifest({
|
assertMissingProperty(xmlManifest, 'Microsoft.VisualStudio.Services.CustomerQnALink');
|
||||||
name: 'test',
|
});
|
||||||
publisher: 'mocha',
|
|
||||||
version: '0.0.1',
|
|
||||||
engines: Object.create(null),
|
|
||||||
repository: 'https://github.com/username/repository'
|
|
||||||
});
|
|
||||||
|
|
||||||
assertMissingProperty(xmlManifest, 'Microsoft.VisualStudio.Services.EnableMarketplaceQnA');
|
it('should not use marketplace in a github repo, without specifying it', async () => {
|
||||||
assertMissingProperty(xmlManifest, 'Microsoft.VisualStudio.Services.CustomerQnALink');
|
const xmlManifest = await toXMLManifest({
|
||||||
|
name: 'test',
|
||||||
|
publisher: 'mocha',
|
||||||
|
version: '0.0.1',
|
||||||
|
engines: Object.create(null),
|
||||||
|
repository: 'https://github.com/username/repository'
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should use marketplace in a github repo, when specifying it', async () => {
|
assertMissingProperty(xmlManifest, 'Microsoft.VisualStudio.Services.EnableMarketplaceQnA');
|
||||||
const xmlManifest = await toXMLManifest({
|
assertMissingProperty(xmlManifest, 'Microsoft.VisualStudio.Services.CustomerQnALink');
|
||||||
name: 'test',
|
});
|
||||||
publisher: 'mocha',
|
|
||||||
version: '0.0.1',
|
|
||||||
engines: Object.create(null),
|
|
||||||
repository: 'https://github.com/username/repository',
|
|
||||||
qna: 'marketplace'
|
|
||||||
});
|
|
||||||
|
|
||||||
assertProperty(xmlManifest, 'Microsoft.VisualStudio.Services.EnableMarketplaceQnA', 'true');
|
it('should use marketplace in a github repo, when specifying it', async () => {
|
||||||
assertMissingProperty(xmlManifest, 'Microsoft.VisualStudio.Services.CustomerQnALink');
|
const xmlManifest = await toXMLManifest({
|
||||||
|
name: 'test',
|
||||||
|
publisher: 'mocha',
|
||||||
|
version: '0.0.1',
|
||||||
|
engines: Object.create(null),
|
||||||
|
repository: 'https://github.com/username/repository',
|
||||||
|
qna: 'marketplace'
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle qna=marketplace', async () => {
|
assertProperty(xmlManifest, 'Microsoft.VisualStudio.Services.EnableMarketplaceQnA', 'true');
|
||||||
const xmlManifest = await toXMLManifest({
|
assertMissingProperty(xmlManifest, 'Microsoft.VisualStudio.Services.CustomerQnALink');
|
||||||
name: 'test',
|
});
|
||||||
publisher: 'mocha',
|
|
||||||
version: '0.0.1',
|
|
||||||
engines: Object.create(null),
|
|
||||||
qna: 'marketplace'
|
|
||||||
});
|
|
||||||
|
|
||||||
assertProperty(xmlManifest, 'Microsoft.VisualStudio.Services.EnableMarketplaceQnA', 'true');
|
it('should handle qna=marketplace', async () => {
|
||||||
assertMissingProperty(xmlManifest, 'Microsoft.VisualStudio.Services.CustomerQnALink');
|
const xmlManifest = await toXMLManifest({
|
||||||
|
name: 'test',
|
||||||
|
publisher: 'mocha',
|
||||||
|
version: '0.0.1',
|
||||||
|
engines: Object.create(null),
|
||||||
|
qna: 'marketplace'
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle qna=false', async () => {
|
assertProperty(xmlManifest, 'Microsoft.VisualStudio.Services.EnableMarketplaceQnA', 'true');
|
||||||
const xmlManifest = await toXMLManifest({
|
assertMissingProperty(xmlManifest, 'Microsoft.VisualStudio.Services.CustomerQnALink');
|
||||||
name: 'test',
|
});
|
||||||
publisher: 'mocha',
|
|
||||||
version: '0.0.1',
|
|
||||||
engines: Object.create(null),
|
|
||||||
qna: false
|
|
||||||
});
|
|
||||||
|
|
||||||
assertProperty(xmlManifest, 'Microsoft.VisualStudio.Services.EnableMarketplaceQnA', 'false');
|
it('should handle qna=false', async () => {
|
||||||
assertMissingProperty(xmlManifest, 'Microsoft.VisualStudio.Services.CustomerQnALink');
|
const xmlManifest = await toXMLManifest({
|
||||||
|
name: 'test',
|
||||||
|
publisher: 'mocha',
|
||||||
|
version: '0.0.1',
|
||||||
|
engines: Object.create(null),
|
||||||
|
qna: false
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle custom qna', async () => {
|
assertProperty(xmlManifest, 'Microsoft.VisualStudio.Services.EnableMarketplaceQnA', 'false');
|
||||||
const xmlManifest = await toXMLManifest({
|
assertMissingProperty(xmlManifest, 'Microsoft.VisualStudio.Services.CustomerQnALink');
|
||||||
name: 'test',
|
});
|
||||||
publisher: 'mocha',
|
|
||||||
version: '0.0.1',
|
|
||||||
engines: Object.create(null),
|
|
||||||
qna: 'http://myqna'
|
|
||||||
});
|
|
||||||
|
|
||||||
assertMissingProperty(xmlManifest, 'Microsoft.VisualStudio.Services.EnableMarketplaceQnA');
|
it('should handle custom qna', async () => {
|
||||||
assertProperty(xmlManifest, 'Microsoft.VisualStudio.Services.CustomerQnALink', 'http://myqna');
|
const xmlManifest = await toXMLManifest({
|
||||||
|
name: 'test',
|
||||||
|
publisher: 'mocha',
|
||||||
|
version: '0.0.1',
|
||||||
|
engines: Object.create(null),
|
||||||
|
qna: 'http://myqna'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
assertMissingProperty(xmlManifest, 'Microsoft.VisualStudio.Services.EnableMarketplaceQnA');
|
||||||
|
assertProperty(xmlManifest, 'Microsoft.VisualStudio.Services.CustomerQnALink', 'http://myqna');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1522,10 +1629,10 @@ describe('MarkdownProcessor', () => {
|
||||||
.then((file) => read(file))
|
.then((file) => read(file))
|
||||||
.then((actual) => {
|
.then((actual) => {
|
||||||
return readFile(
|
return readFile(
|
||||||
path.join(root, "readme.branch.override.images.expected.md"),
|
path.join(root, "readme.branch.override.images.expected.md"),
|
||||||
"utf8"
|
"utf8"
|
||||||
).then((expected) => {
|
).then((expected) => {
|
||||||
assert.equal(actual, expected);
|
assert.equal(actual, expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1554,13 +1661,13 @@ describe('MarkdownProcessor', () => {
|
||||||
.onFile(readme)
|
.onFile(readme)
|
||||||
.then((file) => read(file))
|
.then((file) => read(file))
|
||||||
.then((actual) => {
|
.then((actual) => {
|
||||||
return readFile(
|
return readFile(
|
||||||
path.join(root, "readme.branch.override.content.expected.md"),
|
path.join(root, "readme.branch.override.content.expected.md"),
|
||||||
"utf8"
|
"utf8"
|
||||||
).then((expected) => {
|
).then((expected) => {
|
||||||
assert.equal(actual, expected);
|
assert.equal(actual, expected);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should infer baseContentUrl if its a github repo (.git)', () => {
|
it('should infer baseContentUrl if its a github repo (.git)', () => {
|
||||||
|
@ -1586,8 +1693,8 @@ describe('MarkdownProcessor', () => {
|
||||||
return readFile(path.join(root, 'readme.expected.md'), 'utf8')
|
return readFile(path.join(root, 'readme.expected.md'), 'utf8')
|
||||||
.then(expected => {
|
.then(expected => {
|
||||||
assert.equal(actual, expected);
|
assert.equal(actual, expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should replace img urls with baseImagesUrl', () => {
|
it('should replace img urls with baseImagesUrl', () => {
|
||||||
|
@ -1829,56 +1936,145 @@ describe('isSupportedWebExtension', () => {
|
||||||
|
|
||||||
describe('WebExtensionProcessor', () => {
|
describe('WebExtensionProcessor', () => {
|
||||||
|
|
||||||
it('should include browser file', () => {
|
it('should include file', async () => {
|
||||||
const manifest = createManifest({ extensionKind: ['web'] });
|
const manifest = createManifest({ extensionKind: ['web'] });
|
||||||
const processor = new WebExtensionProcessor(manifest, { web: true });
|
const processor = new WebExtensionProcessor(manifest, { web: true });
|
||||||
const file = { path: 'extension/browser.js', contents: '' };
|
const file = { path: 'extension/browser.js', contents: '' };
|
||||||
|
|
||||||
processor.onFile(file);
|
await processor.onFile(file);
|
||||||
|
await processor.onEnd();
|
||||||
|
|
||||||
const expected: IAsset[] = [{ type: `Microsoft.VisualStudio.Code.WebResources/${file.path}`, path: file.path }];
|
const expected: IAsset[] = [{ type: `Microsoft.VisualStudio.Code.WebResources/${file.path}`, path: file.path }];
|
||||||
assert.deepEqual(processor.assets, expected);
|
assert.deepEqual(processor.assets, expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should exclude manifest', () => {
|
it('should include file when extension kind is not specified', async () => {
|
||||||
|
const manifest = createManifest({ browser: 'browser.js' });
|
||||||
|
const processor = new WebExtensionProcessor(manifest, { web: true });
|
||||||
|
const file = { path: 'extension/browser.js', contents: '' };
|
||||||
|
|
||||||
|
await processor.onFile(file);
|
||||||
|
await processor.onEnd();
|
||||||
|
|
||||||
|
const expected: IAsset[] = [{ type: `Microsoft.VisualStudio.Code.WebResources/${file.path}`, path: file.path }];
|
||||||
|
assert.deepEqual(processor.assets, expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not include file when not asked for', async () => {
|
||||||
|
const manifest = createManifest({ extensionKind: ['web'] });
|
||||||
|
const processor = new WebExtensionProcessor(manifest, { web: false });
|
||||||
|
const file = { path: 'extension/browser.js', contents: '' };
|
||||||
|
|
||||||
|
await processor.onFile(file);
|
||||||
|
await processor.onEnd();
|
||||||
|
|
||||||
|
assert.deepEqual(processor.assets, []);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not include file for non web extension', async () => {
|
||||||
|
const manifest = createManifest({ extensionKind: ['ui'] });
|
||||||
|
const processor = new WebExtensionProcessor(manifest, { web: true });
|
||||||
|
const file = { path: 'extension/browser.js', contents: '' };
|
||||||
|
|
||||||
|
await processor.onFile(file);
|
||||||
|
await processor.onEnd();
|
||||||
|
|
||||||
|
assert.deepEqual(processor.assets, []);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include manifest', async () => {
|
||||||
const manifest = createManifest({ extensionKind: ['web'] });
|
const manifest = createManifest({ extensionKind: ['web'] });
|
||||||
const processor = new WebExtensionProcessor(manifest, { web: true });
|
const processor = new WebExtensionProcessor(manifest, { web: true });
|
||||||
const manifestFile = { path: 'extension/package.json', contents: JSON.stringify(manifest) };
|
const manifestFile = { path: 'extension/package.json', contents: JSON.stringify(manifest) };
|
||||||
|
|
||||||
processor.onFile(manifestFile);
|
await processor.onFile(manifestFile);
|
||||||
|
await processor.onEnd();
|
||||||
|
|
||||||
assert.deepEqual(processor.assets, []);
|
const expected: IAsset[] = [{ type: `Microsoft.VisualStudio.Code.WebResources/${manifestFile.path}`, path: manifestFile.path }];
|
||||||
|
assert.deepEqual(processor.assets, expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should exclude changelog', () => {
|
it('should fail for svg file', async () => {
|
||||||
const manifest = createManifest({ extensionKind: ['web'] });
|
|
||||||
const processor = new WebExtensionProcessor(manifest, { web: true });
|
|
||||||
const changelogFile = { path: 'extension/changelog.md', contents: '' };
|
|
||||||
|
|
||||||
processor.onFile(changelogFile);
|
|
||||||
|
|
||||||
assert.deepEqual(processor.assets, []);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should exclude readme', () => {
|
|
||||||
const manifest = createManifest({ extensionKind: ['web'] });
|
|
||||||
const processor = new WebExtensionProcessor(manifest, { web: true });
|
|
||||||
const readMeFile = { path: 'extension/readme.md', contents: '' };
|
|
||||||
|
|
||||||
processor.onFile(readMeFile);
|
|
||||||
|
|
||||||
assert.deepEqual(processor.assets, []);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should exclude files from node_modules', () => {
|
|
||||||
const manifest = createManifest({ extensionKind: ['web'] });
|
const manifest = createManifest({ extensionKind: ['web'] });
|
||||||
const processor = new WebExtensionProcessor(manifest, { web: true });
|
const processor = new WebExtensionProcessor(manifest, { web: true });
|
||||||
|
|
||||||
processor.onFile({ path: 'extension/node_modules/sample.t.ds', contents: '' });
|
try {
|
||||||
processor.onFile({ path: 'extension/node_modules/a/sample.js', contents: '' });
|
await processor.onFile({ path: 'extension/sample.svg', contents: '' });
|
||||||
processor.onFile({ path: 'extension/node_modules/a/b/c/sample.js', contents: '' });
|
} catch (error) {
|
||||||
|
return; // expected
|
||||||
|
}
|
||||||
|
|
||||||
assert.deepEqual(processor.assets, []);
|
assert.fail('Should fail');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should include max 25 files', async () => {
|
||||||
|
const manifest = createManifest({ extensionKind: ['web'] });
|
||||||
|
const processor = new WebExtensionProcessor(manifest, { web: true });
|
||||||
|
|
||||||
|
const expected: IAsset[] = [];
|
||||||
|
for (let i = 1; i <= 25; i++) {
|
||||||
|
const file = { path: `extension/${i}.json`, contents: `${i}` };
|
||||||
|
await processor.onFile(file);
|
||||||
|
expected.push({ type: `Microsoft.VisualStudio.Code.WebResources/${file.path}`, path: file.path });
|
||||||
|
}
|
||||||
|
|
||||||
|
await processor.onEnd();
|
||||||
|
|
||||||
|
assert.deepEqual(processor.assets.length, 25);
|
||||||
|
assert.deepEqual(processor.assets, expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error if there are more than 25 files', async () => {
|
||||||
|
const manifest = createManifest({ extensionKind: ['web'] });
|
||||||
|
const processor = new WebExtensionProcessor(manifest, { web: true });
|
||||||
|
|
||||||
|
for (let i = 1; i <= 26; i++) {
|
||||||
|
await processor.onFile({ path: `extension/${i}.json`, contents: `${i}` });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await processor.onEnd();
|
||||||
|
} catch (error) {
|
||||||
|
return; // expected error
|
||||||
|
}
|
||||||
|
assert.fail('Should fail');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include web extension property', async () => {
|
||||||
|
const manifest = createManifest({ extensionKind: ['web'] });
|
||||||
|
const processor = new WebExtensionProcessor(manifest, { web: true });
|
||||||
|
|
||||||
|
await processor.onEnd();
|
||||||
|
|
||||||
|
assert.equal(processor.vsix.webExtension, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include web extension property when extension kind is not provided', async () => {
|
||||||
|
const manifest = createManifest({ browser: 'browser.js' });
|
||||||
|
const processor = new WebExtensionProcessor(manifest, { web: true });
|
||||||
|
|
||||||
|
await processor.onEnd();
|
||||||
|
|
||||||
|
assert.equal(processor.vsix.webExtension, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not include web extension property when not asked for', async () => {
|
||||||
|
const manifest = createManifest({ extensionKind: ['web'] });
|
||||||
|
const processor = new WebExtensionProcessor(manifest, { web: false });
|
||||||
|
|
||||||
|
await processor.onEnd();
|
||||||
|
|
||||||
|
assert.equal(processor.vsix.webExtension, undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not include web extension property for non web extension', async () => {
|
||||||
|
const manifest = createManifest({ extensionKind: ['ui'] });
|
||||||
|
const processor = new WebExtensionProcessor(manifest, { web: true });
|
||||||
|
|
||||||
|
await processor.onEnd();
|
||||||
|
|
||||||
|
assert.equal(processor.vsix.webExtension, undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
Loading…
Add table
Reference in a new issue