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.
Files changed (148) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yml +31 -0
  3. data/.gitignore +3 -0
  4. data/.rspec +2 -2
  5. data/AI_INTEGRATION_IDEAS.md +203 -0
  6. data/Gemfile +3 -15
  7. data/History.markdown +82 -0
  8. data/{.infinity_test → INFINITY_TEST} +18 -15
  9. data/LICENSE.txt +2 -2
  10. data/README.md +627 -0
  11. data/Rakefile +1 -65
  12. data/TODO.markdown +24 -19
  13. data/bin/infinity_test +1 -4
  14. data/images/fuuu/pending.png +0 -0
  15. data/images/fuuu/success.png +0 -0
  16. data/infinity_test.gemspec +41 -189
  17. data/lib/infinity_test/core/auto_discover.rb +67 -0
  18. data/lib/infinity_test/core/base.rb +369 -0
  19. data/lib/infinity_test/core/callback.rb +59 -0
  20. data/lib/infinity_test/core/changed_file.rb +13 -0
  21. data/lib/infinity_test/core/command_builder.rb +48 -0
  22. data/lib/infinity_test/core/command_runner.rb +62 -0
  23. data/lib/infinity_test/core/configuration_merge.rb +37 -0
  24. data/lib/infinity_test/core/continuous_test_server.rb +106 -0
  25. data/lib/infinity_test/core/load_configuration.rb +48 -0
  26. data/lib/infinity_test/core/notifier.rb +59 -0
  27. data/lib/infinity_test/core/options.rb +134 -0
  28. data/lib/infinity_test/core/runner.rb +18 -0
  29. data/lib/infinity_test/core/version.rb +5 -0
  30. data/lib/infinity_test/framework/base.rb +57 -0
  31. data/lib/infinity_test/framework/padrino.rb +33 -0
  32. data/lib/infinity_test/framework/rails.rb +35 -0
  33. data/lib/infinity_test/framework/rubygems.rb +29 -0
  34. data/lib/infinity_test/framework/shared_example.rb +47 -0
  35. data/lib/infinity_test/observer/base.rb +40 -0
  36. data/lib/infinity_test/observer/filewatcher.rb +72 -0
  37. data/lib/infinity_test/observer/listen.rb +74 -0
  38. data/lib/infinity_test/observer/shared_example.rb +35 -0
  39. data/lib/infinity_test/old_dsl/configuration.rb +26 -0
  40. data/lib/infinity_test/strategy/base.rb +34 -0
  41. data/lib/infinity_test/strategy/rbenv.rb +32 -0
  42. data/lib/infinity_test/strategy/ruby_default.rb +20 -0
  43. data/lib/infinity_test/strategy/rvm.rb +50 -0
  44. data/lib/infinity_test/strategy/shared_example.rb +32 -0
  45. data/lib/infinity_test/test_framework/base.rb +64 -0
  46. data/lib/infinity_test/test_framework/rspec.rb +48 -0
  47. data/lib/infinity_test/test_framework/shared_example.rb +56 -0
  48. data/lib/infinity_test/test_framework/test_unit.rb +57 -0
  49. data/lib/infinity_test.rb +53 -35
  50. data/spec/infinity_test/core/auto_discover_spec.rb +149 -0
  51. data/spec/infinity_test/core/base_spec.rb +240 -0
  52. data/spec/infinity_test/core/callback_spec.rb +89 -0
  53. data/spec/infinity_test/core/changed_file_spec.rb +26 -0
  54. data/spec/infinity_test/core/command_builder_spec.rb +38 -0
  55. data/spec/infinity_test/core/configuration_merge_spec.rb +124 -0
  56. data/spec/infinity_test/core/continuous_test_server_spec.rb +116 -0
  57. data/spec/infinity_test/core/load_configuration_spec.rb +43 -0
  58. data/spec/infinity_test/core/notifier_spec.rb +151 -0
  59. data/spec/infinity_test/core/options_spec.rb +168 -0
  60. data/spec/infinity_test/core/runner_spec.rb +17 -0
  61. data/spec/infinity_test/framework/base_spec.rb +55 -0
  62. data/spec/infinity_test/framework/padrino_spec.rb +36 -0
  63. data/spec/infinity_test/framework/rails_spec.rb +36 -0
  64. data/spec/infinity_test/framework/rubygems_spec.rb +34 -0
  65. data/spec/infinity_test/observer/base_spec.rb +78 -0
  66. data/spec/infinity_test/observer/filewatcher_spec.rb +51 -0
  67. data/spec/infinity_test/observer/listen_spec.rb +50 -0
  68. data/spec/infinity_test/{builder_spec.rb → strategy/base_spec.rb} +1 -2
  69. data/spec/infinity_test/strategy/rbenv_spec.rb +53 -0
  70. data/spec/infinity_test/strategy/ruby_default_spec.rb +32 -0
  71. data/spec/infinity_test/strategy/rvm_spec.rb +69 -0
  72. data/spec/infinity_test/test_framework/rspec_spec.rb +119 -0
  73. data/spec/infinity_test/test_framework/test_unit_spec.rb +193 -0
  74. data/spec/spec_helper.rb +34 -119
  75. metadata +272 -176
  76. data/.rvmrc +0 -1
  77. data/Gemfile.lock +0 -62
  78. data/Readme.markdown +0 -147
  79. data/Tasks +0 -4
  80. data/VERSION.yml +0 -5
  81. data/buzz_images/buzz_lightyear.jpg +0 -0
  82. data/buzz_images/buzz_lightyear_continencia.gif +0 -0
  83. data/buzz_images/to_infinity_and_beyond.png +0 -0
  84. data/features/heuristics.feature +0 -23
  85. data/features/support/env.rb +0 -2
  86. data/images/fuuu/sucess.png +0 -0
  87. data/lib/infinity_test/application.rb +0 -362
  88. data/lib/infinity_test/application_library/rails.rb +0 -94
  89. data/lib/infinity_test/application_library/rubygems.rb +0 -43
  90. data/lib/infinity_test/binary_path.rb +0 -43
  91. data/lib/infinity_test/builder.rb +0 -66
  92. data/lib/infinity_test/command.rb +0 -58
  93. data/lib/infinity_test/configuration.rb +0 -277
  94. data/lib/infinity_test/continuous_testing.rb +0 -40
  95. data/lib/infinity_test/dependencies.rb +0 -80
  96. data/lib/infinity_test/environment.rb +0 -15
  97. data/lib/infinity_test/heuristics.rb +0 -36
  98. data/lib/infinity_test/heuristics_helper.rb +0 -9
  99. data/lib/infinity_test/options.rb +0 -96
  100. data/lib/infinity_test/runner.rb +0 -38
  101. data/lib/infinity_test/test_framework.rb +0 -110
  102. data/lib/infinity_test/test_library/bacon.rb +0 -55
  103. data/lib/infinity_test/test_library/cucumber.rb +0 -22
  104. data/lib/infinity_test/test_library/rspec.rb +0 -60
  105. data/lib/infinity_test/test_library/test_unit.rb +0 -52
  106. data/lib/infinity_test/test_unit_loader.rb +0 -5
  107. data/spec/factories/buzz/lib/buzz.rb +0 -0
  108. data/spec/factories/buzz/spec/buzz_spec.rb +0 -0
  109. data/spec/factories/company/Gemfile +0 -0
  110. data/spec/factories/company/lib/company.rb +0 -0
  111. data/spec/factories/company/test/company_test.rb +0 -0
  112. data/spec/factories/images/failure.png +0 -0
  113. data/spec/factories/images/pending.png +0 -0
  114. data/spec/factories/images/sucess.png +0 -0
  115. data/spec/factories/infinity_test +0 -5
  116. data/spec/factories/infinity_test_example +0 -7
  117. data/spec/factories/slinky/spec/slinky/slinky_spec.rb +0 -0
  118. data/spec/factories/travel/lib/travel.rb +0 -0
  119. data/spec/factories/travel/test/partner_test.rb +0 -0
  120. data/spec/factories/travel/test/travel_test.rb +0 -0
  121. data/spec/factories/wood/lib/wood.rb +0 -0
  122. data/spec/factories/wood/spec/wood_spec.rb +0 -0
  123. data/spec/infinity_test/application_library/rails_spec.rb +0 -140
  124. data/spec/infinity_test/application_library/rubygems_spec.rb +0 -52
  125. data/spec/infinity_test/application_spec.rb +0 -434
  126. data/spec/infinity_test/binary_path_spec.rb +0 -72
  127. data/spec/infinity_test/command_spec.rb +0 -53
  128. data/spec/infinity_test/configuration_spec.rb +0 -382
  129. data/spec/infinity_test/continuous_testing_spec.rb +0 -25
  130. data/spec/infinity_test/environment_spec.rb +0 -23
  131. data/spec/infinity_test/heuristics_helper_spec.rb +0 -15
  132. data/spec/infinity_test/heuristics_spec.rb +0 -127
  133. data/spec/infinity_test/options_spec.rb +0 -111
  134. data/spec/infinity_test/runner_spec.rb +0 -42
  135. data/spec/infinity_test/test_framework_spec.rb +0 -127
  136. data/spec/infinity_test/test_library/bacon_spec.rb +0 -150
  137. data/spec/infinity_test/test_library/cucumber_spec.rb +0 -8
  138. data/spec/infinity_test/test_library/rspec_spec.rb +0 -189
  139. data/spec/infinity_test/test_library/test_unit_spec.rb +0 -184
  140. data/spec/infinity_test_spec.rb +0 -40
  141. /data/images/faces/{sucess.png → success.png} +0 -0
  142. /data/images/hands/{sucess.png → success.png} +0 -0
  143. /data/images/mario_bros/{sucess.jpg → success.jpg} +0 -0
  144. /data/images/rails/{sucess.png → success.png} +0 -0
  145. /data/images/rubies/{sucess.png → success.png} +0 -0
  146. /data/images/simpson/{sucess.jpg → success.jpg} +0 -0
  147. /data/images/street_fighter/{sucess.jpg → success.jpg} +0 -0
  148. /data/images/toy_story/{sucess.png → success.png} +0 -0
