smart-tests-cli 2.4.2__tar.gz → 2.5.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/.tagpr +1 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/Dockerfile +11 -5
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/PKG-INFO +1 -1
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/commands/compare/subsets.py +45 -1
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/commands/record/attachment.py +74 -12
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/commands/subset.py +1 -1
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/maven.py +14 -3
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/pytest.py +36 -3
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests_cli.egg-info/PKG-INFO +1 -1
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/commands/compare/test_subsets.py +146 -14
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/commands/record/test_attachment.py +122 -8
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/.bazelrc +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/.bazelversion +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/.dockerignore +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/.editorconfig +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/.github/release.yml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/.github/workflows/bazel-test.yml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/.github/workflows/e2e.yml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/.github/workflows/publish.yml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/.github/workflows/test.yml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/.github/workflows/update_maven_install_json.yml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/.gitignore +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/.pre-commit-config.yaml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/.python-version +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/CLAUDE.md +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/CONTRIBUTING.md +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/LICENSE.txt +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/README.md +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/WORKSPACE +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/build-java.sh +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/pyproject.toml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/renovate.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/setup.cfg +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/setup.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/__main__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/app.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/args4p/README.md +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/args4p/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/args4p/argument.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/args4p/command.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/args4p/converters/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/args4p/decorators.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/args4p/exceptions.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/args4p/option.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/args4p/parameter.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/args4p/typer/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/commands/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/commands/compare/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/commands/detect_flakes.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/commands/gate.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/commands/inspect/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/commands/inspect/model.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/commands/inspect/subset.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/commands/record/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/commands/record/build.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/commands/record/case_event.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/commands/record/commit.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/commands/record/session.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/commands/record/tests.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/commands/stats/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/commands/stats/test_sessions.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/commands/test_path_writer.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/commands/verify.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/jar/exe_deploy.jar +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/plugins/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/adb.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/ant.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/bazel.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/behave.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/codeceptjs.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/ctest.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/cts.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/cucumber.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/cypress.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/dotnet.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/file.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/flutter.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/go_test.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/googletest.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/gradle.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/jasmine.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/jest.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/karma.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/minitest.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/nunit.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/playwright.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/prove.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/raw.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/robot.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/rspec.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/smart_tests.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/vitest.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/test_runners/xctest.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/testpath.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/authentication.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/ci_provider.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/commands.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/commit_ingester.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/common_tz.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/edit_distance.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/env_keys.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/exceptions.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/fail_fast_mode.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/file_name_pattern.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/git_log_parser.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/glob.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/gzipgen.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/http_client.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/input_snapshot.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/java.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/link.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/logger.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/no_build.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/sax.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/session.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/smart_tests_client.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/subprocess.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/tracking.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/utils/typer_types.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests/version.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests_cli.egg-info/SOURCES.txt +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests_cli.egg-info/dependency_links.txt +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests_cli.egg-info/entry_points.txt +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests_cli.egg-info/requires.txt +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/smart_tests_cli.egg-info/top_level.txt +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/BUILD +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/Authenticator.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/BUILD +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/BackgroundWorkStatus.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/BoundedExecutorService.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/ChunkStreamer.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/CommitChunkStreamer.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/CommitGraphCollector.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/ConcurrentConsumer.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/CountingDiffFormatter.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/FileChunkStreamer.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/FlushableConsumer.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/GitFile.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/GitHubActionsAuthenticator.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/GitHubIdTokenAuthenticator.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/IOConsumer.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/JSAsyncFileCollectionProgress.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/JSAsyncFileCollectionResponse.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/JSCommit.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/JSFileChange.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/LaunchableHttpClient.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/Main.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/ObjectRevFilter.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/ProgressReporter.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/SSLBypass.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/TokenAuthenticator.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/TreeReceiver.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/main/java/com/launchableinc/ingest/commits/VirtualFile.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/maven_install.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/test/java/com/launchableinc/ingest/commits/AllTests.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/test/java/com/launchableinc/ingest/commits/BUILD +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/test/java/com/launchableinc/ingest/commits/BoundedExecutorServiceTest.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/test/java/com/launchableinc/ingest/commits/CommitGraphCollectorTest.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/test/java/com/launchableinc/ingest/commits/ConcurrentConsumerTest.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/test/java/com/launchableinc/ingest/commits/FileChunkStreamerTest.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/test/java/com/launchableinc/ingest/commits/MainTest.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/test/java/com/launchableinc/ingest/commits/PassThroughTreeReceiverImpl.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/test/java/com/launchableinc/ingest/commits/ProgressReporterTest.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/test/java/com/launchableinc/ingest/commits/SSLBypassTest.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/src/test/java/com/launchableinc/ingest/commits/java8-compat.sh +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/test-runner/__main__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/args4p/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/args4p/converters/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/args4p/converters/test_converters.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/args4p/test_badcode.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/args4p/test_badinput.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/args4p/test_command.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/args4p/test_decorators.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/args4p/test_help.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/args4p/test_parameter.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/args4p/test_typer.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/cli_test_case.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/commands/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/commands/compare/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/commands/inspect/test_model.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/commands/inspect/test_subset.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/commands/record/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/commands/record/test_build.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/commands/record/test_case_event.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/commands/record/test_commit.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/commands/record/test_session.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/commands/record/test_tests.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/commands/test_api_error.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/commands/test_detect_flakes.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/commands/test_gate.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/commands/test_subset.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/commands/test_verify.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/adb/subset_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/ant/junitreport/TEST-com.example.HelloWorldTest.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/ant/junitreport/TEST-com.example.library.CacheTest.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/ant/junitreport/TESTS-TestSuites.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/ant/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/ant/src/com/example/HelloWorld.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/ant/src/com/example/HelloWorldTest.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/ant/src/com/example/library/Cache.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/ant/src/com/example/library/CacheTest.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/ant/subset_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test1/test.cache_status +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test1/test.log +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test1/test.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test2/test.cache_status +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test2/test.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test3/test.cache_status +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test3/test.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test4/test.cache_status +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test4/test.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test5/test.cache_status +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test5/test.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test6/test.cache_status +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test6/test.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test7/test.cache_status +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test7/test.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test8/test.cache_status +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test8/test.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test9/test.cache_status +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/bazel-testlogs/src/test/java/com/ninjinkun/mylib_test9/test.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/build_event.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/build_event_rest.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/record_test_with_build_event_json_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/record_test_with_multiple_build_event_json_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/bazel/subset_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/behave/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/behave/reports/report.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/behave/subset_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/broken_xml/broken.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/broken_xml/normal.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/codeceptjs/codeceptjs-result.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/codeceptjs/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/ctest/Testing/latest/Test.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/ctest/ctest_list.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/ctest/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/ctest/subset_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/cts/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/cts/subset_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/cts/test_result.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/cucumber/features/foo/bar.feature +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/cucumber/features/foo/is_it_friday_yet.feature +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/cucumber/features/foo-bar.feature +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/cucumber/features/is_it_friday_yet.feature +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/cucumber/record_test_json_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/cucumber/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/cucumber/report/TEST-features-foo-bar.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/cucumber/report/TEST-features-foo-is_it_friday_yet.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/cucumber/report/TEST-features-is_it_friday_yet.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/cucumber/report/dummy.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/cucumber/report/result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/cypress/empty.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/cypress/empty.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/cypress/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/cypress/subset_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/cypress/test-result.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/dotnet/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/dotnet/test-result.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/file/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/file/record_test_result_custom_attribute.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/file/result.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/file/result_custom_attribute.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/flutter/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/flutter/report.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/git_log_ingest/sample.out +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/go_test/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/go_test/reportv1/reportv1.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/go_test/reportv2/reportv2.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/go_test/subset_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/googletest/fail/output.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/googletest/fail/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/googletest/output_a.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/googletest/output_b.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/googletest/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/googletest/subset_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/gradle/java/app/src/test/java/com/example/sample_app_gradle/App2Test.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/gradle/java/app/src/test/java/com/example/sample_app_gradle/AppTest.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/gradle/java/app/src/test/java/com/example/sample_app_gradle/sub/App3Test.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/gradle/recursion/expected.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/gradle/recursion/foo/bar/reports/1.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/jasmine/README.md +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/jasmine/jasmine-test-results-v3.99.0.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/jasmine/jasmine-test-results.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/jasmine/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/jasmine/subset_payload.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/jest/junit.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/jest/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/jest/subset_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/karma/README.md +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/karma/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/karma/sample-report.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/karma/subset_payload.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/karma/subset_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/maven/createdFile_1.lst +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/maven/createdFile_2.lst +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/maven/java/test/src/java/com/example/sample_app_maven/App2Test.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/maven/java/test/src/java/com/example/sample_app_maven/AppTest.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/maven/java/test/src/java/com/launchableinc/rocket_car_maven/e2e/E2ETest.java +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/maven/list.lst +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/maven/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/maven/reports/TEST-1.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/maven/reports/TEST-2.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/maven/reports/TEST-nested.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/maven/reports/dummy.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/maven/subset_by_absolute_time_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/maven/subset_by_confidence_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/maven/subset_from_file_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/maven/subset_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/maven/subset_scan_test_compile_lst_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/maven/subset_with_exclude_rules_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/minitest/TEST-Admin_UserTest.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/minitest/TEST-Admin_UserTest_ChildlenTest.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/minitest/TEST-UserControllerTest.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/minitest/TEST-UserCopyTest.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/minitest/TEST-UserTest.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/minitest/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/minitest/record_test_result_chunk1.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/minitest/record_test_result_chunk2.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/minitest/subset_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/minitest/test/example_test.rb +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/nunit/list.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/nunit/nunit-reporter-bug-with-nested-type.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/nunit/nunit-reporter-bug-with-nested-type.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/nunit/output-linux.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/nunit/output-windows.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/nunit/record_test_result-linux.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/nunit/record_test_result-windows.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/nunit/src/.gitignore +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/nunit/src/Program.cs +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/nunit/src/README.md +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/nunit/src/Test.cs +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/nunit/src/calc.csproj +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/nunit/subset_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/playwright/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/playwright/record_test_result_with_json.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/playwright/report.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/playwright/report.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/prove/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/prove/report.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/pytest/pytest.ini +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/pytest/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/pytest/record_test_result_json.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/pytest/report.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/pytest/report.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/pytest/subset_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/pytest/tests/conftest.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/pytest/tests/fooo/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/pytest/tests/fooo/filenameonly_test.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/pytest/tests/fooo/func4_test.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/pytest/tests/funcs3_test.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/pytest/tests/test_funcs1.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/pytest/tests/test_funcs2.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/robot/dryrun.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/robot/output.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/robot/record_test_executed_only_one_file_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/robot/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/robot/single-output.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/robot/subset_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/rspec/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/rspec/rspec.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/vitest/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/vitest/report.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/xctest/junit.xml +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/xctest/record_test_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/data/xctest/subset_result.json +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/helper.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/plugins/foo.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_cli_test_case.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_plugin.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_adb.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_ant.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_bazel.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_behave.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_codeceptjs.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_ctest.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_cts.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_cucumber.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_cypress.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_dotnet.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_file.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_go_test.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_googletest.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_gradle.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_jasmine.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_jest.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_karma.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_maven.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_minitest.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_nunit.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_playwright.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_prove.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_pytest.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_raw.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_robot.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_rspec.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_vitest.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_runners/test_xctest.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_testpath.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/test_version.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/utils/__init__.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/utils/test_authentication.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/utils/test_edit_distance.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/utils/test_fail_fast_mode.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/utils/test_file_name_pattern.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/utils/test_git_log_parser.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/utils/test_glob.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/utils/test_gzipgen.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/utils/test_http_client.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/utils/test_link.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/utils/test_logger.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/utils/test_session.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/utils/test_typer.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tests/utils/test_typer_types.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tools/README.md +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/tools/generate_reference.py +0 -0
- {smart_tests_cli-2.4.2 → smart_tests_cli-2.5.1}/uv.lock +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
FROM python:3.13-slim
|
|
1
|
+
FROM python:3.13-slim AS builder
|
|
2
2
|
|
|
3
3
|
RUN apt-get update && \
|
|
4
4
|
apt-get install -y --no-install-recommends \
|
|
@@ -13,15 +13,21 @@ COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv
|
|
|
13
13
|
WORKDIR /src
|
|
14
14
|
COPY . .
|
|
15
15
|
|
|
16
|
-
#
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
# Build wheel for distribution (standard Python package)
|
|
17
|
+
RUN uv build --wheel --out-dir /wheels
|
|
18
|
+
|
|
19
|
+
FROM python:3.13-slim
|
|
19
20
|
|
|
21
|
+
# Install runtime dependencies
|
|
20
22
|
RUN apt-get update && \
|
|
21
23
|
apt-get install -y --no-install-recommends openjdk-21-jre-headless git && \
|
|
22
24
|
rm -rf /var/lib/apt/lists/*
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
# Install wheel system-wide to /usr/local/bin
|
|
27
|
+
RUN --mount=type=bind,from=builder,source=/wheels,target=/wheels \
|
|
28
|
+
pip install --no-cache-dir /wheels/*.whl
|
|
29
|
+
|
|
30
|
+
RUN useradd --system --no-create-home smart-tests
|
|
25
31
|
USER smart-tests
|
|
26
32
|
|
|
27
33
|
ENTRYPOINT ["smart-tests"]
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import shutil
|
|
3
|
+
import textwrap
|
|
1
4
|
from dataclasses import dataclass
|
|
2
5
|
from http import HTTPStatus
|
|
3
6
|
from pathlib import Path
|
|
@@ -192,13 +195,54 @@ def _from_subset_ids(client: SmartTestsClient, subset_id_before: int, subset_id_
|
|
|
192
195
|
|
|
193
196
|
# Display results in a tabular format
|
|
194
197
|
headers = ["Δ Rank", "Subset Rank", "Test Name", "Reason", "Density"]
|
|
198
|
+
column_width = get_column_width()
|
|
195
199
|
tabular_data = [
|
|
196
|
-
(rank, after, test_name, reason, density)
|
|
200
|
+
(rank, after, wrap_data(test_name, width=column_width), wrap_data(reason, width=column_width), density)
|
|
197
201
|
for rank, after, test_name, reason, density in rows
|
|
198
202
|
]
|
|
199
203
|
click.echo_via_pager(summary + "\n" + tabulate(tabular_data, headers=headers, tablefmt="simple"))
|
|
200
204
|
|
|
201
205
|
|
|
206
|
+
def wrap_data(data: str, width: int = 30) -> str:
|
|
207
|
+
|
|
208
|
+
if not data:
|
|
209
|
+
return data
|
|
210
|
+
|
|
211
|
+
# Add space after / and \ to allow wrapping at these points
|
|
212
|
+
formatted_data = re.sub(r'([/\\])', r'\1 ', data)
|
|
213
|
+
wrapped = textwrap.fill(formatted_data, width=width)
|
|
214
|
+
# Remove the added spaces
|
|
215
|
+
wrapped = wrapped.replace("/ ", "/").replace("\\ ", "\\")
|
|
216
|
+
return wrapped
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def get_column_width() -> int:
|
|
220
|
+
|
|
221
|
+
try:
|
|
222
|
+
# Get terminal size, fallback to 80x24 if not detectable
|
|
223
|
+
terminal_size = shutil.get_terminal_size(fallback=(80, 24))
|
|
224
|
+
terminal_width = terminal_size.columns
|
|
225
|
+
|
|
226
|
+
# Estimate space needed for fixed columns and table formatting:
|
|
227
|
+
# - "Δ Rank" column: ~10 chars
|
|
228
|
+
# - "Subset Rank" column: ~12 chars
|
|
229
|
+
# - "Density" column: ~8 chars
|
|
230
|
+
# - Table separators and padding: ~6 chars
|
|
231
|
+
fixed_width = 36
|
|
232
|
+
|
|
233
|
+
# Calculate available width for the two wrappable columns
|
|
234
|
+
available_width = terminal_width - fixed_width
|
|
235
|
+
|
|
236
|
+
# Split equally between Test Name and Reason columns
|
|
237
|
+
column_width = available_width // 2
|
|
238
|
+
|
|
239
|
+
# Ensure minimum width of 30 characters
|
|
240
|
+
return max(30, column_width)
|
|
241
|
+
except Exception:
|
|
242
|
+
# If anything goes wrong, fall back to default
|
|
243
|
+
return 30
|
|
244
|
+
|
|
245
|
+
|
|
202
246
|
def _from_files(file_before: Path, file_after: Path):
|
|
203
247
|
before_subset = SubsetResultBases.from_file(file_before)
|
|
204
248
|
after_subset = SubsetResultBases.from_file(file_after)
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
import fnmatch
|
|
2
|
+
import os
|
|
2
3
|
import tarfile
|
|
3
4
|
import zipfile
|
|
4
5
|
from io import BytesIO
|
|
5
|
-
from typing import Annotated, List, Tuple
|
|
6
|
+
from typing import Annotated, List, Optional, Set, Tuple
|
|
6
7
|
|
|
7
8
|
import click
|
|
9
|
+
from tabulate import tabulate
|
|
8
10
|
|
|
9
11
|
import smart_tests.args4p.typer as typer
|
|
10
12
|
from smart_tests.utils.session import SessionId, get_session
|
|
11
13
|
|
|
12
14
|
from ... import args4p
|
|
13
15
|
from ...app import Application
|
|
14
|
-
from ...utils.fail_fast_mode import warn_and_exit_if_fail_fast_mode
|
|
15
16
|
from ...utils.smart_tests_client import SmartTestsClient
|
|
16
|
-
from tabulate import tabulate
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
class AttachmentStatus:
|
|
20
20
|
SUCCESS = "✓ Recorded successfully"
|
|
21
21
|
FAILED = "⚠ Failed to record"
|
|
22
22
|
SKIPPED_NON_TEXT = "⚠ Skipped: not a valid text file"
|
|
23
|
+
SKIPPED_DUPLICATE = "⚠ Skipped: duplicate"
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
@args4p.command(help="Record attachment information")
|
|
@@ -39,6 +40,8 @@ def attachment(
|
|
|
39
40
|
):
|
|
40
41
|
client = SmartTestsClient(app=app)
|
|
41
42
|
summary_rows = []
|
|
43
|
+
used_filenames: Set[str] = set()
|
|
44
|
+
|
|
42
45
|
try:
|
|
43
46
|
# Note: Call get_session method to check test session exists
|
|
44
47
|
_ = get_session(session, client)
|
|
@@ -50,7 +53,7 @@ def attachment(
|
|
|
50
53
|
if zip_info.is_dir():
|
|
51
54
|
continue
|
|
52
55
|
|
|
53
|
-
if not matches_include_patterns(zip_info.filename, include_patterns):
|
|
56
|
+
if not matches_include_patterns(zip_info.filename, tuple(include_patterns)):
|
|
54
57
|
continue
|
|
55
58
|
|
|
56
59
|
file_content = zip_file.read(zip_info.filename)
|
|
@@ -60,9 +63,15 @@ def attachment(
|
|
|
60
63
|
[zip_info.filename, AttachmentStatus.SKIPPED_NON_TEXT])
|
|
61
64
|
continue
|
|
62
65
|
|
|
66
|
+
file_name = get_unique_filename(zip_info.filename, used_filenames)
|
|
67
|
+
if not file_name:
|
|
68
|
+
summary_rows.append(
|
|
69
|
+
[zip_info.filename, AttachmentStatus.SKIPPED_DUPLICATE])
|
|
70
|
+
continue
|
|
71
|
+
|
|
63
72
|
status = post_attachment(
|
|
64
|
-
client, session, file_content,
|
|
65
|
-
summary_rows.append([
|
|
73
|
+
client, session, file_content, file_name)
|
|
74
|
+
summary_rows.append([file_name, status])
|
|
66
75
|
|
|
67
76
|
# If tar file (tar, tar.gz, tar.bz2, tgz, etc.)
|
|
68
77
|
elif tarfile.is_tarfile(a):
|
|
@@ -71,7 +80,7 @@ def attachment(
|
|
|
71
80
|
if tar_info.isdir():
|
|
72
81
|
continue
|
|
73
82
|
|
|
74
|
-
if not matches_include_patterns(tar_info.name, include_patterns):
|
|
83
|
+
if not matches_include_patterns(tar_info.name, tuple(include_patterns)):
|
|
75
84
|
continue
|
|
76
85
|
|
|
77
86
|
file_obj = tar_file.extractfile(tar_info)
|
|
@@ -85,9 +94,15 @@ def attachment(
|
|
|
85
94
|
[tar_info.name, AttachmentStatus.SKIPPED_NON_TEXT])
|
|
86
95
|
continue
|
|
87
96
|
|
|
97
|
+
file_name = get_unique_filename(tar_info.name, used_filenames)
|
|
98
|
+
if not file_name:
|
|
99
|
+
summary_rows.append(
|
|
100
|
+
[tar_info.name, AttachmentStatus.SKIPPED_DUPLICATE])
|
|
101
|
+
continue
|
|
102
|
+
|
|
88
103
|
status = post_attachment(
|
|
89
|
-
client, session, file_content,
|
|
90
|
-
summary_rows.append([
|
|
104
|
+
client, session, file_content, file_name)
|
|
105
|
+
summary_rows.append([file_name, status])
|
|
91
106
|
|
|
92
107
|
else:
|
|
93
108
|
with open(a, mode='rb') as f:
|
|
@@ -98,15 +113,55 @@ def attachment(
|
|
|
98
113
|
[a, AttachmentStatus.SKIPPED_NON_TEXT])
|
|
99
114
|
continue
|
|
100
115
|
|
|
101
|
-
|
|
102
|
-
|
|
116
|
+
file_name = get_unique_filename(a, used_filenames)
|
|
117
|
+
if not file_name:
|
|
118
|
+
summary_rows.append(
|
|
119
|
+
[a, AttachmentStatus.SKIPPED_DUPLICATE])
|
|
120
|
+
continue
|
|
121
|
+
|
|
122
|
+
status = post_attachment(client, session, file_content, file_name)
|
|
123
|
+
summary_rows.append([file_name, status])
|
|
124
|
+
|
|
103
125
|
except Exception as e:
|
|
104
126
|
client.print_exception_and_recover(e)
|
|
105
127
|
|
|
106
128
|
display_summary_as_table(summary_rows)
|
|
107
129
|
|
|
108
130
|
|
|
109
|
-
def
|
|
131
|
+
def get_unique_filename(filepath: str, used_filenames: Set[str]) -> Optional[str]:
|
|
132
|
+
"""
|
|
133
|
+
Get a unique filename by extracting the basename and prepending parent folders if needed.
|
|
134
|
+
Strategy:
|
|
135
|
+
1. First occurrence: use basename (e.g., app.log)
|
|
136
|
+
2. Duplicate: prepend parent directories until unique
|
|
137
|
+
"""
|
|
138
|
+
# Normalize path separators to forward slash (archives always use forward slash in both linux, and windows)
|
|
139
|
+
normalized_path = filepath.replace(os.sep, '/')
|
|
140
|
+
normalized_path = normalize_filename(normalized_path)
|
|
141
|
+
|
|
142
|
+
basename = normalized_path.split('/')[-1]
|
|
143
|
+
|
|
144
|
+
# If basename is not used, return it
|
|
145
|
+
if basename not in used_filenames:
|
|
146
|
+
used_filenames.add(basename)
|
|
147
|
+
return basename
|
|
148
|
+
|
|
149
|
+
# Try prepending parents from nearest to farthest
|
|
150
|
+
path_parts = normalized_path.split('/')
|
|
151
|
+
parent_parts = [p for p in path_parts[:-1] if p]
|
|
152
|
+
|
|
153
|
+
prefixed_name = basename
|
|
154
|
+
for parent in reversed(parent_parts):
|
|
155
|
+
prefixed_name = f"{parent}/{prefixed_name}"
|
|
156
|
+
|
|
157
|
+
if prefixed_name not in used_filenames:
|
|
158
|
+
used_filenames.add(prefixed_name)
|
|
159
|
+
return prefixed_name
|
|
160
|
+
|
|
161
|
+
return None
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def matches_include_patterns(filename: str, include_patterns: Tuple[str, ...]) -> bool:
|
|
110
165
|
"""
|
|
111
166
|
Check if a file should be included based on the include patterns.
|
|
112
167
|
If no patterns are specified, all files are included.
|
|
@@ -121,6 +176,13 @@ def matches_include_patterns(filename: str, include_patterns: List[str]) -> bool
|
|
|
121
176
|
return False
|
|
122
177
|
|
|
123
178
|
|
|
179
|
+
def normalize_filename(filename: str) -> str:
|
|
180
|
+
"""
|
|
181
|
+
Normalize filename by replacing whitespace with dashes.
|
|
182
|
+
"""
|
|
183
|
+
return filename.replace(' ', '-')
|
|
184
|
+
|
|
185
|
+
|
|
124
186
|
def valid_utf8_file(file_content: bytes) -> bool:
|
|
125
187
|
# Check for null bytes (binary files)
|
|
126
188
|
if b'\x00' in file_content:
|
|
@@ -537,7 +537,7 @@ class Subset(TestPathWriter):
|
|
|
537
537
|
|
|
538
538
|
def _collect_potential_test_files(self):
|
|
539
539
|
LOOSE_TEST_FILE_PATTERN = r'(\.(test|spec)\.|_test\.|Test\.|Spec\.|test/|tests/|__tests__/|src/test/)'
|
|
540
|
-
EXCLUDE_PATTERN = r'(BUILD|Makefile|Dockerfile|LICENSE|.gitignore|.gitkeep|.keep|id_rsa|rsa|blank|taglib)|\.(xml|json|jsonl|txt|yml|yaml|toml|md|png|jpg|jpeg|gif|svg|sql|html|css|graphql|proto|gz|zip|rz|bzl|conf|config|snap|pem|crt|key|lock|jpi|hpi|jelly|properties|jar|ini|mod|sum|bmp|env|envrc|sh)$' # noqa E501
|
|
540
|
+
EXCLUDE_PATTERN = r'(BUILD|Makefile|Dockerfile|LICENSE|.gitignore|.gitkeep|.keep|id_rsa|rsa|blank|taglib)|\.(xml|json|jsonl|txt|yml|yaml|toml|md|png|jpg|jpeg|gif|svg|sql|html|css|graphql|proto|gz|zip|rz|bzl|conf|config|snap|pem|crt|key|lock|jpi|hpi|jelly|properties|jar|ini|mod|sum|bmp|env|envrc|sh|csv|list)$' # noqa E501
|
|
541
541
|
|
|
542
542
|
try:
|
|
543
543
|
git_managed_files = subprocess.run(['git', 'ls-files'], stdout=subprocess.PIPE,
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import glob
|
|
2
2
|
import os
|
|
3
3
|
import re
|
|
4
|
-
from typing import Annotated
|
|
5
|
-
from typing import Dict, List, Tuple
|
|
4
|
+
from typing import Annotated, Dict, List
|
|
6
5
|
|
|
7
6
|
import click
|
|
8
7
|
|
|
9
8
|
import smart_tests.args4p.typer as typer
|
|
10
9
|
from smart_tests.utils import glob as uglob
|
|
11
10
|
from smart_tests.utils.java import junit5_nested_class_path_builder
|
|
12
|
-
|
|
11
|
+
|
|
13
12
|
from ..args4p.exceptions import BadCmdLineException
|
|
14
13
|
from ..commands.record.tests import RecordTests
|
|
15
14
|
from ..commands.subset import Subset
|
|
15
|
+
from . import smart_tests
|
|
16
16
|
|
|
17
17
|
# Surefire has the default inclusion pattern
|
|
18
18
|
# https://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html#includes
|
|
@@ -169,4 +169,15 @@ def record_tests(
|
|
|
169
169
|
)],
|
|
170
170
|
):
|
|
171
171
|
client.path_builder = junit5_nested_class_path_builder(client.path_builder)
|
|
172
|
+
|
|
173
|
+
# Override report method to filter out non-JUnit report files
|
|
174
|
+
original_report = client.report
|
|
175
|
+
|
|
176
|
+
IGNORED_FILES = {'failsafe-summary.xml', 'testng-results.xml'}
|
|
177
|
+
|
|
178
|
+
def report_with_filter(junit_report_file: str):
|
|
179
|
+
if not any(junit_report_file.endswith(f) for f in IGNORED_FILES):
|
|
180
|
+
original_report(junit_report_file)
|
|
181
|
+
|
|
182
|
+
client.report = report_with_filter # type: ignore[method-assign]
|
|
172
183
|
smart_tests.CommonRecordTestImpls.load_report_files(client=client, source_roots=reports)
|
|
@@ -3,7 +3,8 @@ import json
|
|
|
3
3
|
import os
|
|
4
4
|
import pathlib
|
|
5
5
|
import subprocess
|
|
6
|
-
from
|
|
6
|
+
from datetime import datetime, timezone
|
|
7
|
+
from typing import Annotated, Generator, Iterable, List, Optional
|
|
7
8
|
|
|
8
9
|
import click
|
|
9
10
|
from junitparser import Properties, TestCase # type: ignore
|
|
@@ -17,7 +18,6 @@ from ..commands.record.tests import RecordTests
|
|
|
17
18
|
from ..commands.subset import Subset
|
|
18
19
|
from . import smart_tests
|
|
19
20
|
|
|
20
|
-
|
|
21
21
|
# Please specify junit_family=legacy for pytest report format. if using pytest version 6 or higher.
|
|
22
22
|
# - pytest has changed its default test report format from xunit1 to xunit2 since version 6.
|
|
23
23
|
# - https://docs.pytest.org/en/latest/deprecations.html#junit-family-default-value-change-to-xunit2
|
|
@@ -40,6 +40,15 @@ from . import smart_tests
|
|
|
40
40
|
# <testcase classname="tests.test_mod.TestClass" name="test__can_print_aaa" file="tests/test_mod.py"
|
|
41
41
|
# line="3" time="0.001" />
|
|
42
42
|
#
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _timestamp_to_iso(ts: Optional[float]) -> Optional[str]:
|
|
46
|
+
# convert to ISO-8601 formatted date
|
|
47
|
+
if ts is None:
|
|
48
|
+
return None
|
|
49
|
+
return datetime.fromtimestamp(ts, tz=timezone.utc).isoformat()
|
|
50
|
+
|
|
51
|
+
|
|
43
52
|
@smart_tests.subset
|
|
44
53
|
def subset(
|
|
45
54
|
client: Subset,
|
|
@@ -344,15 +353,39 @@ class PytestJSONReportParser:
|
|
|
344
353
|
else:
|
|
345
354
|
props = None
|
|
346
355
|
|
|
356
|
+
# extract raw timestamps
|
|
357
|
+
start_timestamp = data.get("start")
|
|
358
|
+
stop_timestamp = data.get("stop")
|
|
359
|
+
|
|
360
|
+
# convert to ISO-8601
|
|
361
|
+
start_timestamp_iso_format = _timestamp_to_iso(start_timestamp)
|
|
362
|
+
end_timestamp_iso_format = _timestamp_to_iso(stop_timestamp)
|
|
363
|
+
|
|
364
|
+
print(
|
|
365
|
+
f"DEBUG pytest timing start={start_timestamp_iso_format}, stop={end_timestamp_iso_format}"
|
|
366
|
+
)
|
|
367
|
+
|
|
368
|
+
event_data = {}
|
|
369
|
+
if start_timestamp_iso_format:
|
|
370
|
+
event_data["start_timestamp"] = start_timestamp_iso_format
|
|
371
|
+
if end_timestamp_iso_format:
|
|
372
|
+
event_data["stop_timestamp"] = end_timestamp_iso_format
|
|
373
|
+
|
|
347
374
|
test_path = _parse_pytest_nodeid(nodeid)
|
|
348
375
|
for path in test_path:
|
|
349
376
|
if path.get("type") == "file":
|
|
350
377
|
path["name"] = pathlib.Path(path["name"]).as_posix()
|
|
351
378
|
|
|
379
|
+
data_payload = event_data if event_data else None
|
|
380
|
+
|
|
381
|
+
# end_timestamp_iso_format is being passed as timestamp as it reflects event finalization
|
|
382
|
+
# start + duration = stop
|
|
383
|
+
# sending both start and stop time in the event data field
|
|
352
384
|
yield CaseEvent.create(
|
|
353
385
|
test_path=test_path,
|
|
354
386
|
duration_secs=data.get("duration", 0),
|
|
355
387
|
status=status,
|
|
356
388
|
stdout=stdout,
|
|
357
389
|
stderr=stderr,
|
|
358
|
-
|
|
390
|
+
timestamp=end_timestamp_iso_format,
|
|
391
|
+
data=data_payload)
|
|
@@ -201,17 +201,149 @@ class SubsetsTest(CliTestCase):
|
|
|
201
201
|
mix_stderr=False)
|
|
202
202
|
|
|
203
203
|
self.assert_success(result)
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
204
|
+
output = result.stdout
|
|
205
|
+
self.assertIn("3 tests analyzed | 1 ↑ promoted | 1 ↓ demoted", output)
|
|
206
|
+
self.assertIn("Code files affected: bbb.py, ccc.py, ddd.py", output)
|
|
207
|
+
self.assertIn("Δ Rank", output)
|
|
208
|
+
self.assertIn("Density", output)
|
|
209
|
+
for expected_row in [
|
|
210
|
+
("NEW", "1", "file=ddd.py", "Changed file: ddd.py", "0.9"),
|
|
211
|
+
("↑1", "2", "file=ccc.py", "Changed file: ccc.py", "0.7"),
|
|
212
|
+
("↓1", "3", "file=bbb.py", "Changed file: bbb.py", "0.5"),
|
|
213
|
+
("DELETED", "-", "file=aaa.py"),
|
|
214
|
+
]:
|
|
215
|
+
for cell in expected_row:
|
|
216
|
+
self.assertIn(cell, output)
|
|
217
|
+
|
|
218
|
+
def test_wrap_data(self):
|
|
219
|
+
"""Test that wrap_data breaks paths at separators."""
|
|
220
|
+
from smart_tests.commands.compare.subsets import wrap_data
|
|
221
|
+
|
|
222
|
+
# Short path - no wrapping needed
|
|
223
|
+
short = "Changed file: aaa.py"
|
|
224
|
+
self.assertEqual(wrap_data(short, width=30), short)
|
|
225
|
+
|
|
226
|
+
# Empty string
|
|
227
|
+
self.assertEqual(wrap_data("", width=30), "")
|
|
228
|
+
|
|
229
|
+
# Long path - should wrap at /
|
|
230
|
+
long_path = "Changed file: src/mongo/db/telemetry/telemetry_thread_base.cpp"
|
|
231
|
+
wrapped = wrap_data(long_path, width=30)
|
|
232
|
+
|
|
233
|
+
# Verify it contains newlines
|
|
234
|
+
self.assertIn("\n", wrapped)
|
|
235
|
+
|
|
236
|
+
# Verify no unwanted spaces around path separators
|
|
237
|
+
self.assertNotIn(" /", wrapped)
|
|
238
|
+
|
|
239
|
+
# Verify content is preserved (just reformatted)
|
|
240
|
+
unwrapped = wrapped.replace("\n", "")
|
|
241
|
+
self.assertEqual(unwrapped, long_path)
|
|
242
|
+
|
|
243
|
+
# Windows path test
|
|
244
|
+
windows_path = "Changed file: C:\\Users\\test\\very\\long\\windows\\path\\file.cpp"
|
|
245
|
+
wrapped_win = wrap_data(windows_path, width=30)
|
|
246
|
+
self.assertIn("\n", wrapped_win)
|
|
247
|
+
self.assertNotIn(" \\", wrapped_win)
|
|
248
|
+
|
|
249
|
+
# Verify content preservation
|
|
250
|
+
self.assertEqual(wrapped_win.replace("\n", ""), windows_path)
|
|
251
|
+
|
|
252
|
+
def test_get_column_width(self):
|
|
253
|
+
"""Test that get_column_width() calculates widths based on terminal size."""
|
|
254
|
+
from smart_tests.commands.compare.subsets import get_column_width
|
|
255
|
+
|
|
256
|
+
# Test with a wide terminal (e.g., 160 columns)
|
|
257
|
+
# Available width = 160 - 36 (fixed columns) = 124
|
|
258
|
+
# Per column = 124 / 2 = 62
|
|
259
|
+
with mock.patch("shutil.get_terminal_size") as mock_terminal:
|
|
260
|
+
mock_terminal.return_value = os.terminal_size((160, 24))
|
|
261
|
+
width = get_column_width()
|
|
262
|
+
self.assertEqual(width, 62)
|
|
263
|
+
|
|
264
|
+
# Test with standard terminal (80 columns)
|
|
265
|
+
# Available width = 80 - 36 = 44
|
|
266
|
+
# Per column = 44 / 2 = 22, but minimum is 30
|
|
267
|
+
with mock.patch("shutil.get_terminal_size") as mock_terminal:
|
|
268
|
+
mock_terminal.return_value = os.terminal_size((80, 24))
|
|
269
|
+
width = get_column_width()
|
|
270
|
+
self.assertEqual(width, 30) # Should hit minimum
|
|
271
|
+
|
|
272
|
+
# Test with narrow terminal (60 columns)
|
|
273
|
+
# Should still return minimum of 30
|
|
274
|
+
with mock.patch("shutil.get_terminal_size") as mock_terminal:
|
|
275
|
+
mock_terminal.return_value = os.terminal_size((60, 24))
|
|
276
|
+
width = get_column_width()
|
|
277
|
+
self.assertEqual(width, 30) # Should hit minimum
|
|
278
|
+
|
|
279
|
+
# Test with very wide terminal (200 columns)
|
|
280
|
+
# Available width = 200 - 36 = 164
|
|
281
|
+
# Per column = 164 / 2 = 82
|
|
282
|
+
with mock.patch("shutil.get_terminal_size") as mock_terminal:
|
|
283
|
+
mock_terminal.return_value = os.terminal_size((200, 24))
|
|
284
|
+
width = get_column_width()
|
|
285
|
+
self.assertEqual(width, 82)
|
|
286
|
+
|
|
287
|
+
# Test fallback when get_terminal_size raises exception
|
|
288
|
+
with mock.patch("shutil.get_terminal_size") as mock_terminal:
|
|
289
|
+
mock_terminal.side_effect = Exception("Terminal size unavailable")
|
|
290
|
+
width = get_column_width()
|
|
291
|
+
self.assertEqual(width, 30) # Should fall back to default
|
|
292
|
+
|
|
293
|
+
@mock.patch.dict(os.environ, {"SMART_TESTS_TOKEN": CliTestCase.smart_tests_token})
|
|
294
|
+
@responses.activate
|
|
295
|
+
def test_subsets_with_long_paths_wrapped(self):
|
|
296
|
+
"""Test that long file paths in Reason column are wrapped properly."""
|
|
297
|
+
long_path1 = "src/mongo/db/telemetry/telemetry_thread_base.cpp"
|
|
298
|
+
long_path2 = "jstests/concurrency/fsm_workloads/timeseries/timeseries_raw_data_operations.js"
|
|
299
|
+
|
|
300
|
+
responses.add(
|
|
301
|
+
responses.GET,
|
|
302
|
+
f"{get_base_url()}/intake/organizations/{self.organization}/workspaces/{self.workspace}/subset/200",
|
|
303
|
+
json={
|
|
304
|
+
"subsetting": {"id": 200},
|
|
305
|
+
"testPaths": [
|
|
306
|
+
{"testPath": [{"type": "file", "name": long_path1}],
|
|
307
|
+
"duration": 10, "density": 0.9,
|
|
308
|
+
"reason": f"Changed file: {long_path1}"}
|
|
309
|
+
],
|
|
310
|
+
"rest": []
|
|
311
|
+
},
|
|
312
|
+
status=200
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
responses.add(
|
|
316
|
+
responses.GET,
|
|
317
|
+
f"{get_base_url()}/intake/organizations/{self.organization}/workspaces/{self.workspace}/subset/201",
|
|
318
|
+
json={
|
|
319
|
+
"subsetting": {"id": 201},
|
|
320
|
+
"testPaths": [
|
|
321
|
+
{"testPath": [{"type": "file", "name": long_path2}],
|
|
322
|
+
"duration": 10, "density": 0.85,
|
|
323
|
+
"reason": f"Changed file: {long_path2}"}
|
|
324
|
+
],
|
|
325
|
+
"rest": []
|
|
326
|
+
},
|
|
327
|
+
status=200
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
result = self.cli('compare', 'subsets',
|
|
331
|
+
'--subset-id-before', '200',
|
|
332
|
+
'--subset-id-after', '201',
|
|
333
|
+
mix_stderr=False)
|
|
334
|
+
|
|
335
|
+
self.assert_success(result)
|
|
336
|
+
|
|
337
|
+
# Verify output contains the summary
|
|
338
|
+
self.assertIn("PTS subset change summary:", result.stdout)
|
|
339
|
+
self.assertIn("Changed file:", result.stdout)
|
|
340
|
+
|
|
341
|
+
# Verify the long paths are present (even if wrapped)
|
|
342
|
+
self.assertIn("telemetry_thread_base.cpp", result.stdout)
|
|
343
|
+
self.assertIn("timeseries_raw_data_operations.js", result.stdout)
|
|
344
|
+
|
|
345
|
+
# Verify no line has excessive length (wrapped properly)
|
|
346
|
+
for line in result.stdout.split('\n'):
|
|
347
|
+
# Allow some buffer for separator lines
|
|
348
|
+
if line.strip() and not line.startswith('─'):
|
|
349
|
+
self.assertLessEqual(len(line), 150)
|