stryker-mutator / stryker-js

Mutation testing for JavaScript and friends
https://stryker-mutator.io
Apache License 2.0
2.6k stars 251 forks source link

Feature: use git to identify files (instead of the files array) #589

Closed nicojs closed 6 years ago

nicojs commented 6 years ago

Current problem

Right now, a lot of reported issues come from people misunderstanding what the files array does in your stryker.conf.js files. And who can blame them. It's kind of a mess.

Here is a list of the most common issues:

  1. "Why do I need to specify files?"
  2. "Why do I need to put !**.* as the first argument?" (psst, both stryker-typescript and stryker-karma-runner expand the files array even before your config is loaded, resulting in a mess. I know, complicated indeed!)
  3. "Why do i need to add insert-file-name-here to my files?"
  4. "What is the difference between mutate and files?"

We can do better than this.

Feature request: use git

Let's replace the current functionality with using the project's .gitignore file by default. This is much more reliable and user-friendly than any custom solution we can come up with. ~For users that still need to specify the files, we can use a .strykerignore file construction. It will work the same way as .gitignore works, so no need to learn something new.~ EDIT: We won't use a .strykerignore file, instead we still support a files array with strings for which files to include.

Way of working

The new way of working will be:

  1. Use files array if present.
  2. If not: use .gitignore file. Use the output of the git ls-files --others --exclude-standard --cached command to get the list without having to parse the .gitignore files ourselves.
  3. ~If not in a git repo (or git isn't installed), use a sane default (ignore only node_modules or something).~ EDIT: We shouldn't use a default. If we did that, the same project on different machines would result in different files being used and different overall result. Instead, we should throw an error which clearly specifies that the input files could not be specified

Advantages:

This way of working has a lot of advantages

  1. It will be zero config for most users. Users don't even have to know about sandboxes or anything.
  2. Marking files to be mutated will be easier, as you can only do that by specifying them in the mutate array. No more mix and matching by combining the files and mutate array.

Downsides

We have some downsides to this new approach.

  1. It is a major (breaking) change
  2. Sandboxes will be bigger than they would need to be. This will not be a big problem I think.
  3. We will lose support for additional file properties you can now specify with your files: transpiled, included and mutated. We can mitigate this:
    • mutated: This one is simple: use the mutate property instead.
    • included: This should move to the test runner configuration (with sane defaults). This might give some problems with both the mocha and karma test runners.
    • transpiled: This should be moved to the transpiler configuration. Not a big deal, as all transpilers have their own config anyway (webpack.config.js, tsconfig, .babelrc, etc)

Todo list:

Work on this feature is done in the feat/identify-files branch

nicojs commented 6 years ago

@simondel @Archcry let's take some time to think about this proposal before we start to implement it. I don't want to rush it, because it will take a chunk of time to implement and is breaking for end users.

sanderkoenders commented 6 years ago

Wouldn't it be possible to still support the files array and use the proposed method when the files array is not specified (undefined)? That way we stay backwards compatible (no breaking change).

nicojs commented 6 years ago

Hmm interesting. In that case I don't want to support a .strykerignore file as well, as both would serve the same purpose. I would also still want to get rid of the additional file attributes (transpiled, included, mutated) as those add to the confusion.

An additional benefit is that keeping the files array is simpler to implement, as we keep the current functionality. I was looking for a module that delivers the .blaignore file functionality, but it seems it does not exist, so keeping the files array makes even more sense to me.

However, we should remove the "magic" adding of files from the ConfigEditor plugins.

@Archcry do you agree with all this?

sanderkoenders commented 6 years ago

Ye I agree, magic causes side effects.

nicojs commented 6 years ago

I've updated the original issue, is this what we want @Archcry @simondel ?

nicojs commented 6 years ago

@simondel the more I think about it, the happier I get. When we are doing implementing this feature we can also change the strange WebFile interface we now have. It is basically only needed to support karma's url-files. We should be able to simply remove it.

We might also be able to remove the distinction between binary and text files. We can simply read any file as buffer. If we need the text representation, we can use buffer.toString('utf8') (as a cached property). This would simplify a lot of code.

sanderkoenders commented 6 years ago

But how will we know what files to mutate in the new situation?

nicojs commented 6 years ago

We will still support the mutate property

sanderkoenders commented 6 years ago

I understand, is it also possible to ignore certain files with this property? Because when you have two files (file.js & fileSpec.js) you can't simply say **/*.js.

nicojs commented 6 years ago

Yes you can exclude with a ! just like you can with files.

nicojs commented 6 years ago

I started the work on the https://github.com/stryker-mutator/stryker/tree/feat/identify-files branch. In order to keep a green build during the breaking changes, we will scope the build on only the packages that are updated (as of now, only the stryker-api package is updated)

simondel commented 6 years ago

We may be able to rewrite the TypescriptConfigEditor to read the ts files for us that have to be mutated.

nicojs commented 6 years ago

@simondel

We may be able to rewrite the TypescriptConfigEditor to read the ts files for us that have to be mutated.

That's not what we want I think. Let's focus on removing the 'hocus pocus' configuration. It will only over complicate things.