@@ -0,0 +1,369 @@
1
+ module InfinityTest
2
+ module Core
3
+ class Base
4
+ # Specify the Ruby Version Manager to run
5
+ cattr_accessor :strategy
6
+ # ==== Options
7
+ # * :rvm
8
+ # * :rbenv
9
+ # * :ruby_normal (Use when don't pass any rubies to run)
10
+ # * :auto_discover(defaults)
11
+ self.strategy = :auto_discover
12
+
13
+ # Specify Ruby version(s) to test against
14
+ #
15
+ # ==== Examples
16
+ # rubies = %w(ree jruby)
17
+ #
18
+ cattr_accessor :rubies
19
+ self.rubies = []
20
+
21
+ # Options to include in the command.
22
+ #
23
+ cattr_accessor :specific_options
24
+ self.specific_options = ''
25
+
26
+ # Test Framework to use RSpec, Test::Unit or AutoDiscover(defaults)
27
+ # ==== Options
28
+ # * :rspec
29
+ # * :test_unit (Test unit here apply to this two libs: test/unit and minitest)
30
+ # * :auto_discover (default)
31
+ #
32
+ # This will load a class constantized by name.
33
+ #
34
+ cattr_accessor :test_framework
35
+ self.test_framework = :auto_discover
36
+
37
+ # Framework to know the folders and files that need to monitoring by the observer.
38
+ #
39
+ # ==== Options
40
+ # * :rails
41
+ # * :rubygems
42
+ # * :auto_discover(defaults)
43
+ #
44
+ # This will load a exactly a class constantize by name.
45
+ #
46
+ cattr_accessor :framework
47
+ self.framework = :auto_discover
48
+
49
+ # Framework to observe and watch the dirs for file changes.
50
+ #
51
+ # ==== Options
52
+ # * :listen (default) - Event-driven, uses native OS notifications
53
+ # * :filewatcher - Polling-based, works everywhere including VMs/NFS
54
+ #
55
+ cattr_accessor :observer
56
+ self.observer = :listen
57
+
58
+ # Ignore test files.
59
+ #
60
+ # ==== Examples
61
+ # ignore_test_files = [ 'spec/generators/controller_generator_spec.rb' ]
62
+ #
63
+ cattr_accessor :ignore_test_files
64
+ self.ignore_test_files = []
65
+
66
+ # Ignore test folders.
67
+ #
68
+ # ==== Examples
69
+ # # Imagine that you don't want to run integration specs.
70
+ # ignore_test_folders = [ 'spec/integration' ]
71
+ #
72
+ cattr_accessor :ignore_test_folders
73
+ self.ignore_test_folders = []
74
+
75
+ # Verbose Mode. Print commands before executing them.
76
+ #
77
+ cattr_accessor :verbose
78
+ self.verbose = true
79
+
80
+ # Set the notification framework to use with Infinity Test.
81
+ #
82
+ # ==== Options
83
+ # * :auto_discover (default) - Automatically detect available notifier
84
+ # * :terminal_notifier - macOS terminal-notifier
85
+ # * :osascript - macOS built-in notifications
86
+ # * :notify_send - Linux/BSD libnotify
87
+ # * :dunstify - Linux/BSD dunst
88
+ #
89
+ cattr_writer :notifications
90
+ self.notifications = :auto_discover
91
+
92
+ # You can set directory to show images matched by the convention names.
93
+ # => http://github.com/tomas-stefano/infinity_test/tree/master/images/ )
94
+ #
95
+ # Infinity test will work on these names in the notification framework:
96
+ #
97
+ # * success (png, gif, jpeg)
98
+ # * failure (png, gif, jpeg)
99
+ # * pending (png, gif, jpeg)
100
+ #
101
+ cattr_accessor :mode
102
+
103
+ #
104
+ # => This will show images in the folder:
105
+ # http://github.com/tomas-stefano/infinity_test/tree/master/images/simpson
106
+ #
107
+ self.mode = :simpson
108
+
109
+ # Success Image to show after the tests run.
110
+ #
111
+ cattr_accessor :success_image
112
+
113
+ # Pending Image to show after the tests run.
114
+ #
115
+ cattr_accessor :pending_image
116
+
117
+ # Failure Image to show after the tests run.
118
+ #
119
+ cattr_accessor :failure_image
120
+
121
+ # Use a specific gemset for each ruby.
122
+ # OBS.: This only will work for RVM strategy.
123
+ #
124
+ cattr_accessor :gemset
125
+
126
+ # InfinityTest try to use bundler if Gemfile is present.
127
+ # Set to false if you don't want use bundler.
128
+ #
129
+ cattr_accessor :bundler
130
+ self.bundler = true
131
+
132
+ # Callbacks accessor to handle before or after all run and for each ruby!
133
+ cattr_accessor :callbacks
134
+ self.callbacks = []
135
+
136
+ # Run the observer to monitor files.
137
+ # If set to false will just <b>Run tests and exit</b>.
138
+ # Defaults to true: run tests and monitoring the files.
139
+ #
140
+ cattr_accessor :infinity_and_beyond
141
+ self.infinity_and_beyond = true
142
+
143
+ # Skip running tests on startup, only watch for file changes.
144
+ # Useful for large applications where you want to start watching quickly.
145
+ #
146
+ cattr_accessor :just_watch
147
+ self.just_watch = false
148
+
149
+ # Focus mode for running specific tests.
150
+ #
151
+ # ==== Options
152
+ # * nil - Run all tests (default)
153
+ # * :failures - Run only previously failed tests
154
+ # * String - Run only the specified file/pattern
155
+ #
156
+ cattr_accessor :focus
157
+ self.focus = nil
158
+
159
+ # The extension files that Infinity Test will search.
160
+ # You can observe python, erlang, etc files.
161
+ #
162
+ cattr_accessor :extension
163
+ self.extension = :rb
164
+
165
+ # Setup Infinity Test passing the ruby versions and others setting.
166
+ # <b>See the class accessors for more information.</b>
167
+ #
168
+ # ==== Examples
169
+ #
170
+ # InfinityTest::Base.setup do |config|
171
+ # config.strategy = :rbenv
172
+ # config.rubies = %w(ree jruby rbx 1.9.2)
173
+ # end
174
+ #
175
+ def self.setup
176
+ yield self
177
+ end
178
+
179
+ # Receives a object that quacks like InfinityTest::Options and do the merge with self(Base class).
180
+ #
181
+ def self.merge!(options)
182
+ ConfigurationMerge.new(self, options).merge!
183
+ end
184
+
185
+ def self.start_continuous_test_server
186
+ continuous_test_server.start
187
+ end
188
+
189
+ def self.continuous_test_server
190
+ @continuous_test_server ||= ContinuousTestServer.new(self)
191
+ end
192
+
193
+ # Just a shortcut to bundler class accessor.
194
+ #
195
+ def self.using_bundler?
196
+ bundler
197
+ end
198
+
199
+ # Just a shortcut to bundler class accessor.
200
+ #
201
+ def self.verbose?
202
+ verbose
203
+ end
204
+
205
+ # Callback method to handle before all run and for each ruby too!
206
+ #
207
+ # ==== Examples
208
+ #
209
+ # before(:all) do
210
+ # # ...
211
+ # end
212
+ #
213
+ # before(:each_ruby) do |environment|
214
+ # # ...
215
+ # end
216
+ #
217
+ # before do # if you pass not then will use :all option
218
+ # # ...
219
+ # end
220
+ #
221
+ def self.before(scope = :all, &block)
222
+ callback = Callback.new(:before, scope, &block)
223
+ callbacks.push(callback)
224
+ callback
225
+ end
226
+
227
+ # Callback method to handle after all run and for each ruby too!
228
+ #
229
+ # ==== Examples
230
+ #
231
+ # after(:all) do
232
+ # # ...
233
+ # end
234
+ #
235
+ # after(:each_ruby) do
236
+ # # ...
237
+ # end
238
+ #
239
+ # after do # if you pass not then will use :all option
240
+ # # ...
241
+ # end
242
+ #
243
+ def self.after(scope = :all, &block)
244
+ callback = Callback.new(:after, scope, &block)
245
+ callbacks.push(callback)
246
+ callback
247
+ end
248
+
249
+ # Run all before callbacks for the given scope
250
+ #
251
+ def self.run_before_callbacks(scope = :all, environment = nil)
252
+ callbacks.select { |c| c.before? && c.scope == scope }.each do |callback|
253
+ callback.call(environment)
254
+ end
255
+ end
256
+
257
+ # Run all after callbacks for the given scope
258
+ #
259
+ def self.run_after_callbacks(scope = :all, environment = nil)
260
+ callbacks.select { |c| c.after? && c.scope == scope }.each do |callback|
261
+ callback.call(environment)
262
+ end
263
+ end
264
+
265
+ # Clear all registered callbacks
266
+ #
267
+ def self.clear_callbacks!
268
+ self.callbacks = []
269
+ end
270
+
271
+ # Clear the terminal (Useful in the before callback)
272
+ #
273
+ def self.clear_terminal
274
+ system('clear')
275
+ end
276
+
277
+ ###### This methods will be removed in the Infinity Test v2.0.1 or 2.0.2 ######
278
+
279
+ # <b>DEPRECATED:</b> Please use <tt>.notification=</tt> instead.
280
+ #
281
+ def self.notifications(notification_name = nil, &block)
282
+ if notification_name.blank?
283
+ self.class_variable_get(:@@notifications)
284
+ else
285
+ message = <<-MESSAGE
286
+ .notifications is DEPRECATED.
287
+ Use this instead:
288
+ InfinityTest.setup do |config|
289
+ config.notifications = :dunstify
290
+ end
291
+ MESSAGE
292
+ ActiveSupport::Deprecation.new.warn(message)
293
+ self.notifications = notification_name
294
+ self.instance_eval(&block) if block_given?
295
+ end
296
+ end
297
+
298
+ # <b>DEPRECATED:</b> Please use:
299
+ # <tt>success_image=</tt> or
300
+ # <tt>pending_image=</tt> or
301
+ # <tt>failure_image=</tt> or
302
+ # <tt>mode=</tt> instead.
303
+ #
304
+ def self.show_images(options)
305
+ message = <<-MESSAGE
306
+ .show_images is DEPRECATED.
307
+ Use this instead:
308
+ InfinityTest.setup do |config|
309
+ config.success_image = 'some_image.png'
310
+ config.pending_image = 'some_image.png'
311
+ config.failure_image = 'some_image.png'
312
+ config.mode = 'infinity_test_dir_that_contain_images'
313
+ end
314
+ MESSAGE
315
+ ActiveSupport::Deprecation.new.warn(message)
316
+ self.success_image = options[:success_image] || options[:sucess_image] if options[:success_image].present? || options[:sucess_image].present? # for fail typo in earlier versions.
317
+ self.pending_image = options[:pending_image] if options[:pending_image].present?
318
+ self.failure_image = options[:failure_image] if options[:failure_image].present?
319
+ self.mode = options[:mode] if options[:mode].present?
320
+ end
321
+
322
+ # <b>DEPRECATED:</b> Please use:
323
+ # .rubies = or
324
+ # .specific_options = or
325
+ # .test_framework = or
326
+ # .framework = or
327
+ # .verbose = or
328
+ # .gemset = instead
329
+ #
330
+ def self.use(options)
331
+ message = <<-MESSAGE
332
+ .use is DEPRECATED.
333
+ Use this instead:
334
+ InfinityTest.setup do |config|
335
+ config.rubies = %w(2.0 jruby)
336
+ config.specific_options = '-J'
337
+ config.test_framework = :rspec
338
+ config.framework = :padrino
339
+ config.verbose = true
340
+ config.gemset = :some_gemset
341
+ end
342
+ MESSAGE
343
+ ActiveSupport::Deprecation.new.warn(message)
344
+ self.rubies = options[:rubies] if options[:rubies].present?
345
+ self.specific_options = options[:specific_options] if options[:specific_options].present?
346
+ self.test_framework = options[:test_framework] if options[:test_framework].present?
347
+ self.framework = options[:app_framework] if options[:app_framework].present?
348
+ self.verbose = options[:verbose] unless options[:verbose].nil?
349
+ self.gemset = options[:gemset] if options[:gemset].present?
350
+ end
351
+
352
+ # <b>DEPRECATED:</b> Please use .clear_terminal instead.
353
+ #
354
+ def self.clear(option)
355
+ message = '.clear(:terminal) is DEPRECATED. Please use .clear_terminal instead.'
356
+ ActiveSupport::Deprecation.new.warn(message)
357
+ clear_terminal
358
+ end
359
+
360
+ def self.heuristics(&block)
361
+ # There is a spec pending.
362
+ end
363
+
364
+ def self.replace_patterns(&block)
365
+ # There is a spec pending.
366
+ end
367
+ end
368
+ end
369
+ end
@@ -0,0 +1,59 @@
1
+ module InfinityTest
2
+ module Core
3
+ class Callback
4
+ attr_reader :scope, :block, :type
5
+
6
+ VALID_SCOPES = [:all, :each_ruby].freeze
7
+
8
+ # Create a new callback
9
+ #
10
+ # @param type [Symbol] :before or :after
11
+ # @param scope [Symbol] :all or :each_ruby (defaults to :all)
12
+ # @param block [Proc] The block to execute
13
+ #
14
+ def initialize(type, scope = :all, &block)
15
+ @type = type
16
+ @scope = scope || :all
17
+ @block = block
18
+
19
+ validate_scope!
20
+ end
21
+
22
+ # Execute the callback block
23
+ #
24
+ # @param environment [Hash] Optional environment info passed to the block
25
+ #
26
+ def call(environment = nil)
27
+ if block.arity > 0
28
+ block.call(environment)
29
+ else
30
+ block.call
31
+ end
32
+ end
33
+
34
+ def before?
35
+ type == :before
36
+ end
37
+
38
+ def after?
39
+ type == :after
40
+ end
41
+
42
+ def all?
43
+ scope == :all
44
+ end
45
+
46
+ def each_ruby?
47
+ scope == :each_ruby
48
+ end
49
+
50
+ private
51
+
52
+ def validate_scope!
53
+ unless VALID_SCOPES.include?(scope)
54
+ raise ArgumentError, "Invalid callback scope: #{scope}. Valid scopes are: #{VALID_SCOPES.join(', ')}"
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,13 @@
1
+ module InfinityTest
2
+ module Core
3
+ class ChangedFile
4
+ attr_accessor :match_data, :name, :path
5
+
6
+ def initialize(match_data)
7
+ @match_data = match_data
8
+ @name = match_data.to_s
9
+ @path = match_data[1]
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,48 @@
1
+ module InfinityTest
2
+ module Core
3
+ class CommandBuilder < String
4
+ # Just Syntax Sugar to add the keyword in the command
5
+ #
6
+ def add(command)
7
+ self << " #{command.to_s}"
8
+ self
9
+ end
10
+
11
+ # Put a double-dash in the command option.
12
+ #
13
+ def opt(command_option)
14
+ self << " --#{command_option}"
15
+ self
16
+ end
17
+
18
+ # Put one dash in the command option
19
+ #
20
+ def option(command_option)
21
+ self << " -#{command_option}"
22
+ self
23
+ end
24
+
25
+ # An Object that respond to all methods.
26
+ #
27
+ def respond_to?(method_name)
28
+ true
29
+ end
30
+
31
+ # Everytime will call a method will append to self.
32
+ #
33
+ # ==== Examples
34
+ #
35
+ # command.bundle.exec.rspec.spec
36
+ # command.bundle.install
37
+ #
38
+ def method_missing(method_name, *args, &block)
39
+ if self.empty?
40
+ self << "#{method_name.to_s}"
41
+ else
42
+ self << " #{method_name.to_s}"
43
+ end
44
+ self
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,62 @@
1
+ module InfinityTest
2
+ module Core
3
+ class CommandRunner < String
4
+ attr_accessor :command
5
+
6
+ def initialize(command)
7
+ @command = command
8
+
9
+ super(run!)
10
+ end
11
+
12
+ def run!
13
+ SynchronizeStdout.new do
14
+ open("| #{@command}", "r") do |file|
15
+ @command_output = CommandOutput.new(file)
16
+ @command_output.puts
17
+ end
18
+ end
19
+
20
+ @command_output.stdout
21
+ end
22
+ end
23
+
24
+ class CommandOutput
25
+ def initialize(file)
26
+ @file = file
27
+ @results = []
28
+ @line = []
29
+ end
30
+
31
+ def puts
32
+ until @file.eof? do
33
+ test_line = @file.getc or break
34
+ print(test_line)
35
+ @line.push(test_line)
36
+ if test_line == ?\n
37
+ # @results.push(yarv? ? @line.join : @line.pack('c*'))
38
+ @results.push(@line.join)
39
+ @line.clear
40
+ end
41
+ end
42
+ end
43
+
44
+ def stdout
45
+ @results.join
46
+ end
47
+ end
48
+
49
+ class SynchronizeStdout
50
+ def initialize
51
+ old_sync = $stdout.sync
52
+ $stdout.sync = true
53
+
54
+ begin
55
+ yield
56
+ ensure
57
+ $stdout.sync = old_sync
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,37 @@
1
+ module InfinityTest
2
+ module Core
3
+ class ConfigurationMerge
4
+ attr_accessor :base, :options
5
+
6
+ delegate :strategy, :rubies, :test_framework, :framework, :to => :options
7
+ delegate :specific_options, :infinity_and_beyond, :verbose, :bundler, :to => :options
8
+ delegate :notifications, :mode, :just_watch, :focus, :to => :options
9
+
10
+ def initialize(base, options)
11
+ @base = base
12
+ @options = options
13
+ end
14
+
15
+ # Execute the merge between base and command line options
16
+ #
17
+ # === Returns
18
+ # <Core::BaseClass>: The infinity test core base class.
19
+ #
20
+ def merge!
21
+ @base.strategy = strategy if strategy.present?
22
+ @base.rubies = rubies unless rubies.nil?
23
+ @base.specific_options = specific_options if specific_options.present?
24
+ @base.test_framework = test_framework if test_framework.present?
25
+ @base.framework = framework if framework.present?
26
+ @base.infinity_and_beyond = infinity_and_beyond unless infinity_and_beyond.nil?
27
+ @base.verbose = verbose unless verbose.nil?
28
+ @base.bundler = bundler unless bundler.nil?
29
+ @base.notifications = notifications if notifications.present?
30
+ @base.mode = mode if mode.present?
31
+ @base.just_watch = just_watch unless just_watch.nil?
32
+ @base.focus = focus if focus.present?
33
+ @base
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,106 @@
1
+ module InfinityTest
2
+ module Core
3
+ class ContinuousTestServer
4
+ attr_reader :base
5
+ delegate :binary, :test_files, to: :test_framework
6
+ delegate :infinity_and_beyond, :notifications, :extension, :just_watch, :focus, to: :base
7
+
8
+ def initialize(base)
9
+ @base = base
10
+ end
11
+
12
+ def start
13
+ run_strategy unless just_watch
14
+ start_observer
15
+ end
16
+
17
+ # Run strategy based on the choosed ruby strategy.
18
+ #
19
+ def run_strategy
20
+ Base.run_before_callbacks(:all)
21
+
22
+ apply_focus if focus.present?
23
+ notify(strategy.run)
24
+
25
+ Base.run_after_callbacks(:all)
26
+ ensure
27
+ clear_focus
28
+ end
29
+
30
+ # Apply focus filter to test files
31
+ #
32
+ def apply_focus
33
+ case focus
34
+ when :failures
35
+ test_framework.test_files = last_failed_files if last_failed_files.present?
36
+ when String
37
+ test_framework.test_files = focus if File.exist?(focus)
38
+ end
39
+ end
40
+
41
+ # Clear focus after running tests
42
+ #
43
+ def clear_focus
44
+ test_framework.test_files = nil
45
+ end
46
+
47
+ # Track last failed test files (stored in .infinity_test_failures)
48
+ #
49
+ def last_failed_files
50
+ failures_file = '.infinity_test_failures'
51
+ return nil unless File.exist?(failures_file)
52
+ File.read(failures_file).split("\n").select { |f| File.exist?(f) }.join(' ')
53
+ end
54
+
55
+ # Re run strategy changed the changed files.
56
+ #
57
+ def rerun_strategy(files)
58
+ test_framework.test_files = files
59
+ run_strategy
60
+ ensure
61
+ test_framework.test_files = nil
62
+ end
63
+
64
+ def notify(strategy_result)
65
+ if notifications.present?
66
+ test_framework.test_message = strategy_result
67
+
68
+ Core::Notifier.new(library: notifications, test_framework: test_framework).notify
69
+ end
70
+ end
71
+
72
+ # Start to monitoring files in the project.
73
+ #
74
+ def start_observer
75
+ if infinity_and_beyond.present?
76
+ framework.heuristics!
77
+ observer.start!
78
+ end
79
+ end
80
+
81
+ # Returns the instance for the configured strategy.
82
+ #
83
+ def strategy
84
+ @strategy ||= "InfinityTest::Strategy::#{base.strategy.to_s.classify}".constantize.new(self)
85
+ end
86
+
87
+ # Return a cached test framework instance.
88
+ #
89
+ def test_framework
90
+ @test_framework ||= "::InfinityTest::TestFramework::#{base.test_framework.to_s.classify}".constantize.new
91
+ end
92
+
93
+ # Return a framework instance based on the base framework accessor.
94
+ #
95
+ def framework
96
+ @framework ||= "::InfinityTest::Framework::#{base.framework.to_s.camelize}".constantize.new(self)
97
+ end
98
+
99
+ # Return a cached observer instance by the observer accessor.
100
+ #
101
+ def observer
102
+ @observer ||= "::InfinityTest::Observer::#{base.observer.to_s.classify}".constantize.new(self)
103
+ end
104
+ end
105
+ end
106
+ end