Skip to content

Instantly share code, notes, and snippets.

@bryanmacfarlane
Last active March 8, 2022 11:03
Show Gist options
  • Save bryanmacfarlane/154f14dd8cb11a71ef04b0c836e5be6e to your computer and use it in GitHub Desktop.
Save bryanmacfarlane/154f14dd8cb11a71ef04b0c836e5be6e to your computer and use it in GitHub Desktop.
VSTS Sample Task
import * as path from 'path';
import * as assert from 'assert';
import * as ttm from 'vsts-task-lib/mock-test';
describe('Sample task tests', function () {
before(() => {
});
after(() => {
});
it('should succeed with simple inputs', (done: MochaDone) => {
this.timeout(1000);
let tp = path.join(__dirname, 'success.js');
let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
tr.Run();
assert(tr.succeeded, 'should have succeeded');
assert.equal(tr.invokedToolCount, 1);
assert.equal(tr.warningIssues.length, 0, "should have no warnings");
assert.equal(tr.errorIssues.length, 0, "should have no errors");
assert(tr.stdout.indexOf('atool output here') >= 0, "tool stdout");
assert(tr.stdout.indexOf('Hello Mock!') >= 0, "task module is called");
done();
});
it('it should fail if tool returns 1', (done: MochaDone) => {
this.timeout(1000);
let tp = path.join(__dirname, 'failrc.js');
let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
tr.Run();
assert(!tr.succeeded, 'should have failed');
assert.equal(tr.invokedToolCount, 1);
assert.equal(tr.warningIssues, 0, "should have no warnings");
assert.equal(tr.errorIssues.length, 1, "should have 1 error issue");
assert.equal(tr.errorIssues[0], '/mocked/tools/echo failed with return code: 1', 'error issue output');
assert(tr.stdout.indexOf('atool output here') >= 0, "tool stdout");
assert.equal(tr.stdout.indexOf('Hello Mock!'), -1, "task module should have never been called");
done();
});
});
import ma = require('vsts-task-lib/mock-answer');
import tmrm = require('vsts-task-lib/mock-run');
import path = require('path');
let taskPath = path.join(__dirname, '..', 'index.js');
let tmr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath);
tmr.setInput('samplestring', "Hello, from task!");
tmr.setInput('samplebool', 'true');
// provide answers for task mock
let a: ma.TaskLibAnswers = <ma.TaskLibAnswers>{
"which": {
"echo": "/mocked/tools/echo"
},
"exec": {
"/mocked/tools/echo Hello, from task!": {
"code": 1,
"stdout": "atool output here",
"stderr": "atool with this stderr output"
}
}
};
tmr.setAnswers(a);
// mock a specific module function called in task
tmr.registerMock('./taskmod', {
sayHello: function() {
console.log('Hello Mock!');
}
});
tmr.run();
import tl = require('vsts-task-lib/task');
import trm = require('vsts-task-lib/toolrunner');
import mod = require('./taskmod');
async function run() {
try {
console.log(process.env["INPUT_SAMPLESTRING"]);
let tool: trm.ToolRunner;
if (process.platform == 'win32') {
let cmdPath = tl.which('cmd');
tool = tl.tool(cmdPath).arg('/c').arg('echo ' + tl.getInput('samplestring', true));
}
else {
let echoPath = tl.which('echo');
tool = tl.tool(echoPath).arg(tl.getInput('samplestring', true));
}
let rc1: number = await tool.exec();
// call some module which does external work
if (rc1 == 0) {
mod.sayHello();
}
console.log('Task done! ' + rc1);
}
catch (err) {
tl.setResult(tl.TaskResult.Failed, err.message);
}
}
run();
{
"id": "{{taskguid}}",
"name": "{{taskname}}",
"friendlyName": "{{taskfriendlyname}}",
"description": "{{taskdescription}}",
"helpMarkDown": "",
"category": "Utility",
"author": "{{taskauthor}}",
"version": {
"Major": 0,
"Minor": 1,
"Patch": 0
},
"instanceNameFormat": "Echo $(samplestring)",
"groups": [
{
"name": "advanced",
"displayName": "Advanced",
"isExpanded": false
}
],
"inputs": [
{
"name": "samplepathinput",
"type": "filePath",
"label": "Sample Path",
"defaultValue": "",
"required": true,
"helpMarkDown": "A sample path which is relative to root of repo if empty"
},
{
"name": "samplestring",
"type": "string",
"label": "Sample String",
"defaultValue": "",
"required": false,
"helpMarkDown": "A sample string"
},
{
"name": "samplebool",
"type": "boolean",
"label": "Sample Boolean",
"defaultValue": "false",
"required": false,
"helpMarkDown": "If this is true, this task will fail if any errors are written to the StandardError stream.",
"groupName": "advanced"
}
],
"execution": {
"Node": {
"target": "index.js"
}
}
}
import ma = require('vsts-task-lib/mock-answer');
import tmrm = require('vsts-task-lib/mock-run');
import path = require('path');
let taskPath = path.join(__dirname, '..', 'index.js');
let tmr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath);
tmr.setInput('samplestring', "Hello, from task!");
tmr.setInput('samplebool', 'true');
// provide answers for task mock
let a: ma.TaskLibAnswers = <ma.TaskLibAnswers>{
"which": {
"echo": "/mocked/tools/echo"
},
"exec": {
"/mocked/tools/echo Hello, from task!": {
"code": 0,
"stdout": "atool output here",
"stderr": "atool with this stderr output"
}
}
};
tmr.setAnswers(a);
// mock a specific module function called in task
tmr.registerMock('./taskmod', {
sayHello: function() {
console.log('Hello Mock!');
}
});
tmr.run();
export function sayHello() {
console.log('Hello World!');
}
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"sourceMap": true
}
}
import tl = require('vsts-task-lib/task');
import trm = require('vsts-task-lib/toolrunner');
import * as apim from 'vso-node-api';
import * as lim from 'vso-node-api/interfaces/LocationsInterfaces';
// console
// export ENDPOINT_URL_SYSTEMVSSCONNECTION=https://youraccount.visualstudio.com
// export ENDPOINT_AUTH_PARAMETER_SYSTEMVSSCONNECTION_ACCESSTOKEN=<yourtoken>
async function run() {
try {
let url = tl.getEndpointUrl('SYSTEMVSSCONNECTION', false);
console.log('Connecting to ' + url);
let token = tl.getEndpointAuthorizationParameter('SYSTEMVSSCONNECTION', 'AccessToken', false);
let auth = token.length == 52 ? apim.getPersonalAccessTokenHandler(token) :
apim.getBearerHandler(token);
let vsts: apim.WebApi = new apim.WebApi(url, auth);
let conn: lim.ConnectionData = await vsts.connect();
console.log('Hello ' + conn.authorizedUser.customDisplayName);
}
catch (err) {
tl.setResult(tl.TaskResult.Failed, err.message);
}
}
run();
//
// "systemConnection": {
// "data": {
// "ServerId": "2f571431-163d-43e3-ac99-1353fb0b5d88",
// "ServerName": "test"
// },
// "name": "SystemVssConnection",
// "url": "https://youraccount.visualstudio.com/",
// "authorization": {
// "parameters": {
// "AccessToken": ********
// },
// "scheme": "OAuth"
// },
// "isReady": false
// }
@bccore
Copy link

bccore commented Apr 10, 2017

I also encountered the same issue with typings install dt~q --global --save
I uninstalled dt~q (typings uninstall dt~q) and installed the npm module (npm install q --save). Seemed to do the trick for me.

Hope this helps.

@bryanmacfarlane
Copy link
Author

step by step updated. We're doing more updates to this gist today.

@riezebosch
Copy link

What a horrible test interface. For all my scenarios it requires me to create a lot of plumbing in separate mock-task-test-files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment