2022-11-28 16:04:53 -08:00
import { Diagnostic , DiagnosticSeverity } from "vscode-languageserver-types" ;
2022-11-21 17:55:24 -08:00
import { createDocument } from "./test-utils/document" ;
import { validate } from "./validate" ;
2022-11-28 16:04:53 -08:00
import { defaultValueProviders } from "./value-providers/default" ;
2023-03-06 15:16:26 -08:00
import { clearCache } from "./utils/workflow-cache" ;
2023-03-20 13:33:58 -04:00
import { ValueProviderConfig , ValueProviderKind } from "./value-providers/config" ;
2023-03-06 11:52:21 -08:00
beforeEach (() => {
2023-03-06 15:16:26 -08:00
clearCache ();
2023-03-06 11:52:21 -08:00
});
2022-11-08 17:00:59 -08:00
describe ( "validation" , () => {
2022-11-21 17:55:24 -08:00
it ( "valid workflow" , async () => {
const result = await validate ( createDocument ( "wf.yaml" , "on: push\njobs:\n build:\n runs-on: ubuntu-latest" ));
2022-11-08 17:00:59 -08:00
2022-11-21 17:55:24 -08:00
expect ( result . length ). toBe ( 0 );
2022-11-08 17:00:59 -08:00
});
2022-11-21 17:55:24 -08:00
it ( "missing jobs key" , async () => {
const result = await validate ( createDocument ( "wf.yaml" , "on: push" ));
2022-11-08 17:00:59 -08:00
2022-11-21 17:55:24 -08:00
expect ( result . length ). toBe ( 1 );
expect ( result [ 0 ]). toEqual ({
message : "Required property is missing: jobs" ,
range : {
start : {
line : 0 ,
character : 0
},
end : {
line : 0 ,
character : 8
}
}
} as Diagnostic );
2022-11-08 17:00:59 -08:00
});
2022-11-21 17:55:24 -08:00
it ( "extraneous key" , async () => {
const result = await validate (
createDocument (
"wf.yaml" ,
`on: push
2022-11-08 17:00:59 -08:00
unknown-key: foo
jobs:
build:
runs-on: ubuntu-latest
steps:
2022-11-15 14:08:12 -05:00
- run: echo`
2022-11-21 17:55:24 -08:00
)
2022-11-08 17:00:59 -08:00
);
2022-11-21 17:55:24 -08:00
expect ( result . length ). toBe ( 1 );
expect ( result [ 0 ]). toEqual ({
message : "Unexpected value 'unknown-key'" ,
range : {
end : {
character : 11 ,
line : 1
},
start : {
character : 0 ,
line : 1
}
}
} as Diagnostic );
2022-11-08 17:00:59 -08:00
});
2022-11-28 16:04:53 -08:00
2022-11-28 16:15:57 -08:00
it ( "single value not returned by suggested value provider" , async () => {
2022-11-28 16:04:53 -08:00
const result = await validate (
createDocument (
"wf.yaml" ,
`on: push
jobs:
build:
runs-on: does-not-exist
steps:
- run: echo`
),
2022-12-13 15:14:57 -05:00
{ valueProviderConfig : defaultValueProviders }
2022-11-28 16:04:53 -08:00
);
2023-01-23 23:11:29 -05:00
expect ( result . length ). toBe ( 0 );
2022-11-28 16:04:53 -08:00
});
it ( "value in sequence not returned by value provider" , async () => {
const result = await validate (
createDocument (
"wf.yaml" ,
`on: push
jobs:
build:
runs-on:
- ubuntu-latest
- does-not-exist
steps:
- run: echo`
),
2022-12-13 15:14:57 -05:00
{ valueProviderConfig : defaultValueProviders }
2022-11-28 16:04:53 -08:00
);
2023-01-23 23:11:29 -05:00
expect ( result . length ). toBe ( 0 );
2022-11-28 16:04:53 -08:00
});
2022-11-28 16:15:57 -08:00
it ( "single value not returned by allowed value provider" , async () => {
const result = await validate (
createDocument (
"wf.yaml" ,
`on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: echo
build:
runs-on: ubuntu-latest
needs: test2
steps:
- run: echo`
),
2022-12-13 15:14:57 -05:00
{ valueProviderConfig : defaultValueProviders }
2022-11-28 16:15:57 -08:00
);
expect ( result [ 0 ]). toEqual ({
message : "Value 'test2' is not valid" ,
severity : DiagnosticSeverity.Error ,
range : {
end : {
character : 16 ,
line : 8
},
start : {
character : 11 ,
line : 8
}
}
} as Diagnostic );
});
2022-12-01 11:37:50 -05:00
it ( "unknown event type" , async () => {
const result = await validate (
createDocument (
"wf.yaml" ,
`on: [push, check_run, pr]
jobs:
build:
runs-on:
- ubuntu-latest`
),
2022-12-13 15:14:57 -05:00
{ valueProviderConfig : defaultValueProviders }
2022-12-01 11:37:50 -05:00
);
expect ( result . length ). toBe ( 1 );
expect ( result [ 0 ]). toEqual ({
message : "Unexpected value 'pr'" ,
range : {
end : {
character : 24 ,
line : 0
},
start : {
character : 22 ,
line : 0
}
}
} as Diagnostic );
});
2023-01-10 09:57:51 -08:00
it ( "invalid cron string" , async () => {
const result = await validate (
createDocument (
"wf.yaml" ,
`on:
schedule:
- cron: '0 0 * *'
jobs:
build:
runs-on: ubuntu-latest`
),
{ valueProviderConfig : defaultValueProviders }
);
expect ( result . length ). toBe ( 1 );
expect ( result [ 0 ]). toEqual ({
message : "Invalid cron string" ,
range : {
end : {
character : 21 ,
line : 2
},
start : {
character : 12 ,
line : 2
}
}
} as Diagnostic );
});
2023-03-08 15:52:33 -05:00
2023-03-14 11:43:28 -04:00
it ( "invalid YAML" , async () => {
// This YAML has some mismatched single-quotes, which causes the string to be terminated early
// within the fromJSON() expression.
// Using double-quotes would make it valid:
// "Run a \${{ inputs.test }} one-line script \${{ fromJSON('test') == inputs.name }}"
const workflow = `
on: push
jobs:
build:
runs-on: ubuntu-latest
environment: TEST
steps:
- name: 'Run a \ ${ { inputs . test } } one-line script \ ${ { fromJSON ( 'test' ) == inputs . name } }'
run: echo
` ;
const result = await validate ( createDocument ( "wf.yaml" , workflow ), { valueProviderConfig : defaultValueProviders });
expect ( result ). toEqual ([
{
message :
"Unexpected scalar at node end at line 8, column 73:\n\n…un a ${{ inputs.test }} one-line script ${{ fromJSON('test') == inputs.name }}'\n ^^^^^^^^^^^^^^^^^^^^^^^^^\n" ,
range : {
start : {
line : 7 ,
character : 72
},
end : {
line : 7 ,
character : 97
}
}
}
]);
2023-03-14 11:46:44 -04:00
const cachedResult = await validate ( createDocument ( "wf.yaml" , workflow ), {
valueProviderConfig : defaultValueProviders
});
expect ( cachedResult ). toEqual ( result );
2023-03-14 11:43:28 -04:00
});
2023-03-08 15:52:33 -05:00
describe ( "value provider case sensitivity" , () => {
it ( "value with a different case and case sensitive provider" , async () => {
const workflow = `
on: push
jobs:
build:
runs-on: ubuntu-latest
environment: TEST
steps:
- run: echo
` ;
const valueProviderConfig : ValueProviderConfig = {
"job-environment" : {
kind : ValueProviderKind.AllowedValues ,
2023-03-20 13:33:58 -04:00
get : () => Promise . resolve ([{ label : "test" }]),
2023-03-08 15:52:33 -05:00
caseInsensitive : false
}
};
const result = await validate ( createDocument ( "wf.yaml" , workflow ), { valueProviderConfig });
expect ( result ). toEqual ([
{
message : "Value 'TEST' is not valid" ,
severity : DiagnosticSeverity.Error ,
range : {
start : {
line : 5 ,
character : 19
},
end : {
line : 5 ,
character : 23
}
}
}
]);
});
it ( "value with a different case and case insensitive provider" , async () => {
const workflow = `
on: push
jobs:
build:
runs-on: ubuntu-latest
environment: TEST
steps:
- run: echo
` ;
const valueProviderConfig : ValueProviderConfig = {
"job-environment" : {
kind : ValueProviderKind.AllowedValues ,
2023-03-20 13:33:58 -04:00
get : () => Promise . resolve ([{ label : "test" }]),
2023-03-08 15:52:33 -05:00
caseInsensitive : true
}
};
const result = await validate ( createDocument ( "wf.yaml" , workflow ), { valueProviderConfig });
expect ( result ). toEqual ([]);
});
});
2022-11-08 17:00:59 -08:00
});