Make function.json parsing less strict (#409)

This commit is contained in:
Eric Jizba 2018-06-25 14:46:40 -07:00 коммит произвёл GitHub
Родитель 63c8ccdb91
Коммит e416969796
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 54 добавлений и 24 удалений

Просмотреть файл

@ -38,11 +38,13 @@ enum BindingDirection {
export class FunctionConfig {
public readonly functionJson: IFunctionJson;
public readonly disabled: boolean;
public readonly inBinding: IFunctionBinding;
public readonly inBindingType: string;
public readonly isHttpTrigger: boolean = false;
public readonly authLevel: HttpAuthLevel = HttpAuthLevel.function;
private readonly _inBinding: IFunctionBinding | undefined;
private readonly _inBindingType: string | undefined;
private readonly _noInBindingError: Error = new Error(localize('noInBinding', 'Failed to find binding with direction "in" for this function.'));
// tslint:disable-next-line:no-any
public constructor(data: any) {
let errMessage: string | undefined;
@ -55,31 +57,33 @@ export class FunctionConfig {
this.disabled = data.disabled === true;
// tslint:disable-next-line:no-unsafe-any
if (!data.bindings || !(data.bindings instanceof Array) || data.bindings.length === 0) {
if (!data.bindings || !(data.bindings instanceof Array)) {
errMessage = localize('expectedBindings', 'Expected "bindings" element of type "Array".');
} else {
this.functionJson = <IFunctionJson>data;
const inBinding: IFunctionBinding | undefined = this.functionJson.bindings.find((b: IFunctionBinding) => b.direction === BindingDirection.in);
if (inBinding === undefined) {
if (inBinding === undefined && this.functionJson.bindings.length > 0) {
// The generated 'function.json' file for C# class libraries doesn't have direction information (by design), so just use the first
this.inBinding = this.functionJson.bindings[0];
this._inBinding = this.functionJson.bindings[0];
} else {
this.inBinding = inBinding;
this._inBinding = inBinding;
}
if (!this.inBinding.type) {
errMessage = localize('inBindingTypeError', 'The binding with direction "in" must have a type.');
} else {
this.inBindingType = this.inBinding.type;
if (this.inBinding.type.toLowerCase() === 'httptrigger') {
this.isHttpTrigger = true;
if (this.inBinding.authLevel) {
const authLevel: HttpAuthLevel | undefined = <HttpAuthLevel>HttpAuthLevel[this.inBinding.authLevel.toLowerCase()];
if (authLevel === undefined) {
errMessage = localize('unrecognizedAuthLevel', 'Unrecognized auth level "{0}".', this.inBinding.authLevel);
} else {
this.authLevel = authLevel;
if (this._inBinding) {
if (!this._inBinding.type) {
errMessage = localize('inBindingTypeError', 'The binding with direction "in" must have a type.');
} else {
this._inBindingType = this._inBinding.type;
if (this._inBinding.type.toLowerCase() === 'httptrigger') {
this.isHttpTrigger = true;
if (this._inBinding.authLevel) {
const authLevel: HttpAuthLevel | undefined = <HttpAuthLevel>HttpAuthLevel[this._inBinding.authLevel.toLowerCase()];
if (authLevel === undefined) {
errMessage = localize('unrecognizedAuthLevel', 'Unrecognized auth level "{0}".', this._inBinding.authLevel);
} else {
this.authLevel = authLevel;
}
}
}
}
@ -94,4 +98,20 @@ export class FunctionConfig {
throw new Error(localize('functionJsonParseError', 'Failed to parse function.json: {0}', errMessage));
}
}
public get inBinding(): IFunctionBinding {
if (!this._inBinding) {
throw this._noInBindingError;
} else {
return this._inBinding;
}
}
public get inBindingType(): string {
if (!this._inBindingType) {
throw this._noInBindingError;
} else {
return this._inBindingType;
}
}
}

Просмотреть файл

@ -21,12 +21,6 @@ suite('Function Config Tests', () => {
(error: Error) => error.message.includes('bindings')
);
// there's no binding
assert.throws(
() => new FunctionConfig({ bindings: [] }),
(error: Error) => error.message.includes('bindings')
);
// in binding does not have type
assert.throws(
() => new FunctionConfig({
@ -72,6 +66,22 @@ suite('Function Config Tests', () => {
assert.equal(config.disabled, true);
assert.equal(config.isHttpTrigger, false);
assert.equal(config.inBinding.testSetting, 'testValue');
// no bindings (we can still get 'isHttpTrigger' and 'disabled', just not 'inBinding' information)
config = new FunctionConfig({
disabled: true,
bindings: []
});
assert.equal(config.disabled, true);
assert.equal(config.isHttpTrigger, false);
assert.throws(
() => config.inBinding,
(error: Error) => error.message.includes('binding')
);
assert.throws(
() => config.inBindingType,
(error: Error) => error.message.includes('binding')
);
});
test('Http trigger', () => {