<commit_before>// Copyright 2018 Google Inc. Use of this source code is governed by an
// MIT-style license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

import 'package:path/path.dart' as p;
import 'package:test/test.dart';
import 'package:test_descriptor/test_descriptor.dart' as d;
import 'package:test_process/test_process.dart';

import '../../utils.dart';

/// Defines test that are shared between the Dart and Node.js CLI test suites.
void sharedTests(Future<TestProcess> runSass(Iterable<String> arguments)) {
  test("--poll may not be passed without --watch", () async {
    var sass = await runSass(["--poll", "-"]);
    await expectLater(
        sass.stdout, emits("--poll may not be passed without --watch."));
    expect(
        sass.stdout, emitsThrough(contains("Print this usage information.")));
    await sass.shouldExit(64);
  });

  for (var poll in [true, false]) {
    Future<TestProcess> watch(Iterable<String> arguments) => runSass(
        ["--no-source-map", "--watch", ...arguments, if (poll) "--poll"]);

    /// Returns a future that completes after a delay if [poll] is `true`.
    ///
    /// Modifying a file very quickly after it was processed can go
    /// unrecognized, especially on Windows where filesystem operations can have
    /// very high delays.
    Future<void> tickIfPoll() => poll ? tick : Future.value();

    group("${poll ? 'with' : 'without'} --poll", () {
      group("when started", () {
        test("updates a CSS file whose source was modified", () async {
          await d.file("out.css", "x {y: z}").create();
          await tick;
          await d.file("test.scss", "a {b: c}").create();

          var sass = await watch(["test.scss:out.css"]);
          await expectLater(
              sass.stdout, emits('Compiled test.scss to out.css.'));
          await expectLater(sass.stdout, _watchingForChanges);
          await sass.kill();

          await d
              .file("out.css", equalsIgnoringWhitespace("a { b: c; }"))
              .validate();
        });

        test("doesn't update a CSS file that wasn't modified", () async {
          await d.file("test.scss", "a {b: c}").create();
          await d.file("out.css", "x {y: z}").create();

          var sass = await watch(["test.scss:out.css"]);
          await expectLater(sass.stdout, _watchingForChanges);
          await sass.kill();

          await d.file("out.css", "x {y: z}").validate();
        });

        group("continues compiling after an error", () {
          test("with --error-css", () async {
            await d.file("test1.scss", "a {b: }").create();
            await d.file("test2.scss", "x {y: z}").create();

            var message = 'Error: Expected expression.';
            var sass =
                await watch(["test1.scss:out1.css", "test2.scss:out2.css"]);
            await expectLater(sass.stderr, emits(message));
            await expectLater(
                sass.stderr, emitsThrough(contains('test1.scss 1:7')));
            await expectLater(
                sass.stdout, emitsThrough('Compiled test2.scss to out2.css.'));
            await expectLater(sass.stdout, _watchingForChanges);
            await sass.kill();

            await d.file("out1.css", contains(message)).validate();
            await d
                .file("out2.css", equalsIgnoringWhitespace("x { y: z; }"))
                .validate();
          });

          test("with --no-error-css", () async {
            await d.file("test1.scss", "a {b: }").create();
            await d.file("test2.scss", "x {y: z}").create();

            var sass = await watch([
              "--no-error-css",
              "test1.scss:out1.css",
              "test2.scss:out2.css"
            ]);
            await expectLater(
                sass.stderr, emits('Error: Expected expression.'));
            await expectLater(
                sass.stderr, emitsThrough(contains('test1.scss 1:7')));
            await expectLater(
                sass.stdout, emitsThrough('Compiled test2.scss to out2.css.'));
            await expectLater(sass.stdout, _watchingForChanges);
            await sass.kill();

            await d.nothing("out1.css").validate();
            await d
                .file("out2.css", equalsIgnoringWhitespace("x { y: z; }"))
                .validate();
          });
        });

        test("stops compiling after an error with --stop-on-error", () async {
          await d.file("test1.scss", "a {b: }").create();
          await d.file("test2.scss", "x {y: z}").create();

          var sass = await watch([
            "--stop-on-error",
            "test1.scss:out1.css",
            "test2.scss:out2.css"
          ]);

          var message = 'Error: Expected expression.';
          await expectLater(
              sass.stderr,
              emitsInOrder([
                message,
                emitsThrough(contains('test1.scss 1:7')),
                emitsDone
              ]));
          await sass.shouldExit(65);

          await d.file("out1.css", contains(message)).validate();
          await d.nothing("out2.css").validate();
        });
      });

      group("recompiles a watched file", () {
        test("when it's modified", () async {
          await d.file("test.scss", "a {b: c}").create();

          var sass = await watch(["test.scss:out.css"]);
          await expectLater(
              sass.stdout, emits('Compiled test.scss to out.css.'));
          await expectLater(sass.stdout, _watchingForChanges);
          await tickIfPoll();

          await d.file("test.scss", "x {y: z}").create();
          await expectLater(
              sass.stdout, emits('Compiled test.scss to out.css.'));
          await sass.kill();

          await d
              .file("out.css", equalsIgnoringWhitespace("x { y: z; }"))
              .validate();
        });

        test("when it's modified when watched from a directory", () async {
          await d.dir("dir", [d.file("test.scss", "a {b: c}")]).create();

          var sass = await watch(["dir:out"]);
          await expectLater(
              sass.stdout, emits(_compiled('dir/test.scss', 'out/test.css')));
          await expectLater(sass.stdout, _watchingForChanges);
          await tickIfPoll();

          await d.dir("dir", [d.file("test.scss", "x {y: z}")]).create();
          await expectLater(
              sass.stdout, emits(_compiled('dir/test.scss', 'out/test.css')));
          await sass.kill();

          await d.dir("out", [
            d.file("test.css", equalsIgnoringWhitespace("x { y: z; }"))
          ]).validate();
        });

        test(
            "when it's modified twice when watched from a directory that is "
            "also a destination", () async {
          await d.file("test.scss", "a {b: c}").create();

          var sass = await watch(["."]);
          await expectLater(
              sass.stdout, emits('Compiled test.scss to test.css.'));
          await expectLater(sass.stdout, _watchingForChanges);
          await tickIfPoll();

          await d.file("test.scss", "r {o: g}").create();
          await expectLater(
              sass.stdout, emits('Compiled test.scss to test.css.'));

          await tickIfPoll();

          await d.file("test.scss", "x {y: z}").create();
          await expectLater(
              sass.stdout, emits('Compiled test.scss to test.css.'));

          await sass.kill();

          await d
              .file("test.css", equalsIgnoringWhitespace("x { y: z; }"))
              .validate();
        });

        group("when its dependency is modified", () {
          test("through @import", () async {
            await d.file("_other.scss", "a {b: c}").create();
            await d.file("test.scss", "@import 'other'").create();

            var sass = await watch(["test.scss:out.css"]);
            await expectLater(
                sass.stdout, emits('Compiled test.scss to out.css.'));
            await expectLater(sass.stdout, _watchingForChanges);
            await tickIfPoll();

            await d.file("_other.scss", "x {y: z}").create();
            await expectLater(
                sass.stdout, emits('Compiled test.scss to out.css.'));
            await sass.kill();
<commit_msg>Wait a tick in a failing test even if polling is disabled<commit_after>// Copyright 2018 Google Inc. Use of this source code is governed by an
// MIT-style license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

import 'package:path/path.dart' as p;
import 'package:test/test.dart';
import 'package:test_descriptor/test_descriptor.dart' as d;
import 'package:test_process/test_process.dart';

import '../../utils.dart';

/// Defines test that are shared between the Dart and Node.js CLI test suites.
void sharedTests(Future<TestProcess> runSass(Iterable<String> arguments)) {
  test("--poll may not be passed without --watch", () async {
    var sass = await runSass(["--poll", "-"]);
    await expectLater(
        sass.stdout, emits("--poll may not be passed without --watch."));
    expect(
        sass.stdout, emitsThrough(contains("Print this usage information.")));
    await sass.shouldExit(64);
  });

  for (var poll in [true, false]) {
    Future<TestProcess> watch(Iterable<String> arguments) => runSass(
        ["--no-source-map", "--watch", ...arguments, if (poll) "--poll"]);

    /// Returns a future that completes after a delay if [poll] is `true`.
    ///
    /// Modifying a file very quickly after it was processed can go
    /// unrecognized, especially on Windows where filesystem operations can have
    /// very high delays.
    Future<void> tickIfPoll() => poll ? tick : Future.value();

    group("${poll ? 'with' : 'without'} --poll", () {
      group("when started", () {
        test("updates a CSS file whose source was modified", () async {
          await d.file("out.css", "x {y: z}").create();
          await tick;
          await d.file("test.scss", "a {b: c}").create();

          var sass = await watch(["test.scss:out.css"]);
          await expectLater(
              sass.stdout, emits('Compiled test.scss to out.css.'));
          await expectLater(sass.stdout, _watchingForChanges);
          await sass.kill();

          await d
              .file("out.css", equalsIgnoringWhitespace("a { b: c; }"))
              .validate();
        });

        test("doesn't update a CSS file that wasn't modified", () async {
          await d.file("test.scss", "a {b: c}").create();
          await d.file("out.css", "x {y: z}").create();

          var sass = await watch(["test.scss:out.css"]);
          await expectLater(sass.stdout, _watchingForChanges);
          await sass.kill();

          await d.file("out.css", "x {y: z}").validate();
        });

        group("continues compiling after an error", () {
          test("with --error-css", () async {
            await d.file("test1.scss", "a {b: }").create();
            await d.file("test2.scss", "x {y: z}").create();

            var message = 'Error: Expected expression.';
            var sass =
                await watch(["test1.scss:out1.css", "test2.scss:out2.css"]);
            await expectLater(sass.stderr, emits(message));
            await expectLater(
                sass.stderr, emitsThrough(contains('test1.scss 1:7')));
            await expectLater(
                sass.stdout, emitsThrough('Compiled test2.scss to out2.css.'));
            await expectLater(sass.stdout, _watchingForChanges);
            await sass.kill();

            await d.file("out1.css", contains(message)).validate();
            await d
                .file("out2.css", equalsIgnoringWhitespace("x { y: z; }"))
                .validate();
          });

          test("with --no-error-css", () async {
            await d.file("test1.scss", "a {b: }").create();
            await d.file("test2.scss", "x {y: z}").create();

            var sass = await watch([
              "--no-error-css",
              "test1.scss:out1.css",
              "test2.scss:out2.css"
            ]);
            await expectLater(
                sass.stderr, emits('Error: Expected expression.'));
            await expectLater(
                sass.stderr, emitsThrough(contains('test1.scss 1:7')));
            await expectLater(
                sass.stdout, emitsThrough('Compiled test2.scss to out2.css.'));
            await expectLater(sass.stdout, _watchingForChanges);
            await sass.kill();

            await d.nothing("out1.css").validate();
            await d
                .file("out2.css", equalsIgnoringWhitespace("x { y: z; }"))
                .validate();
          });
        });

        test("stops compiling after an error with --stop-on-error", () async {
          await d.file("test1.scss", "a {b: }").create();
          await d.file("test2.scss", "x {y: z}").create();

          var sass = await watch([
            "--stop-on-error",
            "test1.scss:out1.css",
            "test2.scss:out2.css"
          ]);

          var message = 'Error: Expected expression.';
          await expectLater(
              sass.stderr,
              emitsInOrder([
                message,
                emitsThrough(contains('test1.scss 1:7')),
                emitsDone
              ]));
          await sass.shouldExit(65);

          await d.file("out1.css", contains(message)).validate();
          await d.nothing("out2.css").validate();
        });
      });

      group("recompiles a watched file", () {
        test("when it's modified", () async {
          await d.file("test.scss", "a {b: c}").create();

          var sass = await watch(["test.scss:out.css"]);
          await expectLater(
              sass.stdout, emits('Compiled test.scss to out.css.'));
          await expectLater(sass.stdout, _watchingForChanges);
          await tickIfPoll();

          await d.file("test.scss", "x {y: z}").create();
          await expectLater(
              sass.stdout, emits('Compiled test.scss to out.css.'));
          await sass.kill();

          await d
              .file("out.css", equalsIgnoringWhitespace("x { y: z; }"))
              .validate();
        });

        test("when it's modified when watched from a directory", () async {
          await d.dir("dir", [d.file("test.scss", "a {b: c}")]).create();

          var sass = await watch(["dir:out"]);
          await expectLater(
              sass.stdout, emits(_compiled('dir/test.scss', 'out/test.css')));
          await expectLater(sass.stdout, _watchingForChanges);
          await tickIfPoll();

          await d.dir("dir", [d.file("test.scss", "x {y: z}")]).create();
          await expectLater(
              sass.stdout, emits(_compiled('dir/test.scss', 'out/test.css')));
          await sass.kill();

          await d.dir("out", [
            d.file("test.css", equalsIgnoringWhitespace("x { y: z; }"))
          ]).validate();
        });

        test(
            "when it's modified twice when watched from a directory that is "
            "also a destination", () async {
          await d.file("test.scss", "a {b: c}").create();

          var sass = await watch(["."]);
          await expectLater(
              sass.stdout, emits('Compiled test.scss to test.css.'));
          await expectLater(sass.stdout, _watchingForChanges);
          await tickIfPoll();

          await d.file("test.scss", "r {o: g}").create();
          await expectLater(
              sass.stdout, emits('Compiled test.scss to test.css.'));

          // When using the native Node.js watcher on Linux, the "modify" event
          // from writing test.css can interfere with the "modify" event from
          // updating test.scss below, so we wait a tick to keep them from
          // overlapping.
          await tick;

          await d.file("test.scss", "x {y: z}").create();
          await expectLater(
              sass.stdout, emits('Compiled test.scss to test.css.'));

          await sass.kill();

          await d
              .file("test.css", equalsIgnoringWhitespace("x { y: z; }"))
              .validate();
        });

        group("when its dependency is modified", () {
          test("through @import", () async {
            await d.file("_other.scss", "a {b: c}").create();
            await d.file("test.scss", "@import 'other'").create();

            var sass = await watch(["test.scss:out.css"]);
            await expectLater(
                sass.stdout, emits('Compiled test.scss to out.css.'));
            await expectLater(sass.stdout, _watchingForChanges);
            await tickIfPoll();

            await d.file("_other.scss", "x {y: z}").create();
            await expectLater(
                sass.stdout, emits('Compiled test.scss to out.css.'));
            await sass.kill();

{'fraction_non_alphanumeric': 0.15848519024158603, 'fraction_numerical': 0.005342197423873687, 'mean_word_length': 1.964109781843772, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 17, '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': '3681981', 'n_tokens_mistral': 5148, 'n_tokens_neox': 5063, 'n_words': 1245}