| /*--------------------------------------------------------- |
| * Copyright (C) Microsoft Corporation. All rights reserved. |
| * Licensed under the MIT License. See License.txt in the project root for license information. |
| *--------------------------------------------------------*/ |
| |
| import assert from 'assert'; |
| import sinon = require('sinon'); |
| import vscode = require('vscode'); |
| import goLanguageServer = require('../../src/language/goLanguageServer'); |
| import goSurvey = require('../../src/goSurvey'); |
| import goDeveloperSurvey = require('../../src/goDeveloperSurvey'); |
| |
| suite('gopls survey tests', () => { |
| test('prompt for survey', () => { |
| // global state -> offer survey |
| const testCases: [goSurvey.GoplsSurveyConfig, boolean | undefined][] = [ |
| // User who is activating the extension for the first time. |
| [{}, true], |
| // User who has already taken the survey. |
| [ |
| { |
| lastDateAccepted: new Date('2020-04-02'), |
| dateComputedPromptThisMonth: new Date('2020-04-10'), |
| lastDatePrompted: new Date('2020-04-02'), |
| prompt: true, |
| promptThisMonth: false |
| }, |
| undefined |
| ], |
| // User who has declined survey prompting. |
| [ |
| { |
| dateComputedPromptThisMonth: new Date('2020-04-10'), |
| lastDatePrompted: new Date('2020-04-02'), |
| prompt: false |
| }, |
| undefined |
| ], |
| // User who hasn't activated the extension in a while, but has opted in to prompting. |
| [ |
| { |
| dateComputedPromptThisMonth: new Date('2019-04-10'), |
| lastDatePrompted: new Date('2019-01-02'), |
| prompt: true |
| }, |
| true |
| ], |
| // User who hasn't activated the extension in a while, and has never been prompted. |
| [ |
| { |
| dateComputedPromptThisMonth: new Date('2019-04-10'), |
| lastDatePrompted: new Date('2019-01-02') |
| }, |
| true |
| ], |
| // User who should get prompted this month, but hasn't been yet. |
| [ |
| { |
| lastDateAccepted: undefined, |
| dateComputedPromptThisMonth: new Date('2020-04-10'), |
| lastDatePrompted: new Date('2019-01-02'), |
| prompt: true, |
| promptThisMonth: true |
| }, |
| true |
| ] |
| ]; |
| testCases.map(([testConfig, wantPrompt], i) => { |
| // Replace Math.Random so that it always returns 0. This means |
| // that we will always choose to prompt, in the event that the |
| // user can be prompted that month. |
| sinon.replace(Math, 'random', () => 0); |
| |
| const now = new Date('2020-04-29'); |
| const gotPrompt = goSurvey.shouldPromptForSurvey(now, testConfig); |
| if (wantPrompt) { |
| assert.ok(gotPrompt, `prompt determination failed for ${i}`); |
| } else { |
| assert.equal(gotPrompt, wantPrompt, `prompt determination failed for ${i}`); |
| } |
| sinon.restore(); |
| }); |
| }); |
| }); |
| |
| suite('developer survey tests', () => { |
| test('inRange', () => { |
| // start, end, date => inRange |
| const testCases: [Date, Date, Date, boolean][] = [ |
| [new Date('2021-09-01'), new Date('2021-11-10'), new Date('2021-10-31'), true], |
| [new Date('2021-09-01'), new Date('2021-11-10'), new Date('2020-10-31'), false], |
| [new Date('2021-09-01'), new Date('2021-11-10'), new Date('2022-10-31'), false] |
| ]; |
| testCases.map(([start, end, date, want]) => { |
| const got = goDeveloperSurvey.inDateRange(start, end, date); |
| assert.equal(got, want, `expected inRange(${start}, ${end}, ${date} = ${want}, got: ${got})`); |
| }); |
| }); |
| |
| test('prompt for survey', () => { |
| // global state -> offer survey |
| const testCases: [goDeveloperSurvey.DeveloperSurveyConfig, boolean | undefined][] = [ |
| // User who is activating the extension for the first time. |
| [{}, true], |
| // User who has already taken the survey. |
| [ |
| { |
| lastDateAccepted: new Date('2020-04-02'), |
| datePromptComputed: new Date('2020-04-02'), |
| lastDatePrompted: new Date('2020-04-02'), |
| prompt: true |
| }, |
| undefined |
| ], |
| // User who has declined survey prompting. |
| [ |
| { |
| datePromptComputed: new Date('2020-04-10'), |
| lastDatePrompted: new Date('2020-04-02'), |
| prompt: false |
| }, |
| undefined |
| ], |
| // User who has opted into prompting, but hasn't opened the |
| // extension in a while. |
| [ |
| { |
| datePromptComputed: new Date('2019-04-10'), |
| lastDatePrompted: new Date('2019-04-10'), |
| prompt: true |
| }, |
| true |
| ], |
| // User who has opted into prompting, but has been prompted < 5 |
| // days ago. |
| [ |
| { |
| datePromptComputed: new Date('2019-04-27'), |
| lastDatePrompted: new Date('2019-04-28'), |
| prompt: true |
| }, |
| true |
| ], |
| // User accepted the survey a year ago. |
| [ |
| { |
| datePromptComputed: new Date('2018-04-27'), |
| lastDatePrompted: new Date('2018-04-28'), |
| prompt: true, |
| lastDateAccepted: new Date('2018-04-28') |
| }, |
| true |
| ], |
| // User declined the survey a year ago. |
| [ |
| { |
| datePromptComputed: new Date('2018-04-27'), |
| lastDatePrompted: new Date('2018-04-28'), |
| prompt: false |
| }, |
| true |
| ] |
| ]; |
| testCases.map(([testConfig, wantPrompt], i) => { |
| // Replace Math.Random so that it always returns a value less than |
| // 0.2. This means that we will always choose to prompt, in the |
| // event that the user can be prompted that month. |
| sinon.replace(Math, 'random', () => 0); |
| |
| sinon.replace(goDeveloperSurvey, 'startDate', new Date('2020-03-10')); |
| sinon.replace(goDeveloperSurvey, 'endDate', new Date('2020-07-10')); |
| |
| const now = new Date('2020-04-29'); |
| const gotPrompt = goDeveloperSurvey.shouldPromptForSurvey(now, testConfig); |
| if (wantPrompt) { |
| assert.ok(gotPrompt, `prompt determination failed for ${i}: expected ${wantPrompt}, got ${gotPrompt}`); |
| } else { |
| assert.equal( |
| gotPrompt, |
| wantPrompt, |
| `prompt determination failed for ${i}: expected undefined, got ${gotPrompt}` |
| ); |
| } |
| sinon.restore(); |
| }); |
| }); |
| }); |
| |
| suite('gopls opt out', () => { |
| let sandbox: sinon.SinonSandbox; |
| |
| setup(() => { |
| sandbox = sinon.createSandbox(); |
| }); |
| |
| teardown(() => { |
| sandbox.restore(); |
| }); |
| |
| const today = new Date(); |
| const yesterday = new Date(today.valueOf() - 1000 * 60 * 60 * 24); |
| |
| // testConfig, choice, wantCount |
| const testCases: [goLanguageServer.GoplsOptOutConfig, string, number][] = [ |
| // No saved config, different choices in the first dialog box. |
| [{}, 'Yes', 1], |
| [{}, 'No', 1], |
| [{}, '', 1], |
| [{ lastDatePrompted: new Date('2020-04-02') }, '', 1], |
| [{ lastDatePrompted: yesterday }, '', 0], |
| [{ prompt: false }, '', 0], |
| [{ prompt: false, lastDatePrompted: new Date('2020-04-02') }, '', 0], |
| [{ prompt: false, lastDatePrompted: yesterday }, '', 0], |
| [{ prompt: true }, '', 1], |
| [{ prompt: true, lastDatePrompted: new Date('2020-04-02') }, 'Yes', 1], |
| [{ prompt: true, lastDatePrompted: yesterday }, '', 0] |
| ]; |
| |
| testCases.map(async ([testConfig, choice, wantCount], i) => { |
| test(`opt out: ${i}`, async () => { |
| const stub = sandbox.stub(vscode.window, 'showInformationMessage').resolves({ title: choice }); |
| const getGoplsOptOutConfigStub = sandbox.stub(goLanguageServer, 'getGoplsOptOutConfig').returns(testConfig); |
| const flushGoplsOptOutConfigStub = sandbox.stub(goLanguageServer, 'flushGoplsOptOutConfig'); |
| sandbox.stub(vscode.env, 'openExternal').resolves(true); |
| |
| await goLanguageServer.promptAboutGoplsOptOut({}); |
| assert.strictEqual(stub.callCount, wantCount, 'unexpected call count'); |
| sandbox.assert.called(getGoplsOptOutConfigStub); |
| sandbox.assert.calledOnce(flushGoplsOptOutConfigStub); |
| const got = flushGoplsOptOutConfigStub.getCall(0).args[0]; |
| if (choice === 'Yes') assert.strictEqual(got.prompt, false, 'unexpected prompt config stored'); |
| if (wantCount > 0) |
| assert( |
| got.lastDatePrompted && got.lastDatePrompted >= today, |
| `unexpected lastDatePrompted: ${JSON.stringify(got.lastDatePrompted)}` |
| ); |
| }); |
| }); |
| }); |