Skip to content

Instantly share code, notes, and snippets.

@bryanmacfarlane
Last active March 8, 2022 11:03
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • 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
// }
@mutn3ja
Copy link

mutn3ja commented Sep 9, 2016

It would be better if tsconfig.json contains "exclude" property. this

@colindembovsky
Copy link

I can't get this to work - I get "assert is not a method" when I try to run the mocha tests.

Copy link

ghost commented Oct 15, 2016

So far blocked at this when running tsc on tests files:
_suite.ts(20,12): error TS2339: Property 'Run' does not exist on type 'MockTestRunner'.
_suite.ts(37,12): error TS2339: Property 'Run' does not exist on type 'MockTestRunner'.

@nixel2007
Copy link

@jesaremi type run - lowercased

@jabbera
Copy link

jabbera commented Feb 10, 2017

Having some issues with the sample. Running:
typings install dt~q --global --save

Results in:
typings ERR! message Attempted to compile "q" as a global module, but it looks like an external module. You'll need to remove the global option to continue.

Removing global allows it to install, but now I'm getting the following when running tsc:
typings/modules/q/index.d.ts(10,1): error TS1316: Global module exports may only appear at top level.

@BerendWouters
Copy link

I have the same issue as @jabbera, any solutions to this?

@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