From 139d2c9a84d8ed5584fa69954a4da6e7f6dce4f9 Mon Sep 17 00:00:00 2001 From: Remy Suen Date: Sun, 27 Aug 2017 07:21:37 +0900 Subject: [PATCH] WIP #162 Add signature help for LABEL Signed-off-by: Remy Suen --- CHANGELOG.md | 1 + src/dockerPlainText.ts | 14 +++ src/dockerSignatures.ts | 107 ++++++++++++++++++ src/parser/property.ts | 28 ++++- test/dockerSignatures.tests.ts | 195 +++++++++++++++++++++++++++++++++ 5 files changed, 344 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b271696..cd6cb90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ All notable changes to this project will be documented in this file. - ARG - EXPOSE - FROM + - LABEL - SHELL - STOPSIGNAL - USER diff --git a/src/dockerPlainText.ts b/src/dockerPlainText.ts index f277f24..c2f4d6c 100644 --- a/src/dockerPlainText.ts +++ b/src/dockerPlainText.ts @@ -53,6 +53,9 @@ export class PlainTextDocumentation { "signatureFrom_Signature3_Param2": "The name of this build stage.", "signatureFrom_Param2": "The name of this build stage.", "signatureHealthcheck": "Define how Docker should test the container to check that it is still working.", + "signatureLabel_Signature0": "Set metadata to an image.", + "signatureLabel_Signature0_Param0": "The name of the metadata.", + "signatureLabel_Signature0_Param1": "The value of the metadata.", "signatureShell": "Override default shell used for the shell form of commands.", "signatureShell_Param1": "The shell executable to use.", "signatureShell_Param2": "The parameters to the shell executable.", @@ -227,6 +230,17 @@ export class PlainTextDocumentation { signatureHealthcheckFlagRetries_Param: this.dockerMessages["hoverHealthcheckFlagRetries"], signatureHealthcheckFlagStartPeriod_Param: this.dockerMessages["hoverHealthcheckFlagStartPeriod"], signatureHealthcheckFlagTimeout_Param: this.dockerMessages["hoverHealthcheckFlagTimeout"], + signatureLabel_Signature0: this.dockerMessages["signatureLabel_Signature0"], + signatureLabel_Signature0_Param0: this.dockerMessages["signatureLabel_Signature0_Param0"], + signatureLabel_Signature0_Param1: this.dockerMessages["signatureLabel_Signature0_Param1"], + signatureLabel_Signature1: this.dockerMessages["signatureLabel_Signature0"], + signatureLabel_Signature1_Param0: this.dockerMessages["signatureLabel_Signature0_Param0"], + signatureLabel_Signature1_Param1: this.dockerMessages["signatureLabel_Signature0_Param1"], + signatureLabel_Signature2: this.dockerMessages["signatureLabel_Signature0"], + signatureLabel_Signature2_Param0: this.dockerMessages["signatureLabel_Signature0_Param0"], + signatureLabel_Signature2_Param1: this.dockerMessages["signatureLabel_Signature0_Param1"], + signatureLabel_Signature2_Param2: this.dockerMessages["signatureLabel_Signature0_Param0"], + signatureLabel_Signature2_Param3: this.dockerMessages["signatureLabel_Signature0_Param1"], signatureShell: this.dockerMessages["signatureShell"], signatureShell_Param1: this.dockerMessages["signatureShell_Param1"], signatureShell_Param2: this.dockerMessages["signatureShell_Param2"], diff --git a/src/dockerSignatures.ts b/src/dockerSignatures.ts index 0257ef5..e6cc31c 100644 --- a/src/dockerSignatures.ts +++ b/src/dockerSignatures.ts @@ -8,10 +8,12 @@ import { import { Dockerfile } from './parser/dockerfile'; import { Argument } from './parser/argument'; import { Instruction } from './parser/instruction'; +import { Property } from './parser/property'; import { Arg } from './parser/instructions/arg'; import { Copy } from './parser/instructions/copy'; import { From } from './parser/instructions/from'; import { Healthcheck } from './parser/instructions/healthcheck'; +import { Label } from './parser/instructions/label'; import { Shell } from './parser/instructions/shell'; import { PlainTextDocumentation } from './dockerPlainText'; import { DockerfileParser } from './parser/dockerfileParser'; @@ -156,6 +158,60 @@ export class DockerSignatures { } } break; + case "LABEL": + const labelSignatures = [ + { + label: "LABEL key value", + documentation: this.documentation.getDocumentation("signatureLabel_Signature0"), + parameters: [ + { + label: "key", + documentation: this.documentation.getDocumentation("signatureLabel_Signature0_Param0") + }, + { + label: "value", + documentation: this.documentation.getDocumentation("signatureLabel_Signature0_Param1") + } + ] + }, + { + label: "LABEL key=value", + documentation: this.documentation.getDocumentation("signatureLabel_Signature1"), + parameters: [ + { + label: "key", + documentation: this.documentation.getDocumentation("signatureLabel_Signature1_Param0") + }, + { + label: "value", + documentation: this.documentation.getDocumentation("signatureLabel_Signature1_Param1") + } + ] + }, + { + label: "LABEL key=value key2=value2", + documentation: this.documentation.getDocumentation("signatureLabel_Signature2"), + parameters: [ + { + label: "key", + documentation: this.documentation.getDocumentation("signatureLabel_Signature2_Param0") + }, + { + label: "value", + documentation: this.documentation.getDocumentation("signatureLabel_Signature2_Param1") + }, + { + label: "key2", + documentation: this.documentation.getDocumentation("signatureLabel_Signature2_Param2") + }, + { + label: "value2", + documentation: this.documentation.getDocumentation("signatureLabel_Signature2_Param3") + } + ] + } + ]; + return this.getPropertySignatureHelp(document, position, labelSignatures, (instruction as Label).getProperties()); case "EXPOSE": let exposeSignatureHelp = { signatures: [ @@ -624,4 +680,55 @@ export class DockerSignatures { } return inTag || inDigest ? 1 : 0; } + + private getPropertySignatureHelp(document: TextDocument, position: Position, signatures: SignatureInformation[], properties: Property[]): SignatureHelp { + return { + signatures: this.getPropertySignatures(document, position, signatures, properties), + activeSignature: 0, + activeParameter: this.getPropertySignatureActiveParameter(document, position, signatures, properties) + }; + } + + private getPropertySignatures(document: TextDocument, position: Position, signatures: SignatureInformation[], properties: Property[]): SignatureInformation[] { + if (properties.length === 0) { + return signatures; + } else if (properties.length === 1) { + const valueRange = properties[0].getValueRange(); + if (valueRange === null) { + return properties[0].isNameBefore(position) ? [ signatures[0] ] : signatures; + } + + const delimiter = document.getText().substring(document.offsetAt(properties[0].getNameRange().end), document.offsetAt(valueRange.start)); + if (delimiter.indexOf('=') === -1) { + return [ signatures[0] ]; + } else if (properties[0].isValueBefore(position)) { + return [ signatures[2] ]; + } + } else { + return [ signatures[2] ]; + } + return [ signatures[1], signatures[2] ]; + } + + private getPropertySignatureActiveParameter(document: TextDocument, position: Position, signatures: SignatureInformation[], properties: Property[]): number { + if (properties.length === 0) { + return 0; + } + + for (let i = properties.length - 1; i > 0; i--) { + if (properties[i].isInValue(position)) { + return 3; + } else if (properties[i].isNameBefore(position) || properties[i].isInName(position)) { + return 2; + } + } + + if (properties[0].isInValue(position)) { + return 1; + } else if (properties[0].isValueBefore(position)) { + const delimiter = document.getText().substring(document.offsetAt(properties[0].getNameRange().end), document.offsetAt(properties[0].getValueRange().start)); + return delimiter.indexOf('=') === -1 ? 1 : 2; + } + return properties[0].isNameBefore(position) ? 1 : 0; + } } \ No newline at end of file diff --git a/src/parser/property.ts b/src/parser/property.ts index 6565fb1..38abcf1 100644 --- a/src/parser/property.ts +++ b/src/parser/property.ts @@ -2,7 +2,7 @@ * Copyright (c) Remy Suen. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ -import { TextDocument, Range } from 'vscode-languageserver'; +import { TextDocument, Range, Position } from 'vscode-languageserver'; import { Argument } from './argument'; import { Util } from '../docker'; @@ -59,6 +59,32 @@ export class Property { return this.valueRange; } + public isInName(position: Position): boolean { + return Util.isInsideRange(position, this.nameRange); + } + + public isNameBefore(position: Position): boolean { + if (this.isInName(position)) { + return false; + } else if (this.nameRange.start.line < position.line) { + return true; + } + return this.nameRange.start.line === position.line ? this.nameRange.end.character < position.character : false; + } + + public isValueBefore(position: Position): boolean { + if (this.valueRange === null) { + return false; + } else if (this.valueRange.start.line < position.line) { + return true; + } + return this.valueRange.start.line === position.line ? this.valueRange.end.character < position.character : false; + } + + public isInValue(position: Position): boolean { + return this.valueRange === null ? false : Util.isInsideRange(position, this.valueRange); + } + public getRawValue(): string { let rawValue = ""; let value = this.document.getText().substring(this.document.offsetAt(this.valueRange.start), this.document.offsetAt(this.valueRange.end)); diff --git a/test/dockerSignatures.tests.ts b/test/dockerSignatures.tests.ts index eb7e12a..0686180 100644 --- a/test/dockerSignatures.tests.ts +++ b/test/dockerSignatures.tests.ts @@ -301,6 +301,82 @@ function assertFrom_Digests_BuildStages_Only(signatureHelp: SignatureHelp, activ assertFrom_ImageDigest_BuildStage(signatureHelp.signatures[0]); } +function assertLabel_Space(signature: SignatureInformation) { + assert.equal(signature.label, "LABEL key value"); + assert.notEqual(signature.documentation, null); + assert.equal(signature.documentation, docs.getDocumentation("signatureLabel_Signature0")); + assert.equal(signature.parameters.length, 2); + assert.equal(signature.parameters[0].label, "key"); + assert.notEqual(signature.parameters[0].documentation, null); + assert.equal(signature.parameters[0].documentation, docs.getDocumentation("signatureLabel_Signature0_Param0")); + assert.equal(signature.parameters[1].label, "value"); + assert.notEqual(signature.parameters[1].documentation, null); + assert.equal(signature.parameters[1].documentation, docs.getDocumentation("signatureLabel_Signature0_Param1")); +} + +function assertLabel_EqualsSingle(signature: SignatureInformation) { + assert.equal(signature.label, "LABEL key=value"); + assert.notEqual(signature.documentation, null); + assert.equal(signature.documentation, docs.getDocumentation("signatureLabel_Signature1")); + assert.equal(signature.parameters.length, 2); + assert.equal(signature.parameters[0].label, "key"); + assert.notEqual(signature.parameters[0].documentation, null); + assert.equal(signature.parameters[0].documentation, docs.getDocumentation("signatureLabel_Signature1_Param0")); + assert.equal(signature.parameters[1].label, "value"); + assert.notEqual(signature.parameters[1].documentation, null); + assert.equal(signature.parameters[1].documentation, docs.getDocumentation("signatureLabel_Signature1_Param1")); +} + +function assertLabel_EqualsMulti(signature: SignatureInformation) { + assert.equal(signature.label, "LABEL key=value key2=value2"); + assert.notEqual(signature.documentation, null); + assert.equal(signature.documentation, docs.getDocumentation("signatureLabel_Signature2")); + assert.equal(signature.parameters.length, 4); + assert.equal(signature.parameters[0].label, "key"); + assert.notEqual(signature.parameters[0].documentation, null); + assert.equal(signature.parameters[0].documentation, docs.getDocumentation("signatureLabel_Signature2_Param0")); + assert.equal(signature.parameters[1].label, "value"); + assert.notEqual(signature.parameters[1].documentation, null); + assert.equal(signature.parameters[1].documentation, docs.getDocumentation("signatureLabel_Signature2_Param1")); + assert.equal(signature.parameters[2].label, "key2"); + assert.notEqual(signature.parameters[2].documentation, null); + assert.equal(signature.parameters[2].documentation, docs.getDocumentation("signatureLabel_Signature2_Param2")); + assert.equal(signature.parameters[3].label, "value2"); + assert.notEqual(signature.parameters[3].documentation, null); + assert.equal(signature.parameters[3].documentation, docs.getDocumentation("signatureLabel_Signature2_Param3")); +} + +function assertLabel(signatureHelp: SignatureHelp) { + assert.equal(signatureHelp.signatures.length, 3); + assert.equal(signatureHelp.activeSignature, 0); + assert.equal(signatureHelp.activeParameter, 0); + assertLabel_Space(signatureHelp.signatures[0]); + assertLabel_EqualsSingle(signatureHelp.signatures[1]); + assertLabel_EqualsMulti(signatureHelp.signatures[2]); +} + +function assertLabel_SpaceOnly(signatureHelp: SignatureHelp, activeParameter: number) { + assert.equal(signatureHelp.signatures.length, 1); + assert.equal(signatureHelp.activeSignature, 0); + assert.equal(signatureHelp.activeParameter, activeParameter); + assertLabel_Space(signatureHelp.signatures[0]); +} + +function assertLabel_Equals(signatureHelp: SignatureHelp, activeParameter: number) { + assert.equal(signatureHelp.signatures.length, 2); + assert.equal(signatureHelp.activeSignature, 0); + assert.equal(signatureHelp.activeParameter, activeParameter); + assertLabel_EqualsSingle(signatureHelp.signatures[0]); + assertLabel_EqualsMulti(signatureHelp.signatures[1]); +} + +function assertLabel_EqualsMultiOnly(signatureHelp: SignatureHelp, activeParameter: number) { + assert.equal(signatureHelp.signatures.length, 1); + assert.equal(signatureHelp.activeSignature, 0); + assert.equal(signatureHelp.activeParameter, activeParameter); + assertLabel_EqualsMulti(signatureHelp.signatures[0]); +} + function assertShell(signatureHelp: SignatureHelp, activeParameter: number) { assert.equal(signatureHelp.activeSignature, 0); assert.equal(signatureHelp.activeParameter, activeParameter); @@ -874,6 +950,124 @@ describe("Dockerfile Signature Tests", function() { testHealthcheck(false); + function testLabel(trigger: boolean) { + let onbuild = trigger ? "ONBUILD " : ""; + let triggerOffset = trigger ? 8 : 0; + + describe("LABEL", function() { + it("all", function() { + assertLabel(compute(onbuild + "LABEL ", 0, triggerOffset + 6)); + + assertLabel(compute(onbuild + "LABEL key", 0, triggerOffset + 6)); + assertLabel(compute(onbuild + "LABEL key", 0, triggerOffset + 7)); + assertLabel(compute(onbuild + "LABEL key", 0, triggerOffset + 9)); + + assertLabel(compute(onbuild + "LABEL key", 0, triggerOffset + 6)); + + assertLabel(compute(onbuild + "LABEL key ", 0, triggerOffset + 6)); + assertLabel(compute(onbuild + "LABEL key ", 0, triggerOffset + 9)); + }); + + it("space", function() { + assertLabel_SpaceOnly(compute(onbuild + "LABEL key ", 0, triggerOffset + 10), 1); + + assertLabel_SpaceOnly(compute(onbuild + "LABEL key value", 0, triggerOffset + 6), 0); + assertLabel_SpaceOnly(compute(onbuild + "LABEL key value", 0, triggerOffset + 9), 0); + assertLabel_SpaceOnly(compute(onbuild + "LABEL key value", 0, triggerOffset + 10), 1); + assertLabel_SpaceOnly(compute(onbuild + "LABEL key value", 0, triggerOffset + 12), 1); + assertLabel_SpaceOnly(compute(onbuild + "LABEL key value", 0, triggerOffset + 15), 1); + + assertLabel_SpaceOnly(compute(onbuild + "LABEL key =value", 0, triggerOffset + 6), 0); + assertLabel_SpaceOnly(compute(onbuild + "LABEL key =value", 0, triggerOffset + 9), 0); + assertLabel_SpaceOnly(compute(onbuild + "LABEL key =value", 0, triggerOffset + 10), 1); + assertLabel_SpaceOnly(compute(onbuild + "LABEL key =value", 0, triggerOffset + 11), 1); + assertLabel_SpaceOnly(compute(onbuild + "LABEL key =value", 0, triggerOffset + 13), 1); + assertLabel_SpaceOnly(compute(onbuild + "LABEL key =value", 0, triggerOffset + 16), 1); + + assertLabel_SpaceOnly(compute(onbuild + "LABEL key value ", 0, triggerOffset + 16), 1); + + assertLabel_SpaceOnly(compute(onbuild + "LABEL key value spaced", 0, triggerOffset + 6), 0); + assertLabel_SpaceOnly(compute(onbuild + "LABEL key value spaced", 0, triggerOffset + 9), 0); + assertLabel_SpaceOnly(compute(onbuild + "LABEL key value spaced", 0, triggerOffset + 10), 1); + assertLabel_SpaceOnly(compute(onbuild + "LABEL key value spaced", 0, triggerOffset + 12), 1); + assertLabel_SpaceOnly(compute(onbuild + "LABEL key value spaced", 0, triggerOffset + 15), 1); + assertLabel_SpaceOnly(compute(onbuild + "LABEL key value spaced", 0, triggerOffset + 16), 1); + assertLabel_SpaceOnly(compute(onbuild + "LABEL key value spaced", 0, triggerOffset + 18), 1); + assertLabel_SpaceOnly(compute(onbuild + "LABEL key value spaced", 0, triggerOffset + 22), 1); + }); + + it("equals", function() { + assertLabel_Equals(compute(onbuild + "LABEL key=", 0, triggerOffset + 6), 0); + assertLabel_Equals(compute(onbuild + "LABEL key=", 0, triggerOffset + 7), 0); + assertLabel_Equals(compute(onbuild + "LABEL key=", 0, triggerOffset + 9), 0); + assertLabel_Equals(compute(onbuild + "LABEL key=", 0, triggerOffset + 10), 1); + + assertLabel_Equals(compute(onbuild + "LABEL key=value", 0, triggerOffset + 6), 0); + assertLabel_Equals(compute(onbuild + "LABEL key=value", 0, triggerOffset + 9), 0); + assertLabel_Equals(compute(onbuild + "LABEL key=value", 0, triggerOffset + 10), 1); + assertLabel_Equals(compute(onbuild + "LABEL key=value", 0, triggerOffset + 12), 1); + assertLabel_Equals(compute(onbuild + "LABEL key=value", 0, triggerOffset + 15), 1); + }); + + it("equals multiples", function() { + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value ", 0, triggerOffset + 16), 2); + + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2", 0, triggerOffset + 6), 0); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2", 0, triggerOffset + 9), 0); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2", 0, triggerOffset + 10), 1); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2", 0, triggerOffset + 12), 1); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2", 0, triggerOffset + 15), 1); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2", 0, triggerOffset + 16), 2); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2", 0, triggerOffset + 18), 2); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2", 0, triggerOffset + 20), 2); + + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=", 0, triggerOffset + 6), 0); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=", 0, triggerOffset + 9), 0); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=", 0, triggerOffset + 10), 1); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=", 0, triggerOffset + 12), 1); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=", 0, triggerOffset + 15), 1); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=", 0, triggerOffset + 16), 2); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=", 0, triggerOffset + 18), 2); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=", 0, triggerOffset + 20), 2); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=", 0, triggerOffset + 21), 3); + + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2", 0, triggerOffset + 6), 0); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2", 0, triggerOffset + 9), 0); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2", 0, triggerOffset + 10), 1); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2", 0, triggerOffset + 12), 1); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2", 0, triggerOffset + 15), 1); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2", 0, triggerOffset + 16), 2); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2", 0, triggerOffset + 18), 2); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2", 0, triggerOffset + 20), 2); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2", 0, triggerOffset + 21), 3); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2", 0, triggerOffset + 24), 3); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2", 0, triggerOffset + 27), 3); + + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2 ", 0, triggerOffset + 28), 2); + + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2 key3=value3", 0, triggerOffset + 6), 0); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2 key3=value3", 0, triggerOffset + 9), 0); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2 key3=value3", 0, triggerOffset + 10), 1); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2 key3=value3", 0, triggerOffset + 12), 1); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2 key3=value3", 0, triggerOffset + 15), 1); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2 key3=value3", 0, triggerOffset + 16), 2); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2 key3=value3", 0, triggerOffset + 18), 2); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2 key3=value3", 0, triggerOffset + 20), 2); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2 key3=value3", 0, triggerOffset + 21), 3); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2 key3=value3", 0, triggerOffset + 24), 3); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2 key3=value3", 0, triggerOffset + 27), 3); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2 key3=value3", 0, triggerOffset + 28), 2); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2 key3=value3", 0, triggerOffset + 30), 2); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2 key3=value3", 0, triggerOffset + 32), 2); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2 key3=value3", 0, triggerOffset + 33), 3); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2 key3=value3", 0, triggerOffset + 36), 3); + assertLabel_EqualsMultiOnly(compute(onbuild + "LABEL key=value key2=value2 key3=value3", 0, triggerOffset + 39), 3); + }); + }); + } + + testLabel(false); + function testShell(trigger: boolean) { let onbuild = trigger ? "ONBUILD " : ""; let triggerOffset = trigger ? 8 : 0; @@ -1091,6 +1285,7 @@ describe("Dockerfile Signature Tests", function() { testCopy(true); testExpose(true); testHealthcheck(true); + testLabel(true); testShell(true); testStopsignal(true); testUser(true);