<commit_before>import * as assert from "assert";
import * as vs from "vscode";
import { activate, currentDoc, everythingFile, extApi, getPackages, positionOf, rangeOf } from "../../helpers";

describe("dart_hover_provider", () => {

	// We have tests that read tooltips from external packages so we need to ensure packages have been fetched.
	before("get packages", () => getPackages());
	beforeEach("activate everythingFile", () => activate(everythingFile));

	async function getHoversAt(searchText: string): Promise<Array<{ displayText: string, documentation?: string, range: vs.Range }>> {
		const position = positionOf(searchText);
		const hoverResult = await (vs.commands.executeCommand("vscode.executeHoverProvider", currentDoc().uri, position) as Thenable<vs.Hover[]>);

		// Our hovers are aways in the form:
		// [{ language: "dart", value: data.displayString }, data.documentation || undefined],
		if (hoverResult == null || hoverResult.length === 0)
			return [];

		return hoverResult.map((h) => {

			// TODO: Once VS Code updates (and we require that version), we may be able to simplify this.
			// For the existing VS Code impl we get an array here, but for LSP we return '---' as a separator since
			// we only get a single item. To treat them the same, join with `---` then split on `---`.
			const sections = h.contents.map((c) => ((c as any).value as string).trim()).join("\n---\n").split("\n---\n");
			const displayText = sections[0];
			const docs = sections[1];
			assert.equal(displayText.substr(0, 7), "```dart");
			assert.equal(displayText.substr(-3), "```");
			return {
				displayText: displayText.substring(7, displayText.length - 3).trim(),
				documentation: docs,
				range: h.range,
			};
		});
	}

	// Helper to get just a single hover when exactly one is expected.
	async function getHoverAt(searchText: string): Promise<{ displayText: string, documentation?: string, range: vs.Range }> {
		const hovers = await getHoversAt(searchText);
		assert.equal(hovers.length, 1);
		return hovers[0];
	}

	it("does not return hovers for blank areas of the document", async () => {
		const hovers = await getHoversAt("\n^\n");
		assert.equal(hovers.length, 0);
	});

	it("returns expected information for a class", async () => {
		const hover = await getHoverAt("class My^Class");
		assert.equal(hover.displayText, "class MyClass");
		assert.equal(hover.documentation, "This is my class.");
		assert.deepStrictEqual(hover.range, rangeOf("class |MyClass|"));
	});

	it("returns expected information for a field", async () => {
		const hover = await getHoverAt("num my^NumField");
		assert.equal(hover.displayText, "num myNumField");
		assert.equal(hover.documentation, "This is my num field.");
		assert.deepStrictEqual(hover.range, rangeOf("num |myNumField|"));
	});

	it("returns expected information for a getter", async () => {
		const hover = await getHoverAt("get my^NumGetter");
		assert.equal(hover.displayText, "get myNumGetter → num");
		assert.equal(hover.documentation, "This is my num getter.");
		assert.deepStrictEqual(hover.range, rangeOf("get |myNumGetter|"));
	});

	// tslint:disable-next-line:only-arrow-functions
	it("returns expected information for a setter", async function () {
		// https://github.com/dart-lang/sdk/issues/32703
		if (extApi.analyzerCapabilities.isDart2) {
			this.skip();
			return;
		}

		const hover = await getHoverAt("my^NumSetter(");
		if (extApi.analyzerCapabilities.isDart2) {
			assert.equal(hover.displayText, "set myNumSetter(num value) → void");
		} else {
			assert.equal(hover.displayText, "set myNumSetter(num value) → dynamic");
		}
		assert.equal(hover.documentation, "This is my num setter.");
		assert.deepStrictEqual(hover.range, rangeOf("|myNumSetter|"));
	});

	it("returns expected information for a constructor", async () => {
		const hover = await getHoverAt("My^Class()");
		assert.equal(hover.displayText, "MyClass() → MyClass");
		assert.equal(hover.documentation, "This is my class constructor.");
		assert.deepStrictEqual(hover.range, rangeOf("|MyClass|()"));
	});

	it("returns expected information for a named constructor", async () => {<commit_msg>Remove code that's cause a test to pass that shouldn't<commit_after>import * as assert from "assert";
import * as vs from "vscode";
import { activate, currentDoc, everythingFile, extApi, getPackages, positionOf, rangeOf } from "../../helpers";

describe("dart_hover_provider", () => {

	// We have tests that read tooltips from external packages so we need to ensure packages have been fetched.
	before("get packages", () => getPackages());
	beforeEach("activate everythingFile", () => activate(everythingFile));

	async function getHoversAt(searchText: string): Promise<Array<{ displayText: string, documentation?: string, range: vs.Range }>> {
		const position = positionOf(searchText);
		const hoverResult = await (vs.commands.executeCommand("vscode.executeHoverProvider", currentDoc().uri, position) as Thenable<vs.Hover[]>);

		// Our hovers are aways in the form:
		// [{ language: "dart", value: data.displayString }, data.documentation || undefined],
		if (hoverResult == null || hoverResult.length === 0)
			return [];

		return hoverResult.map((h) => {

			// TODO: Once VS Code updates (and we require that version), we may be able to simplify this.
			// For the existing VS Code impl we get an array here, but for LSP we return '---' as a separator since
			// we only get a single item. To treat them the same, join with `---` then split on `---`.
			const sections = h.contents.map((c) => ((c as any).value as string).trim()).join("\n---\n").split("\n---\n");
			const displayText = sections[0];
			const docs = sections[1];
			assert.equal(displayText.substr(0, 7), "```dart");
			assert.equal(displayText.substr(-3), "```");
			return {
				displayText: displayText.substring(7, displayText.length - 3).trim(),
				documentation: docs,
				range: h.range,
			};
		});
	}

	// Helper to get just a single hover when exactly one is expected.
	async function getHoverAt(searchText: string): Promise<{ displayText: string, documentation?: string, range: vs.Range }> {
		const hovers = await getHoversAt(searchText);
		assert.equal(hovers.length, 1);
		return hovers[0];
	}

	it("does not return hovers for blank areas of the document", async () => {
		const hovers = await getHoversAt("\n^\n");
		assert.equal(hovers.length, 0);
	});

	it("returns expected information for a class", async () => {
		const hover = await getHoverAt("class My^Class");
		assert.equal(hover.displayText, "class MyClass");
		assert.equal(hover.documentation, "This is my class.");
		assert.deepStrictEqual(hover.range, rangeOf("class |MyClass|"));
	});

	it("returns expected information for a field", async () => {
		const hover = await getHoverAt("num my^NumField");
		assert.equal(hover.displayText, "num myNumField");
		assert.equal(hover.documentation, "This is my num field.");
		assert.deepStrictEqual(hover.range, rangeOf("num |myNumField|"));
	});

	it("returns expected information for a getter", async () => {
		const hover = await getHoverAt("get my^NumGetter");
		assert.equal(hover.displayText, "get myNumGetter → num");
		assert.equal(hover.documentation, "This is my num getter.");
		assert.deepStrictEqual(hover.range, rangeOf("get |myNumGetter|"));
	});

	it.only("returns expected information for a setter", async function () {
		// https://github.com/dart-lang/sdk/issues/32703
		if (extApi.analyzerCapabilities.isDart2) {
			this.skip();
			return;
		}

		const hover = await getHoverAt("my^NumSetter(");
		assert.equal(hover.displayText, "set myNumSetter(num value) → void");
		assert.equal(hover.documentation, "This is my num setter.");
		assert.deepStrictEqual(hover.range, rangeOf("|myNumSetter|"));
	});

	it("returns expected information for a constructor", async () => {
		const hover = await getHoverAt("My^Class()");
		assert.equal(hover.displayText, "MyClass() → MyClass");
		assert.equal(hover.documentation, "This is my class constructor.");
		assert.deepStrictEqual(hover.range, rangeOf("|MyClass|()"));
	});

	it("returns expected information for a named constructor", async () => {
{'fraction_non_alphanumeric': 0.15443069003554358, 'fraction_numerical': 0.00428974138987621, 'mean_word_length': 4.524712254570074, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 33, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5521994', 'n_tokens_mistral': 2674, 'n_tokens_neox': 2444, 'n_words': 721}