infinity_test 1.0.3 → 2.0.0.rc1
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.markdown +82 -0
- data/{.infinity_test → INFINITY_TEST} +18 -15
- data/LICENSE.txt +2 -2
- data/README.md +627 -0
- data/Rakefile +1 -65
- data/TODO.markdown +24 -19
- 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 +62 -0
- data/lib/infinity_test/core/configuration_merge.rb +37 -0
- data/lib/infinity_test/core/continuous_test_server.rb +106 -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 +57 -0
- data/lib/infinity_test/framework/padrino.rb +33 -0
- data/lib/infinity_test/framework/rails.rb +35 -0
- data/lib/infinity_test/framework/rubygems.rb +29 -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 +34 -0
- data/lib/infinity_test/strategy/rbenv.rb +32 -0
- data/lib/infinity_test/strategy/ruby_default.rb +20 -0
- data/lib/infinity_test/strategy/rvm.rb +50 -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/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 +53 -35
- data/spec/infinity_test/core/auto_discover_spec.rb +149 -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/padrino_spec.rb +36 -0
- data/spec/infinity_test/framework/rails_spec.rb +36 -0
- data/spec/infinity_test/framework/rubygems_spec.rb +34 -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/rbenv_spec.rb +53 -0
- data/spec/infinity_test/strategy/ruby_default_spec.rb +32 -0
- data/spec/infinity_test/strategy/rvm_spec.rb +69 -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 +272 -176
- 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,48 @@
|
|
|
1
|
+
module InfinityTest
|
|
2
|
+
module Core
|
|
3
|
+
class LoadConfiguration
|
|
4
|
+
attr_accessor :global_file, :project_file
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
@global_file = File.expand_path('~/INFINITY_TEST')
|
|
8
|
+
@project_file = './INFINITY_TEST'
|
|
9
|
+
@old_configuration = InfinityTest::OldDSL::Configuration
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Load the Configuration file
|
|
13
|
+
#
|
|
14
|
+
# Command line options can be persisted in an INFINITY_TEST file in a project.
|
|
15
|
+
# You can also store an INFINITY_TEST file in your home directory (~/INFINITY_TEST)
|
|
16
|
+
#
|
|
17
|
+
# Precedence is:
|
|
18
|
+
# command line
|
|
19
|
+
# ./INFINITY_TEST
|
|
20
|
+
# ~/INFINITY_TEST
|
|
21
|
+
#
|
|
22
|
+
# Example:
|
|
23
|
+
#
|
|
24
|
+
# ~/INFINITY_TEST -> infinity_test { notifications :osascript }
|
|
25
|
+
#
|
|
26
|
+
# ./INFINITY_TEST -> infinity_test { notifications :terminal_notifier } # High Priority
|
|
27
|
+
#
|
|
28
|
+
# After the load the Notifications Framework will be Terminal Notifier
|
|
29
|
+
#
|
|
30
|
+
def load!
|
|
31
|
+
load_global_file!
|
|
32
|
+
load_project_file!
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def load_global_file!
|
|
36
|
+
load_file(@global_file)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def load_project_file!
|
|
40
|
+
load_file(@project_file)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def load_file(file)
|
|
44
|
+
load(file) if File.exist?(file)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module InfinityTest
|
|
2
|
+
module Core
|
|
3
|
+
class Notifier
|
|
4
|
+
include ::Notifiers
|
|
5
|
+
|
|
6
|
+
attr_reader :test_framework, :library
|
|
7
|
+
|
|
8
|
+
IMAGES = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'images'))
|
|
9
|
+
|
|
10
|
+
delegate :test_message, to: :test_framework
|
|
11
|
+
|
|
12
|
+
def initialize(options)
|
|
13
|
+
@test_framework = options.fetch(:test_framework)
|
|
14
|
+
@library = options.fetch(:library)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def notify
|
|
18
|
+
send(library).title(RUBY_VERSION).message(test_message).image(image).notify
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def image
|
|
22
|
+
return success_image if test_framework.success?
|
|
23
|
+
|
|
24
|
+
if test_framework.failure?
|
|
25
|
+
failure_image
|
|
26
|
+
else
|
|
27
|
+
pending_image
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def success_image
|
|
32
|
+
Core::Base.success_image || find_image(:success)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def failure_image
|
|
36
|
+
Core::Base.failure_image || find_image(:failure)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def pending_image
|
|
40
|
+
Core::Base.pending_image || find_image(:pending)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def find_image(image_type)
|
|
44
|
+
Dir.glob(File.join(images_dir, "#{image_type.to_s}*")).first
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def images_dir
|
|
48
|
+
mode = Core::Base.mode
|
|
49
|
+
|
|
50
|
+
case mode
|
|
51
|
+
when Symbol
|
|
52
|
+
File.join(IMAGES, mode.to_s)
|
|
53
|
+
when String
|
|
54
|
+
File.expand_path(File.join(mode))
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
module InfinityTest
|
|
2
|
+
module Core
|
|
3
|
+
class Options
|
|
4
|
+
attr_accessor :arguments, :options_parser, :strategy, :bundler, :verbose
|
|
5
|
+
attr_accessor :rubies, :specific_options, :test_framework, :framework, :infinity_and_beyond
|
|
6
|
+
attr_accessor :notifications, :mode, :just_watch, :focus
|
|
7
|
+
|
|
8
|
+
def initialize(*arguments)
|
|
9
|
+
@arguments = arguments.flatten.clone
|
|
10
|
+
@options_parser = new_options_parser
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def new_options_parser
|
|
14
|
+
OptionParser.new do |option|
|
|
15
|
+
%w(
|
|
16
|
+
ruby_strategy
|
|
17
|
+
ruby_versions
|
|
18
|
+
options_to_added_in_the_command
|
|
19
|
+
test_framework_to_be_run
|
|
20
|
+
app_framework
|
|
21
|
+
notifications_library
|
|
22
|
+
image_mode
|
|
23
|
+
infinity_and_beyond_option
|
|
24
|
+
just_watch_option
|
|
25
|
+
focus_option
|
|
26
|
+
verbose_mode
|
|
27
|
+
skip_bundler
|
|
28
|
+
).each do |option_to_parse|
|
|
29
|
+
send(option_to_parse, option)
|
|
30
|
+
end
|
|
31
|
+
banner(option)
|
|
32
|
+
help(option)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def parse!
|
|
37
|
+
@options_parser.parse!(@arguments)
|
|
38
|
+
|
|
39
|
+
self
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def ruby_strategy(option)
|
|
43
|
+
option.on('--ruby strategy', 'Ruby Manager. Ex.: auto_discover, rvm, rbenv, ruby_default') do |strategy|
|
|
44
|
+
@strategy = strategy.to_sym
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def ruby_versions(option)
|
|
49
|
+
option.on('--rubies=rubies', 'Specify Ruby version(s) to test against') do |versions|
|
|
50
|
+
@rubies = versions.split(',')
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def options_to_added_in_the_command(option)
|
|
55
|
+
option.on('--options=options', 'Pass the options to be added. Ex. -Ilib-Itest-Iapp') do |options|
|
|
56
|
+
@specific_options = options.split('-').join(' -').strip
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def test_framework_to_be_run(option)
|
|
61
|
+
option.on('--test library', 'Test Framework to be run. Ex.: auto_discover, rspec, test_unit.') do |library|
|
|
62
|
+
@test_framework = library.to_sym
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def app_framework(option)
|
|
67
|
+
option.on('--framework library', 'Application Framework to be run and added the patterns to search changed files. Ex.: auto_discover, rails, rubygems, padrino.') do |library|
|
|
68
|
+
@framework = library.to_sym
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def notifications_library(option)
|
|
73
|
+
option.on('--notifications library', 'Notification library to use. Ex.: auto_discover, osascript, terminal_notifier, notify_send, dunstify.') do |library|
|
|
74
|
+
@notifications = library.to_sym
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def image_mode(option)
|
|
79
|
+
option.on('--mode theme', 'Image theme for notifications. Ex.: simpson, faces, fuuu, hands, mario_bros, rails, rubies, street_fighter, toy_story.') do |theme|
|
|
80
|
+
@mode = theme.to_sym
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def infinity_and_beyond_option(option)
|
|
85
|
+
option.on('-n', '--no-infinity-and-beyond', 'Run tests and exit. Useful in a Continuous Integration environment.') do
|
|
86
|
+
@infinity_and_beyond = false
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def just_watch_option(option)
|
|
91
|
+
option.on('-j', '--just-watch', 'Skip initial test run and only watch for file changes. Useful for large applications.') do
|
|
92
|
+
@just_watch = true
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def focus_option(option)
|
|
97
|
+
option.on('-f', '--focus [FILE]', 'Focus on specific tests. Use "failures" for failed tests, or provide a file path.') do |file|
|
|
98
|
+
@focus = file == 'failures' ? :failures : file
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def verbose_mode(option)
|
|
103
|
+
option.on('--no-verbose', "Don't print commands before executing them") do
|
|
104
|
+
@verbose = false
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def skip_bundler(option)
|
|
109
|
+
option.on('--no-bundler', "Bypass Infinity Test's Bundler support") do
|
|
110
|
+
@bundler = false
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def banner(option)
|
|
115
|
+
option.banner = [ "Usage: infinity_test [options]", "Run tests"].join("\n")
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def help(option)
|
|
119
|
+
option.on_tail("--help", "You're looking at it.") do
|
|
120
|
+
print option.help
|
|
121
|
+
exit
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def verbose?
|
|
126
|
+
@verbose
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def bundler?
|
|
130
|
+
@bundler
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module InfinityTest
|
|
2
|
+
module Core
|
|
3
|
+
class Runner
|
|
4
|
+
attr_accessor :options
|
|
5
|
+
|
|
6
|
+
def initialize(*arguments)
|
|
7
|
+
@options = Options.new(arguments).parse!
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def start
|
|
11
|
+
Core::LoadConfiguration.new.load!
|
|
12
|
+
Core::Base.merge!(options)
|
|
13
|
+
Core::AutoDiscover.new(Core::Base).discover_libraries
|
|
14
|
+
Core::Base.start_continuous_test_server
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module InfinityTest
|
|
2
|
+
module Framework
|
|
3
|
+
class Base
|
|
4
|
+
attr_reader :continuous_test_server, :hike
|
|
5
|
+
delegate :observer, :test_framework, :extension, to: :continuous_test_server
|
|
6
|
+
delegate :watch, :watch_dir, to: :observer
|
|
7
|
+
|
|
8
|
+
def initialize(continuous_test_server)
|
|
9
|
+
@continuous_test_server = continuous_test_server
|
|
10
|
+
@hike = Hike::Trail.new(Dir.pwd)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def heuristics!
|
|
14
|
+
hike.append_extension(extension)
|
|
15
|
+
hike.append_path(test_framework.test_dir)
|
|
16
|
+
heuristics
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# This method is called for the InfinityTest before starting the observer
|
|
20
|
+
#
|
|
21
|
+
def heuristics
|
|
22
|
+
raise NotImplementedError, "not implemented in #{self}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Put all the requires to autodiscover use your framework instead of others.
|
|
26
|
+
#
|
|
27
|
+
def self.run?
|
|
28
|
+
raise NotImplementedError, "not implemented in #{self}"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Run all the strategy again.
|
|
32
|
+
#
|
|
33
|
+
def run_all
|
|
34
|
+
continuous_test_server.run_strategy
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Run the same changed file.
|
|
38
|
+
# E.g: the user saves the test file, runs the test file.
|
|
39
|
+
#
|
|
40
|
+
# @param changed_file [<InfinityTest::Core::ChangedFile>]
|
|
41
|
+
#
|
|
42
|
+
def run_file(changed_file)
|
|
43
|
+
continuous_test_server.rerun_strategy(changed_file.name)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Run test based on the changed file.
|
|
47
|
+
#
|
|
48
|
+
# @param changed_file [<InfinityTest::Core::ChangedFile>]
|
|
49
|
+
#
|
|
50
|
+
def run_test(changed_file)
|
|
51
|
+
file_name = "#{changed_file.path}_#{test_framework.test_dir}.#{extension}"
|
|
52
|
+
file = hike.find(file_name)
|
|
53
|
+
continuous_test_server.rerun_strategy(file) if file.present?
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module InfinityTest
|
|
2
|
+
module Framework
|
|
3
|
+
class Padrino < 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 app folder (models, controllers, helpers, mailers) 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_dir('app/models') { |file| run_test(file) }
|
|
16
|
+
watch_dir('app/controllers') { |file| run_test(file) }
|
|
17
|
+
watch_dir('app/helpers') { |file| run_test(file) }
|
|
18
|
+
watch_dir('app/mailers') { |file| run_test(file) }
|
|
19
|
+
watch_dir(:lib) { |file| run_test(file) }
|
|
20
|
+
watch_dir(test_dir) { |file| run_file(file) }
|
|
21
|
+
watch(test_helper_file) { run_all }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# ==== Returns
|
|
25
|
+
# TrueClass: Find the config/apps.rb in the user current dir
|
|
26
|
+
# FalseClass: Don't Find the config/apps.rb in the user current dir
|
|
27
|
+
#
|
|
28
|
+
def self.run?
|
|
29
|
+
File.exist?(File.expand_path('./config/apps.rb'))
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
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 app/models and run corresponding tests/specs
|
|
10
|
+
# * Watch app/controllers and run corresponding tests/specs
|
|
11
|
+
# * Watch app/helpers and run corresponding tests/specs
|
|
12
|
+
# * Watch app/mailers and run corresponding tests/specs
|
|
13
|
+
# * Watch app/jobs and run corresponding tests/specs
|
|
14
|
+
# * Watch lib dir and run corresponding tests
|
|
15
|
+
# * Watch test/spec dir and run the changed file
|
|
16
|
+
# * Watch test/spec helper and run all
|
|
17
|
+
# * Watch config/routes.rb and run routing specs
|
|
18
|
+
#
|
|
19
|
+
def heuristics
|
|
20
|
+
watch_dir('app/models') { |file| run_test(file) }
|
|
21
|
+
watch_dir('app/controllers') { |file| run_test(file) }
|
|
22
|
+
watch_dir('app/helpers') { |file| run_test(file) }
|
|
23
|
+
watch_dir('app/mailers') { |file| run_test(file) }
|
|
24
|
+
watch_dir('app/jobs') { |file| run_test(file) }
|
|
25
|
+
watch_dir(:lib) { |file| run_test(file) }
|
|
26
|
+
watch_dir(test_dir) { |file| run_file(file) }
|
|
27
|
+
watch(test_helper_file) { run_all }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.run?
|
|
31
|
+
File.exist?(File.expand_path('./config/environment.rb'))
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
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,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
|