Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test Blocks In Src #4207

Open
mcmah309 opened this issue Dec 15, 2024 · 2 comments
Open

Test Blocks In Src #4207

mcmah309 opened this issue Dec 15, 2024 · 2 comments
Labels
feature Proposed language feature that solves one or more problems

Comments

@mcmah309
Copy link

It would be nice if tests could live next to their declarations in source. This would make it clearer what code does, make tests easier to write, and users would no longer have to maintain a mirrored directory tree in tests.
e.g.

int plusOne(int x) => x + 1;

test "PluseOne" {
   import 'package:test/test.dart'; // can import regular dependencies or dev dependencies

    expect(plusOne(-1), 0);
    expect(plusOne(0), 1);
    expect(plusOne(1), 2);
}

Prior art

@mcmah309 mcmah309 added the feature Proposed language feature that solves one or more problems label Dec 15, 2024
@lrhn
Copy link
Member

lrhn commented Dec 15, 2024

Sounds very specialized. It would make testing into a language feature, not just something you do using normal dart code and a helper library, a special compilation mode with some code only accessible when compiled for testing.

Even if Dart chose to do that, it would probably be normal Day code inside the test block, so more likely

... The library code ...
test {
  import test; // assume shorthand imports.
  main() {
    test("Foo", () {
       // Some test code 
    });
  }
}

That would make the code inside the test block be normal top-level declaration code, which makes it so much easier to explain what's going on: it's conditional compilation. The code is only included when compiling on the mode called "test", and the Collier didn't have to understand what that means, just that modes exist.
(But would make it harder to have multiple blocks of code that get combined into one main function.)

I'd probably generalize it to something similar to conditional imports/parts, where the condition is something you could use in such a conditional URI:

if (test) {
  // Declarations
}

What would work the same as of that code was written inside a separate part file and included as

part "empty.dart"
  if (dart.mode.test) "the_code.dart";

Then you can define multiple modes.

Still doesn't allow you to have multiple blocks of test code if each tries to introduce a main function.
We need some way to combine multiple top-level declarations into sobbing that can be acted on by a generic main function.
There is a proposal for "accumulated collections", where multiple declarations of the same collection connect all the values. Maybe something like

if (test) {
  import test/inline;
  accumulator Tests tests = {};
  main() => testSet(tests);
} 
....
if (test) {
  tests += {
    test("Foo", () {
      // The test 
    });
  };
}

Which would collect all the test declarations as literals of one set, and then access that set once in main.

This is still much more complicated than what is being asked for, and therefore has more overhead, but it's also a general language feature that could be used for other things than testing. That makes it more likely to be worth doing. (Maybe, if that generality has any real uses.)

@tatumizer
Copy link

a general language feature that could be used for other things than testing

I'm aware of two more features: defer and atExit. Each of them requires language support anyway (to varying degrees).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Proposed language feature that solves one or more problems
Projects
None yet
Development

No branches or pull requests

3 participants