infinity_test 1.0.3 → 2.0.0.rc2
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.
- checksums.yaml +7 -0
- data/.github/workflows/ci.yml +31 -0
- data/.gitignore +3 -0
- data/.rspec +2 -2
- data/AI_INTEGRATION_IDEAS.md +203 -0
- data/Gemfile +3 -15
- data/HISTORY.md +84 -0
- data/History.markdown +82 -0
- data/{.infinity_test → INFINITY_TEST} +18 -15
- data/LICENSE.txt +2 -2
- data/README.md +867 -0
- data/Rakefile +1 -65
- data/TODO.markdown +38 -24
- data/bin/infinity_test +1 -4
- data/images/fuuu/pending.png +0 -0
- data/images/fuuu/success.png +0 -0
- data/infinity_test.gemspec +41 -189
- data/lib/infinity_test/core/auto_discover.rb +67 -0
- data/lib/infinity_test/core/base.rb +369 -0
- data/lib/infinity_test/core/callback.rb +59 -0
- data/lib/infinity_test/core/changed_file.rb +13 -0
- data/lib/infinity_test/core/command_builder.rb +48 -0
- data/lib/infinity_test/core/command_runner.rb +38 -0
- data/lib/infinity_test/core/configuration_merge.rb +37 -0
- data/lib/infinity_test/core/continuous_test_server.rb +124 -0
- data/lib/infinity_test/core/load_configuration.rb +48 -0
- data/lib/infinity_test/core/notifier.rb +59 -0
- data/lib/infinity_test/core/options.rb +134 -0
- data/lib/infinity_test/core/runner.rb +18 -0
- data/lib/infinity_test/core/version.rb +5 -0
- data/lib/infinity_test/framework/base.rb +93 -0
- data/lib/infinity_test/framework/django.rb +109 -0
- data/lib/infinity_test/framework/elixir_mix.rb +47 -0
- data/lib/infinity_test/framework/fast_api.rb +104 -0
- data/lib/infinity_test/framework/padrino.rb +30 -0
- data/lib/infinity_test/framework/phoenix.rb +72 -0
- data/lib/infinity_test/framework/python_package.rb +97 -0
- data/lib/infinity_test/framework/rails.rb +26 -0
- data/lib/infinity_test/framework/rocket.rb +70 -0
- data/lib/infinity_test/framework/rubygems.rb +29 -0
- data/lib/infinity_test/framework/rust_cargo.rb +69 -0
- data/lib/infinity_test/framework/shared_example.rb +47 -0
- data/lib/infinity_test/observer/base.rb +40 -0
- data/lib/infinity_test/observer/filewatcher.rb +72 -0
- data/lib/infinity_test/observer/listen.rb +74 -0
- data/lib/infinity_test/observer/shared_example.rb +35 -0
- data/lib/infinity_test/old_dsl/configuration.rb +26 -0
- data/lib/infinity_test/strategy/base.rb +50 -0
- data/lib/infinity_test/strategy/elixir_default.rb +20 -0
- data/lib/infinity_test/strategy/python_default.rb +22 -0
- data/lib/infinity_test/strategy/rbenv.rb +34 -0
- data/lib/infinity_test/strategy/ruby_default.rb +21 -0
- data/lib/infinity_test/strategy/rust_default.rb +21 -0
- data/lib/infinity_test/strategy/rvm.rb +52 -0
- data/lib/infinity_test/strategy/shared_example.rb +32 -0
- data/lib/infinity_test/test_framework/base.rb +64 -0
- data/lib/infinity_test/test_framework/cargo_test.rb +49 -0
- data/lib/infinity_test/test_framework/ex_unit.rb +53 -0
- data/lib/infinity_test/test_framework/pytest.rb +65 -0
- data/lib/infinity_test/test_framework/rspec.rb +48 -0
- data/lib/infinity_test/test_framework/shared_example.rb +56 -0
- data/lib/infinity_test/test_framework/test_unit.rb +57 -0
- data/lib/infinity_test.rb +66 -35
- data/spec/infinity_test/core/auto_discover_spec.rb +175 -0
- data/spec/infinity_test/core/base_spec.rb +240 -0
- data/spec/infinity_test/core/callback_spec.rb +89 -0
- data/spec/infinity_test/core/changed_file_spec.rb +26 -0
- data/spec/infinity_test/core/command_builder_spec.rb +38 -0
- data/spec/infinity_test/core/configuration_merge_spec.rb +124 -0
- data/spec/infinity_test/core/continuous_test_server_spec.rb +116 -0
- data/spec/infinity_test/core/load_configuration_spec.rb +43 -0
- data/spec/infinity_test/core/notifier_spec.rb +151 -0
- data/spec/infinity_test/core/options_spec.rb +168 -0
- data/spec/infinity_test/core/runner_spec.rb +17 -0
- data/spec/infinity_test/framework/base_spec.rb +55 -0
- data/spec/infinity_test/framework/django_spec.rb +95 -0
- data/spec/infinity_test/framework/elixir_mix_spec.rb +44 -0
- data/spec/infinity_test/framework/fast_api_spec.rb +96 -0
- data/spec/infinity_test/framework/padrino_spec.rb +58 -0
- data/spec/infinity_test/framework/phoenix_spec.rb +85 -0
- data/spec/infinity_test/framework/python_package_spec.rb +95 -0
- data/spec/infinity_test/framework/rails_spec.rb +58 -0
- data/spec/infinity_test/framework/rocket_spec.rb +69 -0
- data/spec/infinity_test/framework/rubygems_spec.rb +34 -0
- data/spec/infinity_test/framework/rust_cargo_spec.rb +94 -0
- data/spec/infinity_test/observer/base_spec.rb +78 -0
- data/spec/infinity_test/observer/filewatcher_spec.rb +51 -0
- data/spec/infinity_test/observer/listen_spec.rb +50 -0
- data/spec/infinity_test/{builder_spec.rb → strategy/base_spec.rb} +1 -2
- data/spec/infinity_test/strategy/elixir_default_spec.rb +46 -0
- data/spec/infinity_test/strategy/python_default_spec.rb +56 -0
- data/spec/infinity_test/strategy/rbenv_spec.rb +70 -0
- data/spec/infinity_test/strategy/ruby_default_spec.rb +49 -0
- data/spec/infinity_test/strategy/rust_default_spec.rb +56 -0
- data/spec/infinity_test/strategy/rvm_spec.rb +86 -0
- data/spec/infinity_test/test_framework/cargo_test_spec.rb +145 -0
- data/spec/infinity_test/test_framework/ex_unit_spec.rb +153 -0
- data/spec/infinity_test/test_framework/pytest_spec.rb +182 -0
- data/spec/infinity_test/test_framework/rspec_spec.rb +119 -0
- data/spec/infinity_test/test_framework/test_unit_spec.rb +193 -0
- data/spec/spec_helper.rb +34 -119
- metadata +315 -177
- data/.rvmrc +0 -1
- data/Gemfile.lock +0 -62
- data/Readme.markdown +0 -147
- data/Tasks +0 -4
- data/VERSION.yml +0 -5
- data/buzz_images/buzz_lightyear.jpg +0 -0
- data/buzz_images/buzz_lightyear_continencia.gif +0 -0
- data/buzz_images/to_infinity_and_beyond.png +0 -0
- data/features/heuristics.feature +0 -23
- data/features/support/env.rb +0 -2
- data/images/fuuu/sucess.png +0 -0
- data/lib/infinity_test/application.rb +0 -362
- data/lib/infinity_test/application_library/rails.rb +0 -94
- data/lib/infinity_test/application_library/rubygems.rb +0 -43
- data/lib/infinity_test/binary_path.rb +0 -43
- data/lib/infinity_test/builder.rb +0 -66
- data/lib/infinity_test/command.rb +0 -58
- data/lib/infinity_test/configuration.rb +0 -277
- data/lib/infinity_test/continuous_testing.rb +0 -40
- data/lib/infinity_test/dependencies.rb +0 -80
- data/lib/infinity_test/environment.rb +0 -15
- data/lib/infinity_test/heuristics.rb +0 -36
- data/lib/infinity_test/heuristics_helper.rb +0 -9
- data/lib/infinity_test/options.rb +0 -96
- data/lib/infinity_test/runner.rb +0 -38
- data/lib/infinity_test/test_framework.rb +0 -110
- data/lib/infinity_test/test_library/bacon.rb +0 -55
- data/lib/infinity_test/test_library/cucumber.rb +0 -22
- data/lib/infinity_test/test_library/rspec.rb +0 -60
- data/lib/infinity_test/test_library/test_unit.rb +0 -52
- data/lib/infinity_test/test_unit_loader.rb +0 -5
- data/spec/factories/buzz/lib/buzz.rb +0 -0
- data/spec/factories/buzz/spec/buzz_spec.rb +0 -0
- data/spec/factories/company/Gemfile +0 -0
- data/spec/factories/company/lib/company.rb +0 -0
- data/spec/factories/company/test/company_test.rb +0 -0
- data/spec/factories/images/failure.png +0 -0
- data/spec/factories/images/pending.png +0 -0
- data/spec/factories/images/sucess.png +0 -0
- data/spec/factories/infinity_test +0 -5
- data/spec/factories/infinity_test_example +0 -7
- data/spec/factories/slinky/spec/slinky/slinky_spec.rb +0 -0
- data/spec/factories/travel/lib/travel.rb +0 -0
- data/spec/factories/travel/test/partner_test.rb +0 -0
- data/spec/factories/travel/test/travel_test.rb +0 -0
- data/spec/factories/wood/lib/wood.rb +0 -0
- data/spec/factories/wood/spec/wood_spec.rb +0 -0
- data/spec/infinity_test/application_library/rails_spec.rb +0 -140
- data/spec/infinity_test/application_library/rubygems_spec.rb +0 -52
- data/spec/infinity_test/application_spec.rb +0 -434
- data/spec/infinity_test/binary_path_spec.rb +0 -72
- data/spec/infinity_test/command_spec.rb +0 -53
- data/spec/infinity_test/configuration_spec.rb +0 -382
- data/spec/infinity_test/continuous_testing_spec.rb +0 -25
- data/spec/infinity_test/environment_spec.rb +0 -23
- data/spec/infinity_test/heuristics_helper_spec.rb +0 -15
- data/spec/infinity_test/heuristics_spec.rb +0 -127
- data/spec/infinity_test/options_spec.rb +0 -111
- data/spec/infinity_test/runner_spec.rb +0 -42
- data/spec/infinity_test/test_framework_spec.rb +0 -127
- data/spec/infinity_test/test_library/bacon_spec.rb +0 -150
- data/spec/infinity_test/test_library/cucumber_spec.rb +0 -8
- data/spec/infinity_test/test_library/rspec_spec.rb +0 -189
- data/spec/infinity_test/test_library/test_unit_spec.rb +0 -184
- data/spec/infinity_test_spec.rb +0 -40
- /data/images/faces/{sucess.png → success.png} +0 -0
- /data/images/hands/{sucess.png → success.png} +0 -0
- /data/images/mario_bros/{sucess.jpg → success.jpg} +0 -0
- /data/images/rails/{sucess.png → success.png} +0 -0
- /data/images/rubies/{sucess.png → success.png} +0 -0
- /data/images/simpson/{sucess.jpg → success.jpg} +0 -0
- /data/images/street_fighter/{sucess.jpg → success.jpg} +0 -0
- /data/images/toy_story/{sucess.png → success.png} +0 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
module InfinityTest
|
|
2
|
+
module Framework
|
|
3
|
+
class Phoenix < Base
|
|
4
|
+
delegate :test_dir, :test_helper_file, to: :test_framework
|
|
5
|
+
|
|
6
|
+
# Override to use .exs extension for Elixir test files.
|
|
7
|
+
#
|
|
8
|
+
def heuristics!
|
|
9
|
+
hike.append_extension('.exs')
|
|
10
|
+
hike.append_path(test_framework.test_dir)
|
|
11
|
+
heuristics
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Add Heuristics to the observer run on pattern changes!
|
|
15
|
+
#
|
|
16
|
+
# ==== Heuristics
|
|
17
|
+
# * Watch all lib/*_web directories (controllers, views, live, channels)
|
|
18
|
+
# * Watch lib dir (.ex files) and run corresponding test
|
|
19
|
+
# * Watch test dir (.exs files) and run the changed file
|
|
20
|
+
# * Watch test helper and run all tests
|
|
21
|
+
#
|
|
22
|
+
def heuristics
|
|
23
|
+
watch_lib_dirs
|
|
24
|
+
watch_dir(test_dir, :exs) { |file| run_file(file) }
|
|
25
|
+
watch(test_helper_file) { run_all }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Auto-discover and watch all directories under lib/ that contain .ex files.
|
|
29
|
+
# Maps lib/my_app/accounts to test/my_app/accounts, etc.
|
|
30
|
+
#
|
|
31
|
+
def watch_lib_dirs
|
|
32
|
+
return unless File.directory?('lib')
|
|
33
|
+
|
|
34
|
+
Dir.glob('lib/*').each do |lib_dir|
|
|
35
|
+
next unless File.directory?(lib_dir)
|
|
36
|
+
next unless Dir.glob("#{lib_dir}/**/*.ex").any?
|
|
37
|
+
|
|
38
|
+
watch_dir(lib_dir, :ex) { |file| run_test_in_lib(file, lib_dir) }
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Run test preserving the directory structure.
|
|
43
|
+
# E.g: lib/my_app_web/controllers/user_controller.ex -> test/my_app_web/controllers/user_controller_test.exs
|
|
44
|
+
#
|
|
45
|
+
# @param changed_file [<InfinityTest::Core::ChangedFile>]
|
|
46
|
+
# @param lib_dir [String] The lib directory (e.g., 'lib/my_app_web')
|
|
47
|
+
#
|
|
48
|
+
def run_test_in_lib(changed_file, lib_dir)
|
|
49
|
+
subdir = File.basename(lib_dir)
|
|
50
|
+
test_file = File.join(test_framework.test_dir, subdir, "#{changed_file.path}_test.exs")
|
|
51
|
+
|
|
52
|
+
if File.exist?(test_file)
|
|
53
|
+
continuous_test_server.rerun_strategy(test_file)
|
|
54
|
+
else
|
|
55
|
+
# Fallback: try finding with hike in test_dir/subdir
|
|
56
|
+
hike.prepend_path(File.join(test_framework.test_dir, subdir))
|
|
57
|
+
file_name = "#{changed_file.path}_test.exs"
|
|
58
|
+
file = hike.find(file_name)
|
|
59
|
+
continuous_test_server.rerun_strategy(file) if file.present?
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# ==== Returns
|
|
64
|
+
# TrueClass: Find a Phoenix project (has lib/*_web directory)
|
|
65
|
+
# FalseClass: Not a Phoenix project
|
|
66
|
+
#
|
|
67
|
+
def self.run?
|
|
68
|
+
File.exist?('mix.exs') && Dir.glob('lib/*_web').any?
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
module InfinityTest
|
|
2
|
+
module Framework
|
|
3
|
+
class PythonPackage < Base
|
|
4
|
+
delegate :test_dir, :test_helper_file, to: :test_framework
|
|
5
|
+
|
|
6
|
+
# Override to use .py extension for Python test files.
|
|
7
|
+
#
|
|
8
|
+
def heuristics!
|
|
9
|
+
hike.append_extension('.py')
|
|
10
|
+
hike.append_path(test_framework.test_dir)
|
|
11
|
+
heuristics
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Add Heuristics to the observer run on pattern changes!
|
|
15
|
+
#
|
|
16
|
+
# ==== Heuristics
|
|
17
|
+
# * Watch src dir (.py files) and run corresponding test
|
|
18
|
+
# * Watch package dirs (.py files) and run corresponding test
|
|
19
|
+
# * Watch test dir (.py files) and run the changed file
|
|
20
|
+
# * Watch conftest.py and run all tests
|
|
21
|
+
#
|
|
22
|
+
def heuristics
|
|
23
|
+
watch_python_dirs
|
|
24
|
+
watch_dir(test_dir, :py) { |file| run_file(file) }
|
|
25
|
+
watch(test_helper_file) { run_all } if File.exist?(test_helper_file.to_s)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Auto-discover and watch Python source directories.
|
|
29
|
+
# Common patterns: src/, package_name/, lib/
|
|
30
|
+
#
|
|
31
|
+
def watch_python_dirs
|
|
32
|
+
python_dirs = detect_python_source_dirs
|
|
33
|
+
|
|
34
|
+
python_dirs.each do |dir|
|
|
35
|
+
next unless File.directory?(dir)
|
|
36
|
+
next unless Dir.glob("#{dir}/**/*.py").any?
|
|
37
|
+
|
|
38
|
+
watch_dir(dir, :py) { |file| run_test(file) }
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Run test based on the changed file.
|
|
43
|
+
# Maps src/mypackage/utils.py -> tests/test_utils.py or tests/mypackage/test_utils.py
|
|
44
|
+
#
|
|
45
|
+
# @param changed_file [<InfinityTest::Core::ChangedFile>]
|
|
46
|
+
#
|
|
47
|
+
def run_test(changed_file)
|
|
48
|
+
# Try test_filename.py pattern first
|
|
49
|
+
test_file = find_test_file(changed_file.path)
|
|
50
|
+
continuous_test_server.rerun_strategy(test_file) if test_file.present?
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# ==== Returns
|
|
54
|
+
# TrueClass: Find a Python package (pyproject.toml, setup.py, or setup.cfg)
|
|
55
|
+
# FalseClass: Not a Python package
|
|
56
|
+
#
|
|
57
|
+
def self.run?
|
|
58
|
+
File.exist?('pyproject.toml') ||
|
|
59
|
+
File.exist?('setup.py') ||
|
|
60
|
+
File.exist?('setup.cfg')
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def detect_python_source_dirs
|
|
66
|
+
dirs = []
|
|
67
|
+
dirs << 'src' if File.directory?('src')
|
|
68
|
+
dirs << 'lib' if File.directory?('lib') && Dir.glob('lib/**/*.py').any?
|
|
69
|
+
|
|
70
|
+
# Detect package directories (directories with __init__.py)
|
|
71
|
+
Dir.glob('*/__init__.py').each do |init_file|
|
|
72
|
+
dir = File.dirname(init_file)
|
|
73
|
+
dirs << dir unless %w[tests test].include?(dir)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
dirs.uniq
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def find_test_file(source_path)
|
|
80
|
+
basename = File.basename(source_path, '.py')
|
|
81
|
+
|
|
82
|
+
# Try various test file patterns
|
|
83
|
+
patterns = [
|
|
84
|
+
"test_#{basename}.py",
|
|
85
|
+
"#{basename}_test.py"
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
patterns.each do |pattern|
|
|
89
|
+
file = hike.find(pattern)
|
|
90
|
+
return file if file.present?
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
nil
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module InfinityTest
|
|
2
|
+
module Framework
|
|
3
|
+
class Rails < Base
|
|
4
|
+
delegate :test_dir, :test_helper_file, to: :test_framework
|
|
5
|
+
|
|
6
|
+
# Add Heuristics to the observer run on pattern changes!
|
|
7
|
+
#
|
|
8
|
+
# ==== Heuristics
|
|
9
|
+
# * Watch all app/* directories and run corresponding tests/specs
|
|
10
|
+
# * Watch lib dir and run corresponding tests
|
|
11
|
+
# * Watch test/spec dir and run the changed file
|
|
12
|
+
# * Watch test/spec helper and run all
|
|
13
|
+
#
|
|
14
|
+
def heuristics
|
|
15
|
+
watch_app_dirs
|
|
16
|
+
watch_dir(:lib) { |file| run_test(file) }
|
|
17
|
+
watch_dir(test_dir) { |file| run_file(file) }
|
|
18
|
+
watch(test_helper_file) { run_all }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.run?
|
|
22
|
+
File.exist?(File.expand_path('./config/environment.rb'))
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
module InfinityTest
|
|
2
|
+
module Framework
|
|
3
|
+
class Rocket < Base
|
|
4
|
+
delegate :test_dir, :test_helper_file, to: :test_framework
|
|
5
|
+
|
|
6
|
+
# Override to use .rs extension for Rust files.
|
|
7
|
+
#
|
|
8
|
+
def heuristics!
|
|
9
|
+
hike.append_extension('.rs')
|
|
10
|
+
hike.append_path(test_framework.test_dir) if File.directory?(test_framework.test_dir.to_s)
|
|
11
|
+
heuristics
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Add Heuristics to the observer run on pattern changes!
|
|
15
|
+
#
|
|
16
|
+
# ==== Heuristics
|
|
17
|
+
# * Watch src dir (.rs files) and run tests matching the module name
|
|
18
|
+
# * Watch tests dir (.rs files) and run the changed integration test
|
|
19
|
+
# * Watch Cargo.toml and run all tests
|
|
20
|
+
# * Watch Rocket.toml if exists and run all tests
|
|
21
|
+
#
|
|
22
|
+
def heuristics
|
|
23
|
+
watch_dir(:src, :rs) { |file| run_module_tests(file) }
|
|
24
|
+
watch_dir(test_dir, :rs) { |file| run_integration_test(file) } if File.directory?(test_dir.to_s)
|
|
25
|
+
watch(test_helper_file) { run_all }
|
|
26
|
+
watch('Rocket.toml') { run_all } if File.exist?('Rocket.toml')
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Run tests matching the module name.
|
|
30
|
+
# E.g: src/routes.rs -> cargo test routes
|
|
31
|
+
#
|
|
32
|
+
# @param changed_file [<InfinityTest::Core::ChangedFile>]
|
|
33
|
+
#
|
|
34
|
+
def run_module_tests(changed_file)
|
|
35
|
+
module_name = File.basename(changed_file.name, '.rs')
|
|
36
|
+
# lib.rs and main.rs changes should run all tests
|
|
37
|
+
if %w[lib main].include?(module_name)
|
|
38
|
+
run_all
|
|
39
|
+
else
|
|
40
|
+
continuous_test_server.rerun_strategy(module_name)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Run a specific integration test file.
|
|
45
|
+
#
|
|
46
|
+
# @param changed_file [<InfinityTest::Core::ChangedFile>]
|
|
47
|
+
#
|
|
48
|
+
def run_integration_test(changed_file)
|
|
49
|
+
test_name = File.basename(changed_file.name, '.rs')
|
|
50
|
+
continuous_test_server.rerun_strategy("--test #{test_name}")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# ==== Returns
|
|
54
|
+
# TrueClass: Find a Rocket project (Cargo.toml with rocket dependency)
|
|
55
|
+
# FalseClass: Not a Rocket project
|
|
56
|
+
#
|
|
57
|
+
def self.run?
|
|
58
|
+
File.exist?('Cargo.toml') && rocket_project?
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.rocket_project?
|
|
62
|
+
return false unless File.exist?('Cargo.toml')
|
|
63
|
+
content = File.read('Cargo.toml')
|
|
64
|
+
content.include?('rocket')
|
|
65
|
+
rescue
|
|
66
|
+
false
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module InfinityTest
|
|
2
|
+
module Framework
|
|
3
|
+
class Rubygems < Base
|
|
4
|
+
delegate :test_dir, :test_helper_file, to: :test_framework
|
|
5
|
+
|
|
6
|
+
# Add Heuristics to the observer run on pattern changes!
|
|
7
|
+
#
|
|
8
|
+
# ==== Heuristics
|
|
9
|
+
# * Add Gemfile and Run bundle install and run all specs.
|
|
10
|
+
# * Observe lib dir and run test.
|
|
11
|
+
# * Observe the test dir and run the same changed file.
|
|
12
|
+
# * Observe the test helper file and run.
|
|
13
|
+
#
|
|
14
|
+
def heuristics
|
|
15
|
+
watch_dir(:lib) { |file| run_test(file) }
|
|
16
|
+
watch_dir(test_dir) { |file| run_file(file) }
|
|
17
|
+
watch(test_helper_file) { run_all }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# ==== Returns
|
|
21
|
+
# TrueClass: Find a gemspec in the user current dir
|
|
22
|
+
# FalseClass: Don't Find a gemspec in the user current dir
|
|
23
|
+
#
|
|
24
|
+
def self.run?
|
|
25
|
+
Dir["*.gemspec"].present?
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
module InfinityTest
|
|
2
|
+
module Framework
|
|
3
|
+
class RustCargo < Base
|
|
4
|
+
delegate :test_dir, :test_helper_file, to: :test_framework
|
|
5
|
+
|
|
6
|
+
# Override to use .rs extension for Rust files.
|
|
7
|
+
#
|
|
8
|
+
def heuristics!
|
|
9
|
+
hike.append_extension('.rs')
|
|
10
|
+
hike.append_path(test_framework.test_dir) if File.directory?(test_framework.test_dir.to_s)
|
|
11
|
+
heuristics
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Add Heuristics to the observer run on pattern changes!
|
|
15
|
+
#
|
|
16
|
+
# ==== Heuristics
|
|
17
|
+
# * Watch src dir (.rs files) and run tests matching the module name
|
|
18
|
+
# * Watch tests dir (.rs files) and run the changed integration test
|
|
19
|
+
# * Watch Cargo.toml and run all tests
|
|
20
|
+
#
|
|
21
|
+
def heuristics
|
|
22
|
+
watch_dir(:src, :rs) { |file| run_module_tests(file) }
|
|
23
|
+
watch_dir(test_dir, :rs) { |file| run_integration_test(file) } if File.directory?(test_dir.to_s)
|
|
24
|
+
watch(test_helper_file) { run_all }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Run tests matching the module name.
|
|
28
|
+
# E.g: src/user.rs -> cargo test user
|
|
29
|
+
#
|
|
30
|
+
# @param changed_file [<InfinityTest::Core::ChangedFile>]
|
|
31
|
+
#
|
|
32
|
+
def run_module_tests(changed_file)
|
|
33
|
+
module_name = File.basename(changed_file.name, '.rs')
|
|
34
|
+
# lib.rs and main.rs changes should run all tests
|
|
35
|
+
if %w[lib main].include?(module_name)
|
|
36
|
+
run_all
|
|
37
|
+
else
|
|
38
|
+
continuous_test_server.rerun_strategy(module_name)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Run a specific integration test file.
|
|
43
|
+
# For tests in tests/, run cargo test --test <name>
|
|
44
|
+
#
|
|
45
|
+
# @param changed_file [<InfinityTest::Core::ChangedFile>]
|
|
46
|
+
#
|
|
47
|
+
def run_integration_test(changed_file)
|
|
48
|
+
test_name = File.basename(changed_file.name, '.rs')
|
|
49
|
+
continuous_test_server.rerun_strategy("--test #{test_name}")
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# ==== Returns
|
|
53
|
+
# TrueClass: Find a Rust project (Cargo.toml exists)
|
|
54
|
+
# FalseClass: Not a Rust project
|
|
55
|
+
#
|
|
56
|
+
def self.run?
|
|
57
|
+
File.exist?('Cargo.toml') && !rocket_project?
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def self.rocket_project?
|
|
61
|
+
return false unless File.exist?('Cargo.toml')
|
|
62
|
+
content = File.read('Cargo.toml')
|
|
63
|
+
content.include?('rocket')
|
|
64
|
+
rescue
|
|
65
|
+
false
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module InfinityTest
|
|
2
|
+
module Framework
|
|
3
|
+
module SharedExample
|
|
4
|
+
# Shared Examples to use in the RSpec specs when you want create your own observer.
|
|
5
|
+
#
|
|
6
|
+
# ==== Examples
|
|
7
|
+
#
|
|
8
|
+
# RSpec.configure do |config|
|
|
9
|
+
# config.include InfinityTest::Observer::SharedExample
|
|
10
|
+
# end
|
|
11
|
+
#
|
|
12
|
+
# describe BarObserver do
|
|
13
|
+
# it_should_behave_like 'an infinity test observer'
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
shared_examples_for 'an infinity test framework' do
|
|
17
|
+
it 'responds to #heuristics' do
|
|
18
|
+
expect(subject).to respond_to(:heuristics)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'responds to #heuristics!' do
|
|
22
|
+
expect(subject).to respond_to(:heuristics!)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'responds to .run?' do
|
|
26
|
+
expect(subject.class).to respond_to(:run?)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'responds to #base' do
|
|
30
|
+
expect(subject).to respond_to(:base)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'responds to #test_framework' do
|
|
34
|
+
expect(subject).to respond_to(:test_framework)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'responds to #strategy' do
|
|
38
|
+
expect(subject).to respond_to(:strategy)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'responds to #observer' do
|
|
42
|
+
expect(subject).to respond_to(:observer)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module InfinityTest
|
|
2
|
+
module Observer
|
|
3
|
+
class Base
|
|
4
|
+
attr_accessor :continuous_test_server
|
|
5
|
+
|
|
6
|
+
def initialize(continuous_test_server)
|
|
7
|
+
@continuous_test_server = continuous_test_server
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def watch(pattern_or_file, &block)
|
|
11
|
+
raise NotImplementedError, "not implemented in #{self}"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def watch_dir(dir_name, extension, &block)
|
|
15
|
+
raise NotImplementedError, "not implemented in #{self}"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def start!
|
|
19
|
+
signal
|
|
20
|
+
start
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def start
|
|
24
|
+
raise NotImplementedError, "not implemented in #{self}"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def signal
|
|
28
|
+
Signal.trap('INT') do
|
|
29
|
+
if @interrupt_at && (Time.now - @interrupt_at) < 2
|
|
30
|
+
puts " To Infinity and Beyond!"
|
|
31
|
+
exit
|
|
32
|
+
else
|
|
33
|
+
puts " Are you sure? :S ... Interrupt a second time to quit!"
|
|
34
|
+
@interrupt_at = Time.now
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
require 'filewatcher'
|
|
2
|
+
|
|
3
|
+
module InfinityTest
|
|
4
|
+
module Observer
|
|
5
|
+
class Filewatcher < Base
|
|
6
|
+
attr_reader :observer, :watch_paths, :patterns
|
|
7
|
+
|
|
8
|
+
def initialize(continuous_test_server)
|
|
9
|
+
super
|
|
10
|
+
@watch_paths = []
|
|
11
|
+
@patterns = {}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Watch a file or pattern for changes.
|
|
15
|
+
#
|
|
16
|
+
# ==== Examples
|
|
17
|
+
#
|
|
18
|
+
# watch('lib/(.*)\.rb') { |file| puts [file.name, file.path, file.match_data] }
|
|
19
|
+
# watch('test/test_helper.rb') { run_all() }
|
|
20
|
+
#
|
|
21
|
+
def watch(pattern_or_file, &block)
|
|
22
|
+
pattern = Regexp.new(pattern_or_file.to_s)
|
|
23
|
+
@patterns[pattern] = block
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Watch a directory for changes.
|
|
27
|
+
#
|
|
28
|
+
# ==== Examples
|
|
29
|
+
#
|
|
30
|
+
# watch_dir(:lib) { |file| run_test(file) }
|
|
31
|
+
# watch_dir(:test) { |file| run_file(file) }
|
|
32
|
+
#
|
|
33
|
+
# watch_dir(:test, :py) { |file| puts [file.name, file.path, file.match_data] }
|
|
34
|
+
# watch_dir(:test, :js) { |file| puts [file.name, file.path, file.match_data] }
|
|
35
|
+
#
|
|
36
|
+
def watch_dir(dir_name, extension = :rb, &block)
|
|
37
|
+
watch("^#{dir_name}/*/(.*).#{extension}", &block)
|
|
38
|
+
path = "#{dir_name}/**/*.#{extension}"
|
|
39
|
+
@watch_paths << path unless @watch_paths.include?(path)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Start the continuous test server.
|
|
43
|
+
#
|
|
44
|
+
def start
|
|
45
|
+
paths = @watch_paths.empty? ? ['**/*.rb'] : @watch_paths
|
|
46
|
+
|
|
47
|
+
@observer = ::Filewatcher.new(paths)
|
|
48
|
+
|
|
49
|
+
@observer.watch do |changes|
|
|
50
|
+
changes.each do |file_path, _event|
|
|
51
|
+
relative_path = file_path.sub("#{Dir.pwd}/", '')
|
|
52
|
+
handle_file_change(relative_path)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
rescue Interrupt
|
|
56
|
+
@observer.stop if @observer
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def handle_file_change(file_path)
|
|
62
|
+
@patterns.each do |pattern, block|
|
|
63
|
+
if match_data = pattern.match(file_path)
|
|
64
|
+
changed_file = InfinityTest::Core::ChangedFile.new(match_data)
|
|
65
|
+
block.call(changed_file)
|
|
66
|
+
break
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
require 'listen'
|
|
2
|
+
|
|
3
|
+
module InfinityTest
|
|
4
|
+
module Observer
|
|
5
|
+
class Listen < Base
|
|
6
|
+
attr_reader :observer, :directories, :patterns
|
|
7
|
+
|
|
8
|
+
def initialize(continuous_test_server)
|
|
9
|
+
super
|
|
10
|
+
@directories = []
|
|
11
|
+
@patterns = {}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Watch a file or pattern for changes.
|
|
15
|
+
#
|
|
16
|
+
# ==== Examples
|
|
17
|
+
#
|
|
18
|
+
# watch('lib/(.*)\.rb') { |file| puts [file.name, file.path, file.match_data] }
|
|
19
|
+
# watch('test/test_helper.rb') { run_all() }
|
|
20
|
+
#
|
|
21
|
+
def watch(pattern_or_file, &block)
|
|
22
|
+
pattern = Regexp.new(pattern_or_file.to_s)
|
|
23
|
+
@patterns[pattern] = block
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Watch a directory for changes.
|
|
27
|
+
#
|
|
28
|
+
# ==== Examples
|
|
29
|
+
#
|
|
30
|
+
# watch_dir(:lib) { |file| run_test(file) }
|
|
31
|
+
# watch_dir(:test) { |file| run_file(file) }
|
|
32
|
+
#
|
|
33
|
+
# watch_dir(:test, :py) { |file| puts [file.name, file.path, file.match_data] }
|
|
34
|
+
# watch_dir(:test, :js) { |file| puts [file.name, file.path, file.match_data] }
|
|
35
|
+
#
|
|
36
|
+
def watch_dir(dir_name, extension = :rb, &block)
|
|
37
|
+
watch("^#{dir_name}/*/(.*).#{extension}", &block)
|
|
38
|
+
@directories << dir_name.to_s unless @directories.include?(dir_name.to_s)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Start the continuous test server.
|
|
42
|
+
#
|
|
43
|
+
def start
|
|
44
|
+
dirs = @directories.empty? ? ['.'] : @directories
|
|
45
|
+
dirs = dirs.select { |d| File.directory?(d) }
|
|
46
|
+
dirs = ['.'] if dirs.empty?
|
|
47
|
+
|
|
48
|
+
@observer = ::Listen.to(*dirs) do |modified, added, _removed|
|
|
49
|
+
(modified + added).each do |file|
|
|
50
|
+
relative_path = file.sub("#{Dir.pwd}/", '')
|
|
51
|
+
handle_file_change(relative_path)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
@observer.start
|
|
56
|
+
sleep
|
|
57
|
+
rescue Interrupt
|
|
58
|
+
@observer.stop if @observer
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
def handle_file_change(file_path)
|
|
64
|
+
@patterns.each do |pattern, block|
|
|
65
|
+
if match_data = pattern.match(file_path)
|
|
66
|
+
changed_file = InfinityTest::Core::ChangedFile.new(match_data)
|
|
67
|
+
block.call(changed_file)
|
|
68
|
+
break
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module InfinityTest
|
|
2
|
+
module Observer
|
|
3
|
+
module SharedExample
|
|
4
|
+
# Shared Examples to use in the RSpec specs when you want create your own observer.
|
|
5
|
+
#
|
|
6
|
+
# ==== Examples
|
|
7
|
+
#
|
|
8
|
+
# RSpec.configure do |config|
|
|
9
|
+
# config.include InfinityTest::Observer::SharedExample
|
|
10
|
+
# end
|
|
11
|
+
#
|
|
12
|
+
# describe BarObserver do
|
|
13
|
+
# it_should_behave_like 'an infinity test observer'
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
shared_examples_for 'an infinity test observer' do
|
|
17
|
+
it 'responds to #observer' do
|
|
18
|
+
expect(subject).to respond_to(:observer)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'responds to #watch_dir' do
|
|
22
|
+
expect(subject).to respond_to(:watch_dir)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'responds to #watch' do
|
|
26
|
+
expect(subject).to respond_to(:watch)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'responds to #start' do
|
|
30
|
+
expect(subject).to respond_to(:start)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module InfinityTest
|
|
2
|
+
module OldDSL
|
|
3
|
+
class Configuration
|
|
4
|
+
# Pass the responsability to InfinityTest::Base class.
|
|
5
|
+
#
|
|
6
|
+
# <b>Don't need #super or #respond_to here.</b>
|
|
7
|
+
# <b>This class will be removed in infinity_test 2.0.1</b>
|
|
8
|
+
#
|
|
9
|
+
def method_missing(method_name, *arguments, &block)
|
|
10
|
+
InfinityTest::Base.send(method_name, *arguments, &block)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
module InfinityTestMethod
|
|
15
|
+
# <b>DEPRECATED:</b> Please use <tt>InfinityTest::Base.setup</tt> instead.
|
|
16
|
+
#
|
|
17
|
+
def infinity_test(&block)
|
|
18
|
+
message = "infinity_test method is deprecated. Use InfinityTest.setup { |config| ... } instead."
|
|
19
|
+
ActiveSupport::Deprecation.warn(message)
|
|
20
|
+
::InfinityTest::OldDSL::Configuration.new.instance_eval(&block)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
include InfinityTest::OldDSL::InfinityTestMethod
|