-
Fix a crash on pattern matching and
**nilparameters. Mutating a block without parameters whose body used either, such asfoo { x in {a: 1} }, raisedKeyError: key not found: :match_pattern_p. The same error stopped mutant from matching a method insideclass << selfwhen pattern matching came earlier in the file. -
Fix a crash on blocks using the Ruby 3.4
itparameter. Mutating a block without parameters whose body holds anitblock, such asfoo { bar { it } }, raisedKeyError: key not found: :itblock.itblocks also gain the mutation tonil, as numbered parameter blocks have:items.map { it.price }now mutates toniltoo. -
Leave the log of each killed mutation out of the session file. It holds the output of the tests that killed the mutation, which the session subcommands never show, and on a suite whose failures print large values, such as the request bodies WebMock lists, it is most of the file. Alive mutations keep their log.
-
Write the session file gzip compressed, to
<session-id>.json.gz. It repeats the source, diff, and tests of each mutation, and compresses about twentyfold. The session subcommands read the compressed files and the plain JSON files earlier versions wrote. -
Keep the 100 most recent sessions, deleting older ones once a run has written its own.
.mutant/results/grew by a session each run, without limit, unlessmutant session gcwas run by hand.
-
Add
mutant-test-unit, an integration for test-unit. Tests declare the subjects they cover withcover, the same waymutant-minitestdoes, and run with--integration test-unit. See mutant-test-unit. -
Write the session file each time a mutation is found alive, not only at the end of the run. The session subcommands now see survivors while a long run is still going. Writes happen at most once per second.
-
The minitest integration now also loads test files under
minitest/, and skips any file under avendor/directory. -
Select tests from a per test coverage recording when there is one. Mutant selects a subject's tests by matching the subject's expression against each test's expression, which RSpec derives from the leading token of an example description. A spec headed
describe 'clamping behaviour'coversCalculator#clampwithout saying so, and its mutations report alive even though the suite kills them.Mutant now reads the per test data simplecov 1.2.0 and newer add to
coverage/coverage.jsonundertrack_tests, and selects the tests that executed the subject's own source lines. It takes on no dependency for this, and readscoverage.jsonrather than the internal resultset, so it consumes simplecov's published schema.The default strategy is
auto: use the recording when there is a usable one, and the expressions otherwise. Every run prints the strategy it settled on.--selection context_mapturns every reason the recording cannot be used into a failed run, and--selection expressionnever reads it.--selection-pathreads a report outsidecoverage. The same settings live under aselectionkey inmutant.yml.Subjects whose lines no test executes, such as a constant body evaluated while the suite loads, fall back to expression based selection.
The selected tests are ordered likeliest killer first, by whether the expressions name the test, then by the share of the test's own footprint falling inside the subject, then by how much of the subject it reached. A run stops at the first failing test, so the order decides whether one test runs or all of them. Rspec picks its own order for groups and examples, so mutant installs an ordering strategy that follows the ranking. On a suite where thirty tests execute a subject incidentally and one asserts on it, this cut the examples run from 129 to 39.
See Test Selection.
-
Fix
NoMethodErrorcrash insource:<glob>subject expressions when the glob matched a bare file (empty file or comment-only file, e.g. containing only# frozen_string_literal: true). Such files parse to anilAST node, whichExpression::Source#toplevel_constsdid not handle. Bare files now contribute no scopes instead of crashing. -
Fix
KeyErrorcrash inMutant::AST::Structure.foron Ruby's parameter-site argument-forwarding syntax (def foo(...)anddef foo(a, ...)). Theforward_argsandforward_argparser nodes were missing fromStructure::ALL, so any matcher / subject resolution that descended into such a file crashed. Observed first againstruby/jsonduring corpus testing.Latent since #1348, which switched
FindMetaclassContaining(and related traversals) toStructure.for(type).each_node(...). The call-site counterparts (forwarded_args,forwarded_restarg,forwarded_kwrestarg) were registered in #1402 / #1403; the parameter-site leaves were missed.
- Fix
JSON::GeneratorErrorcrash inResult::JSONWriterwhen test output contains bytes that are not valid UTF-8. Captured log output is now preserved as tagged{type, content}objects in the session JSON, distinguishing UTF-8 text from binary bytes (base64-encoded). Session files written by prior versions still load: plain-stringlog/outputfields are promoted to string-typed captures on read.
- Fix pattern language rejecting Ruby method names with
!,?, or=suffixes and operator method names (==,<=>,[]=, etc.) inignore_patternsselector values. Patterns likesend{selector=(let, cast, assert_type!)}now parse successfully.
-
Add integer overflow boundary probe mutations.
Integer literals are now mutated to safe prime sentinel values that fall within integer width overflow zones. Each literal snaps to the next overflow zone above its absolute value, emitting exactly one additional mutation per integer literal.
This targets a class of bugs that prior mutation operators could not detect: code that assumes fixed-width integer semantics. Ruby transparently promotes integers across width boundaries, but code that interfaces with systems that do not — databases, FFI bindings, binary protocols, serialization formats — can silently produce incorrect results when values cross these thresholds.
Common examples of bugs this operator catches:
- FFI bindings declaring
intparameters where Ruby happily passes Bignum values that get silently truncated at the C boundary. - MessagePack serialization assuming signed 32-bit representation, silently wrapping unsigned values to negative numbers.
pack/unpackformat strings assuming specific integer widths, silently truncating or wrapping values that exceed the format width.- Missing error handling for libraries and databases that do raise
on overflow (e.g. PostgreSQL
integer out of range, Protocol BuffersRangeError). Tests using small values never exercise these error paths, leaving them untested.
The overflow zones and their sentinel values:
Zone Boundary Sentinel int8 128 167uint8 256 467int16 32768 55_487uint16 65536 108_503int32 2^31 2_667_278_543uint32 2^32 7_980_081_959int64 2^63 15_508_464_536_481_899_903Sentinel values are safe primes (p = 2q + 1 where both p and q are prime). Safe primes cannot arise from simple arithmetic, bit shifts, or masking, which provides strong guarantees against coincidental mutation kills. A mutation surviving against a safe prime is a strong signal of missing boundary validation for that integer width.
Each integer literal snaps to the next zone above its absolute value. For example, a literal
port = 80(below 128) receives the int8 sentinel167. A literaltimeout = 500(between 256 and 32768) receives the int16 sentinel55_487. Values at or above 2^63 receive no sentinel as there is no higher zone to probe.This keeps the mutation count to exactly one additional mutation per integer literal while providing maximum diagnostic value. When an overflow sentinel survives, it tells you exactly which width boundary your tests do not cover.
Most surviving overflow sentinels indicate that the integer literal should be extracted to a named constant with explicit range validation at the system boundary.
Future versions of mutant will add infrastructure to explain alive overflow sentinel mutations, including which zone a surviving sentinel belongs to and what class of bug it indicates.
- FFI bindings declaring
-
Add machine-readable session recording.
-
Add machine-readable session recording.
Mutant now writes a JSON result file to
.mutant/results/after every run. Past sessions can be recalled without re-running mutant. -
Add
mutant sessionCLI subcommands.mutant session list— list past sessions sorted by most recent first. Shows alive count, mutations, subjects, runtime, and killtime.mutant session show— reprint the full report from a stored session. Defaults to the most recent session. Use--session-idto select a specific session.mutant session subject— list subjects with alive/total mutation counts. Pass a subject expression (e.g.Foo::Bar#baz) to show alive mutation details for that specific subject.mutant session gc [--keep=N]— remove incompatible and old sessions.- All session commands accept
--session-id UUIDto operate on a specific session instead of the latest.
-
Add alive mutation explanation to CLI report output. When alive mutations are present, the report now prints guidance explaining the two actions: keep the mutated code or add the missing test. This is helpful to improve agent behavior when processing mutant reports.
-
Add alive mutation explanation to README and documentation.
-
Remove mutant rust wrapper stub. The rust wrapper is canceled in favor of a spiritual successor to mutant.
-
Add operator mutations.
-
#1523 #1530 Add arithmetic operator swap mutations (
+↔-,*↔/). Multiplication/division skips multiplicative identity operands. -
#1527 Add
==↔!=swap mutation. -
#1534 Add logical operator swap mutations (
and↔or,&&↔||). -
#1535 #1576 Add compound assignment operator swap mutations (
+=↔-=,*=↔/=,%=→/=,**=→*=,&=↔|=↔^=,<<=↔>>=,&&=↔||=).
-
-
Add selector replacement mutations.
Orthogonal replacements (circular swaps):
- #1559
select/filter↔reject - #1560
any?↔none? - #1561
take↔drop - #1562
append/push↔prepend/unshift - #1563
positive?↔negative? - #1564
zero?↔nonzero? - #1565
count↔size/length - #1568
keys↔values - #1571
even?↔odd?,min↔max,min_by↔max_by - #1573
all?↔none?,floor↔ceil,start_with?↔end_with?,transform_keys↔transform_values,upcase↔downcase - #1576
pop↔shift,each_key↔each_value,assoc↔rassoc,succ↔pred,chars↔bytes,empty?↔any?,grep↔grep_v
Semantic reductions:
- #1542 Bang → non-bang methods
(e.g.
map!→map,sort!→sort,compact!→compact). - #1567
#1572 Enumerable reductions
(
collect→each,each_with_object→each,each_with_index→each,each_cons→each,each_slice→each,sample→first/last,sort_by→sort). - #1574
filter_map→map,delete_if→reject,keep_if→select,collect_concat→collect,chunk/chunk_while/slice_before/slice_after/slice_when→each,strip→lstrip/rstrip,to_f→to_i,defined?→true, strip regexpm(multiline) flag.
- #1559
-
Add pattern-matching mutation support. Dedicated mutators for
case/inexpressions,inpatterns, match alternatives (A | B), and pattern match predicates (x in pattern→false). Guard clauses in pattern matches are now mutated. -
Add control flow mutations.
while↔untilorthogonal swap mutations.while_postanduntil_postsupport forbegin...end while/begin...end untilconstructs. -
Add
super↔super()mutation operators to test implicit vs explicit argument forwarding. -
Add rescue clause removal mutations. When multiple rescue clauses exist, emit mutations that remove each clause individually.
-
Add inline rescue modifier mutations (
foo rescue bar→bar). -
Add explicit ensure mutator with ensure-clause reduction.
-
Add empty collection return value mutations (
to_a→[],to_h→{},to_s→""). -
Add type-aware default return mutations for method bodies (
Array→[],Hash→{},String→"",Integer→0,Float→0.0). -
Add generic receiver promotion mutations for blocks (
a.b { }→a). -
Add non-empty string to empty string mutation.
-
Add literal mutators for complex and rational numeric nodes.
-
Add RSpec 4 support.
-
Dependency updates:
- #1570 Bump parser dependency to ~> 3.3.10 and unparser dependency to ~> 0.8.2.
-
Fix bundler stability issue.
-
Add bitwise operator mutations.
Mutant now generates mutations for bitwise operators (
&,|,^,~,<<,>>), replacing them with alternative operators to test bitwise logic coverage. -
Add visual progress bar for TTY output.
When running in a terminal, mutant now displays a progress bar showing mutation testing progress.
-
Fix coverage percentage rounding up to 100% when mutations survive.
-
Fix VERSION file in gemspec.
-
Add Ruby 4.0 support.
Mutant now supports Ruby 4.0. This includes:
-
#1504 Fix IO loop compatibility with Ruby 4.0.
-
#1490 Fix Minitest 6+ integration (default test framework on Ruby 4.0).
-
Update CI to test against Ruby 4.0.
Note: Ruby 3.1 support has been removed. Minimum supported version is now Ruby 3.2.
-
-
Remove uncanonical mutation from
@footofoo. This mutation was generating semantically different code that changed instance variable reads to method calls. -
Fix post hooks to only run after successful integration setup.
-
Fix frozen constant handling.
-
Fix eigenclass duplication issue.
-
Fix interrupt handling bug.
-
Dependency updates:
- Allow minitest 6.x in mutant-minitest
- Allow irb 1.16
- Update rspec-its to ~> 2.0
- Update sorbet-runtime to ~> 0.6
-
Add support for
MUTANT_JOBSenvironment variableThe
jobsconfiguration can now be set via theMUTANT_JOBSenvironment variable. This provides an additional configuration method with the following precedence:- CLI option:
-jor--jobs(highest priority) - Environment variable:
MUTANT_JOBS - Configuration file:
jobs:in YAML - Default: system processor count (lowest priority)
Example usage:
MUTANT_JOBS=4 bundle exec mutant runThe environment variable value must be a valid base-10 integer. Invalid values (including octal or hexadecimal notation) will result in a clear error message.
- CLI option:
Fix parallel test runner to correctly setup global environment.
Before environment customizations such as requires and includes where not run at all when using the parallel test runner.
-
Change coverage criteria defaults:
- Default mutation timeout of 5s, previous: none.
- Coverage triteria timeout switched on, default off.
This means mutant will stop evaluation of mutations after 5s and consider these as covered from now on.
The previous behavior can be restored via:
# mutant.yaml coverage_criteria: timeout: false mutation: timeout: 3600.0 # 1 hourThis is not exactly equivalent as before mutant supported to be configured with unbounded mutation runtime, but its functionally equivalent.
Change to unparser 0.8.0 release. Which improves 3.4 support.
On ruby-3.4 this release uses the prism parser which results in faster mutant boot times on especially larger code bases.
No changes for <=ruby-3.3 still uses the whitequark parser there.
Also add the explicit irb dependency as its no longer a default gem for 3.5 to avoid a load time warning.
Add new mutant test primary subcommand. This subcommand allows
to run rspec (or minitest) tests via mutants parallel test runner.
Standard precautions to correctly synchronize or isolate global resources (fileystems / database) apply.
Significant unparser upgrade. Mutant now:
Avoids emitting mutations that do not round trip against unparsers API.
This change generates less mutations, and currently slightly increases boot time. But the number of mutations that are hitting the test suite is much lower so it should balance.
Also its a good step towards parallel mutation generation reducing boot times.
Also mutations that are currently not creating round trippable ASTS are removed:
-
Negation of
ifconditions, as negating these needs operator precendence sensitive AST mutations mutant does not have the infrastructure for right now. The mutation tounlessis still present so there is no real reduction of semantic coverage. -
All mutations that modify the local variable scope are removed. These generated ASTs that would not round trip and are thus likely to be covered, execution wise these would move lvar reads to implicit self receivers in the past. But this was not intended by these mutations, at least not without explicitly changing the reads to send nodes explicitly.
-
Fix zombifier on memoized methods (only relevant for mutant developers).
-
Fix parsing of empty rspec descriptions
-
Remove invalid mutation operator.
-
Add ordering mutations to full and light operator set,
#find/#detect/#min/#max/#min_by/#max_by -> #first/#last. These mutations force to provide test cases with more than one element to observe the extra semantics by these methods over just#firstand#last.Add
#first -> #lastand#last -> #firstto full operator set. These where highly controversial in the past and thus where removed. People who do not care about ordering of their collections can choose the light operator set. -
Change mutants test runner to always report in test definition order deterministically. Before results where recorded in order of arrival, which could result a fast test that started late to be reported before a slow test that started early. Basically it makes parallel test execution reporting deterministic.
Change the behavior of reporting test errors on fail fast to only display the fist test that failed. Parallel test execution can result in one or more tests failing before the execution engine has time to adhere to the fail fast setting.
Drop the license gem, entirely. This reduces DRM in mutants code base to the absolute minimum. Mutant is still comercial software that requires payment if used on a commercial code base!
Migration:
- Commercial users: Add
usage: commercialto your config file (or--usage commercialto your CLI) - Opensource users: Add
usage: opensourceto your config file (or--usage opensourceto your CLI)
-
Fix const pattern mutation to not generate invalid ast. The generic node mutation would generate invalid AST. This also removes some recursion into the nested pattern. Still this is preferable till we add explicit pattern mutation operators.
-
Add source match expression, source
source:$glob_expression, examplesource:{app,lib}/**/*.rbworks with anything thatPathname#globsuppors.Allows to match all toplevel class/module constants defined in the matched ruby files.
-
Also factor in Rspec 3.9+ signal
rspec_is_quittingto detect rspec not being able to load examples.
-
Improve rspec integration. Mutant now properly exits early if rspec cannot load examples.
-
Add integration setup hooks.
setup_integration_pre- called before the test integration setup.setup_integration_post- called after the test integration setup.
-
#1426 Fix mutations to unintentionally change constant scope. This fixes: #1422.
-
#1421 Change to optional warning display via --print-warnings environment option.
-
#1418 Fix mutation to invalid pattern match.
-
#1416 Fix CLI parsing issue where arguments given to
mutant environmentwhere silently ignored. -
#1415 Change to report efficiency instead of overhead. Efficiency is defined by
killtime / runtime. -
Add
Process.warmupoptimization for ruby-3.3+ which yields a noticable speed improvement.
-
Update to parser-3.3.0 dependency.
-
Fix config file support for AST pattern ignores. Before this fix the AST ignore patterns would only be picked up when specified via CLI.
-
Drop support for ruby 2.7.
-
Add support for commercial organization wide licenses
-
Fix restarg and kwrestarg nested mutations.
-
Fix restarg and kwrestarg invalid mutations.
-
Introduce mutation operators config 'light' and 'full'. Mutant will default to light set that for the moment does not include
#== -> #eql?.
-
Upgrade to unparser 0.6.8 dependency which ships an important bugfix on unparsing of csend AST nodes on binary operators.
-
Change to
--integrationfrom--useon CLI andintegration_namefromintegrationkey in config file.The old key is still supported but deprecated.
Add ability to provide multiple
--integration-argumentoptions that get passed down directly to rspec. Also available in the config file.
-
Significantly optimize parsing overhead during boot. Smaller projects may see boot time speedups of 10-20%. Larger projects may see boot time improvements of 2-3x or greater. Memory consumption is also greatly reduced (by a factor of 5x or more in some small changesets).
-
Add support for user defined mutation worker process hooks. These hooks are triggered before the mutation worker process starts processing mutations. They can be used so setup separate test databases to avoid clobbering between mutation threads or do other isolation mechanisms.
-
Add
#available_teststo integrations, differentiating tests eligible for mutation testing from all tests availabe in the integration. This will allow to re-use mutants test runner for all integration tests, outside of mutation testing.
-
Fix crash on code that must have been a ternary on original source.
-
Change to more performant rspec integration. Significant rspec runner speed improvement on projets with a very large number of tests.
-
Add ruby-3.2 support.
-
Upgrade regexp-parser to 2.6.1. This also re-implements the regexp mutation emitter to be more maintainable, no semantic changes expected.
-
Adapt to behavior change in ruby 3.1.3 where methods inherited from module inclusions that just got visibility changes are now owned by the included module/class.
-
Add execution profiling via
--profile. The output format is not stable yet, still this profile is very useful to differentiate mutant load time from target application load time. -
Improve worker process termination speed. Reduces pause before report print especially on high core count machines.
-
Fix ignore patterns support for single node def nodes. Fix config merge support for ignore patterns.
-
Fix to provide a well formed
Mutant::Config::DEFAULTconstant at all times. Primarily useful for custom 3rd party integrations that use mutants API directly.
-
Change to improved AST matching performance. Mutant boot performance is positively affected mostly on larger projects with larger AST node count per file.
-
Fix AST structure metadata issues.
- Add support for org wide opensource licensing.
-
Add user defined mutation filtering.
Mutant will not emit mutations for AST patterns defined by the new mutation specific option
ignore_patterns.mutation: ignore_patterns: - send{selector=log} # does no emit any mutation for `logger.log` or similar.The supported syntax is way more powerful than this simple example.
-
Fix: [#1308] again.
Properly normalize repository names on OSS license check.
-
Deprecate
mutation_timeouttoplevel configuration key.Now use:
mutation: timeout: 10.0
-
Add support for minitest-0.5.16, and its srant initalization. Currently mutant randomizes selected minitest tests by default. AS this is also the minitest default for versions past 0.5.16 this should be a good enough behavior.
-
Add mutation AST filtering. This allows to not emit mutations on user specified ASTS.
-
Fix incomplete mutations for regexp capture groups. As an example,
/(\w\d)/now gets mutated to/(\W\d)/and/(\w\D)/instead of just the former case.Fix capture group -> passive group mutations which would not get properly generated in many cases. As an example,
/(\w\d)/would get mutated to/(?:\w)/instead of/(?:\w\d)/like it will now.
-
Fix incomplete mutations for named regexp capture groups. As an example,
/(?<name>\w\d)/now gets mutated to/(?<name>\W\d)/and/(?<name>\w\D)/instead of just the former case. -
Add graceful but urgent exit on SIGINT.
-
Add explicit mutation handler for xstr nodes.
-
Fix crash with certain block argument edge cases such as
foo { |(*)| }.Fix mutation from
foo { |(a, b)| }tofoo { |(_a, b)| }andfoo { |(a, _b)| }instead of the less useful mutation to onlyfoo { |_a| }.Add
foo { |(a, b)| }->foo { |a, b| }mutation.
-
Remove useless
loop { code }->loop { nil }mutation.
-
Add inline mutant disable configuration. This allows individual subjects to be marked as disbled directly in the code.
Use:
class Something # mutant:disable def some_method end end
-
Fix regexp mapper to do full, ruby version specific unicode property mapping.
-
Fix forward arg mutations.
-
Fix visibility of mutated methods to retain original value.
Fix: [#1242]
-
Change to fully enforced license.
-
Remove support for Ruby-2.6 as its EOL.
-
Change to ignore case mismatches in git repository names on license check.
-
Add full Ruby 3.1 support.
-
Change to parser/unparser that works on 3.1 syntax. This does not mean mutant is yet fully 3.1 compatible. Mostly that mutant does not block the parser dependency anymore. And unparser is ready for Ruby 3.1.
-
Prevent multipath matches. Should multiple match expessions evaluate to the same subject, mutant now only visits that subject once.
This prevents blowing up the mutation testing work on bigger applications with more complex match expressions.
-
Add descendants matchers. These matchers allow to select subjects in inheritance trees that are not namespace based.
This is very useful for non namespaced (rails) applications. As users can now use match expressions like
descendants:ApplicationControllerto match all descants ofApplicationControllerincludingApplicationController.This feature is not bound to rails inheritance trees and can be used with any inheritance tree.
-
Improve matching speed. This is especially noticeable in larger projects. Mutant now creates way less objects while matching subjects.
-
Fix: #1273
Prevent crashes on degenerate object interfaces where method reflection returns methods that are later not accessible via
#instance_method. -
Add ability to set environment variables via the CLI. The environment variables are inserted before the application is loaded. This is especially useful to load rails in test mode via setting
RAILS_ENV=test.For CLI use the
--envargument. For config file use theenvironment_variableskey.
-
Add sorbet method matching. Allows mutant to operate on methods with a sorbet signature. Does not yet use the signature to constrain the mutations.
This adds a direct
sorbet-runtimedependency to mutant. Note that Mutant intents to use sorbet directly for its own code.sorbet-runtimeis itself a clean dependency, that unless told to: Will not perform core extensions.As mutant is a development dependency it should not be an issue for a project that mutant itself will soon use sorbet type checks to accelerate its development.
Please report any issues the addition of the
sorbet-runtimedependency to mutant causes.Bumping minor version to signal this more out of the ordinary change.
- #1269
Add
mutant environment irbcommand. Starts an IRB session for the configured mutant environment. Very useful for iterating on environment setup issues.
-
#1252 Remove not universally useful binary left negation operator.
-
#1253 Remove support for Ruby-2.5, which is EOL.
-
#1255 Remove invalid mutations to invalid syntax
-
#1257 Fix crash on numblock mutations.
-
#1258 Add improved UI on detecting 0 tests. This should be beneficial in onboarding scenarios or after manual persistend rspec selections.
- #1249
Add
mutant util mutationsubcommand to allow inspect mutations of a code snippet outside a booted environment. This eases debugging, learning and mutant developers life.
-
#1234 Add mapping for latin regexp properties to fix crash on mutating
\p{Latin}regexp nodes.Fix: #1231
-
- Add beginless range mutations
-
- Remove float literal negation mutations (
1.0->-1.0).
- Remove float literal negation mutations (
-
- Remove integer literal negation mutations (
1->-1).
- Remove integer literal negation mutations (
-
- Ignore methods defined in non
.rbfiles during matching.
- Ignore methods defined in non
-
Fix exception serialization form rails infected code bases. This case can happen when the killfork terminates abnormal, and the resulting exception in the worker has to be propagated to the main process for reporting. On "normal" Ruby the exceptions are dump/loadable but rails and its core extensions break this invariant. Hence mutant now captures the essence of the exception in an attribute copy for propagation.
-
- Remove
#eql?->#equal?mutation
- Remove
-
- Remove generic mutation to
self
- Remove generic mutation to
-
- Add
#reduce->#summutationsa.reduce(:+)->a.suma.reduce(0, &:+)->a.sum(0)
- Add
-
- Add
/\Astatic/->#start_with?mutations:a.match(/\Atext/)->b.start_with?('text')a.match?(/\Atext/)->b.start_with?('text')a =~ /\Atext/->b.start_with?('text')
- Add
/static\z/->#end_with?mutations:a.match(/text\z/)->b.end_with?('text')a.match?(/text\z/)->b.end_with?('text')a =~ /text\z/->b.end_with?('text')
- Add
-
- Add unused group name mutation:
/(?<foo>bar)/->/(?<_foo>bar)/.
- Add unused group name mutation:
-
- Add
mutant environment test listsubcommand. Useful to verify which tests mutant detects as candiates for test selection.
- Add
-
- Allow constants to be passed to minitest integrations
coverdeclaration.cover SomeClassis equivalent tocover 'SomeClass*'.
- Allow constants to be passed to minitest integrations
-
- Add mutation from named capturing group to non-capturing group:
/(?<foo>bar)/->/(?:bar).
- Add mutation from named capturing group to non-capturing group:
-
- Fix configured match expression loading to properly display error messages on invalid expression syntax.
-
- Add mutations from predicate-like methods (methods ending in ?) to
true/falsea.b?->falsea.b?->true
- Add mutations from predicate-like methods (methods ending in ?) to
-
Add additional
*->+regexp quantifier mutations:/a*?/->/a+?//a*+/->/a++/
-
Add
a === b->a.is_a?(b)mutation -
- Add mutation from
=~->#match? - Add mutation from
#match->#match?
- Add mutation from
-
Allow subject matcher configuration in the configuration file.
-
Reintroduce regexp mutation support
-
- Remove unuseful kwarg mutations.
- Remove argument promotion on kwarg mutations. These yield AST that when unparsed have invalid syntax.
-
- Add ruby-3.0 syntax and mutation support.
-
- Add mutation from
#any?to#all?and vice versa.
- Add mutation from
-
- Add GIL scaling and memory optimization via intermediary sub-processes. This architecture improves mutant performance slightly on the average (incremental) case but has a significant increase for longer coverage runs. Mostly this process model reduces the friction from forking from an ever growing main process. Also it reduces the chance of GC amplification, while enabling future optimizations in the area.
- Substantially improve performance on coverage attempts that involve many selected tests.
- Reduce (but not eliminate) performance degeneration on larger subject sets.
- This release for many average cases should get 2x the performance.
-
- Change to strict integration version bounds.
- Mutant is evolving the integration interface, and will keep doing so.
- Before this change integrations would declare they can work with many future mutant releases, but this is actually not the case.
-
- Add
defined?(@a)->instance_variable_defined?(:@a)mutation. - Remove invalid mutations from
defined?->true. - Remove mutations of
defined?()arguments, thedefined?method is not fully evaluating the argument but instead partially evaluates the AST, or inspects the AST. Delegating to the value semantics based "generic" mutation engine does create too many hard to cover mutations.
- Add
-
- Add support for unicode ruby method names.
- Fixes long standing bug on expression parsing of method operators. This means that mutant is now selecting a more narrow / correct set of tests for operators. As a side effect measure coverage may drop. But for a good reason as mutant before would select way more tests even if a specific test for such an operator was available. Enforcing that this specific test actually covers the subject.
-
- Fix matching non existing constants.
-
- Improve minitest integration to also render minitest failures in reports. This is useful when reacting to noop errors.
-
- Add subcommand
environment subject list. It allows to list all matched subjects.
- Add subcommand
-
Fix low frequency stuck isolation reads.
-
Minor performance improvements on small runs.
-
Add support for incremental mutation testing when the working directory is not the git repository root.
-
Change process abort coverage criteria to also cover nonzero killfork exits.
-
Fix to properly propagate coverage criteria from config file.
-
Fix absent jobs on CLI to not shadow file configuration.
-
Performance improvements on caching more work in the master process.
-
Add
environment showsubcommand to display environment without coverage run. -
Fix unspecified integration to have dedicated error message.
- Fix CLI overwrites of config file. #1127.
- Add support for specifying multiple subject expressions with the RSpec integration. #1125
-
Add support for process abort as coverage condition.
This allows mutation to be covered on abnormal process aborts, such as segfaults.
-
Add support for external mutation timeouts.
New config file settings.
mutation_timeoutandcoverage_criteriato control timeouts and coverage conditions. -
Improve CLI reporting to be less noisy:
-
Fix crash on static send mutation. #1108
-
Add more verbose configuration documentation.
- Change to always display help on invalid CLI. #1093
- Fix config inheritance between environment, config file and CLI options.
- Fix mutant-minitest and mutant rspec to not rely on git anymore in gemspec. #1087
- Fix mutant-minitest to ship minitest/coverge file. #1086
- Fix type error on subscription show subcommand with active commercial license. #1074
- Add support for multiple cover expressions in minitest integration #1076
- Add 2.7 syntax support. #1062.
- Add symbol-to-proc block mutations (
map(&:to_s)->map(&to_str)) #1048 - Add block-pass mutations (
foo(&method(:bar))->foo(&public_method(:bar))) #1047 - Add new mutation of
Array(foo)->[foo]#1043 - Add new mutation to mutate dynamic sends to static sends ({
foo.__send__(:bar),foo.send(:bar),foo.public_send(:bar)} ->foo.bar) #1040 and #1049 - Change packaging to not rely on git anymore. #1053
- Remove mutation to equivalent semantics on endless ranges #1036.
- Remove bounds to allow
diff-lcs 1.4.x#1032. - Fix crash on endless ranges #1026.
- Fix memoized subjects to preserve freezer option #973.
- Add support for mutating methods inside eigenclasses
class <<. #1009
- Remove
<-><=and>->>=mutations as non canonical. #1020 - Remove
true->nilandfalse->nilmutations as non canonical. #1018
- Change to generic catch all node mutator. This allows better cross parser version compatibility.
- Bump parser dependency to 2.7.1, note this still does not support Ruby 2.7 syntax. But it supports running bundling with that parser version.
- Nail diff-lcs to 1.3 till output difference for 1.4 can be addressed.
- Dependencies upgrade, should not change user facing semantics.
- Bump license nudge to 40s
- Change to 2.7 parser series. This does not drop support for < 2.7 but enables to in the future add full Ruby 2.7 support.
- Bump unparser dependency
- Change to soft dependency on mutant-license. Rationale its fine to bundle mutant if not used. This can easily happen on transitive dependencies.
- Upgrade to parser ~> 2.6.5
- Packaging bugfix.
- New license.
- Fix mutations to void value expressions to not be reported as integration error.
- Remove regexp body mutations
- Remove restarg mutations
- Remove support for rspec-3.{4,5,6}
- Change to {I,M}Var based concurrency
- Remove actors
- Change to always insert mutations with frozen string literals
- Fix various invalid AST or source mutations
- Handle regexp
regexp_parsercannot parse but MRI accepts gracefully
- Improved isolation error reporting
- Errors between isolation and tests do not kill mutations anymore.
- Remove hard ruby version requirement. 2.5 is still the only officially supported version.
- Change to modern ast format via unparser-0.4.1.
- Replace internal timers with monotonic ones.
Find older changelogs in the project history