railstest 0.3.1

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.
@@ -0,0 +1,291 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tmpdir'
4
+ require 'fileutils'
5
+
6
+ module Railstest
7
+ class DockerManager
8
+ attr_reader :ruby_version, :rails_version, :gem_path, :database
9
+
10
+ def initialize(ruby_version:, rails_version:, gem_path: nil, database: nil)
11
+ @ruby_version = ruby_version
12
+ @rails_version = rails_version
13
+ @gem_path = gem_path
14
+ @database = database
15
+ @target_gem_name = nil
16
+ validate_docker!
17
+ validate_gem_path! if target_gem_mode?
18
+ end
19
+
20
+ def build_image
21
+ puts "Building Docker image for Ruby #{ruby_version} and Rails #{rails_version}..."
22
+ dockerfile_path = File.join(Dir.tmpdir, "railstest_dockerfile_#{Process.pid}")
23
+
24
+ begin
25
+ File.write(dockerfile_path, generate_dockerfile)
26
+
27
+ build_args = [
28
+ '--build-arg', "RUBY_VERSION=#{ruby_version}"
29
+ ]
30
+
31
+ if target_gem_mode?
32
+ build_args << '--build-arg' << "TARGET_GEM_NAME=#{target_gem_name}"
33
+ build_args << '--build-arg' << "RAILS_VERSION=#{rails_version}"
34
+ else
35
+ # Local mode: find actual gemfile and pass it
36
+ gemfile = find_gemfile_for_version
37
+ build_args << '--build-arg' << "GEMFILE_PATH=gemfiles/#{gemfile}"
38
+ end
39
+
40
+ success = system(
41
+ 'docker', 'build', '.',
42
+ '-f', dockerfile_path,
43
+ *build_args,
44
+ '-t', image_name
45
+ )
46
+
47
+ raise Error, 'Docker build failed' unless success
48
+ ensure
49
+ FileUtils.rm_f(dockerfile_path)
50
+ end
51
+ end
52
+
53
+ def run_command(command, env_vars: {}, volumes: [], workdir: nil)
54
+ docker_cmd = ['docker', 'run', '--rm', '--network=host']
55
+
56
+ env_vars.each do |key, value|
57
+ docker_cmd << '-e' << "#{key}=#{value}"
58
+ end
59
+
60
+ volumes.each do |volume|
61
+ docker_cmd << '-v' << volume
62
+ end
63
+
64
+ docker_cmd << '-w' << workdir if workdir
65
+
66
+ docker_cmd << image_name
67
+ docker_cmd.concat(Array(command))
68
+
69
+ system(*docker_cmd)
70
+ end
71
+
72
+ def image_name
73
+ @image_name ||= begin
74
+ base = File.basename(Dir.pwd).downcase.gsub(/[^a-z0-9._-]/, '-')
75
+ ruby_tag = ruby_version.to_s.gsub(/[^a-z0-9._-]/, '-')
76
+ rails_tag = rails_version.to_s.gsub(/[^a-z0-9._-]/, '-')
77
+ "#{base}-ruby#{ruby_tag}-rails#{rails_tag}-tests"
78
+ end
79
+ end
80
+
81
+ def target_gem_mode?
82
+ !gem_path.nil? && !gem_path.empty?
83
+ end
84
+
85
+ def target_gem_name
86
+ return @target_gem_name if @target_gem_name
87
+ return nil unless target_gem_mode?
88
+
89
+ @target_gem_name = extract_gem_name(gem_path)
90
+ end
91
+
92
+ def expanded_gem_path
93
+ return nil unless target_gem_mode?
94
+
95
+ File.expand_path(gem_path)
96
+ end
97
+
98
+ def rails_version_for_gemfile
99
+ # Convert dotted format to underscore for gemfile paths (e.g., 7.1 -> 7_1)
100
+ rails_version.tr('.', '_')
101
+ end
102
+
103
+ def find_gemfile_for_version
104
+ # Find actual gemfile in gemfiles/ directory that matches the Rails version
105
+ # Handles various naming conventions: rails_7.0.gemfile, Gemfile.rails-5.2-rc1, etc.
106
+ return nil if target_gem_mode?
107
+
108
+ gemfiles_dir = 'gemfiles'
109
+ return nil unless File.directory?(gemfiles_dir)
110
+
111
+ # Look for any file containing the version pattern, exclude lock files
112
+ matching_files = Dir.glob(File.join(gemfiles_dir, '*')).select do |f|
113
+ basename = File.basename(f)
114
+ rails_version_regex = rails_version.gsub('.', '[.-]')
115
+ basename =~ /#{rails_version_regex}/ && basename !~ /\.lock$/
116
+ end
117
+
118
+ raise Error, "No gemfile found in gemfiles/ for Rails #{rails_version}" if matching_files.empty?
119
+
120
+ if matching_files.length > 1
121
+ # Prefer exact patterns, warn about multiple matches
122
+ puts "⚠️ Warning: Multiple gemfiles found for Rails #{rails_version}:"
123
+ matching_files.each { |f| puts " - #{File.basename(f)}" }
124
+ puts " Using: #{File.basename(matching_files.first)}"
125
+ end
126
+
127
+ File.basename(matching_files.first)
128
+ end
129
+
130
+ private
131
+
132
+ # Reads an Aptfile from the gem root (one package per line, # comments allowed).
133
+ # Returns the packages as a space-separated string, or '' if no Aptfile exists.
134
+ def extra_apt_packages
135
+ return '' unless target_gem_mode?
136
+
137
+ aptfile = File.join(expanded_gem_path, 'Aptfile')
138
+ return '' unless File.exist?(aptfile)
139
+
140
+ packages = File.readlines(aptfile)
141
+ .map { |l| l.sub(/#.*/, '').strip }
142
+ .reject(&:empty?)
143
+ packages.join(' ')
144
+ end
145
+
146
+ # Returns the Dockerfile RUN lines needed to install the requested database adapter,
147
+ # stripping any existing declaration first to avoid version conflicts.
148
+ # Returns an empty string when no --db was specified (gem's own Gemfile is used as-is).
149
+ def adapter_setup
150
+ return '' unless database
151
+
152
+ gem_name, version, sed_pattern = case database.to_s
153
+ when 'mysql' then ['mysql2', '~> 0.5', '/mysql2/d']
154
+ when 'postgres' then ['pg', '~> 1.1', "/'pg'/d; /\\\"pg\\\"/d"]
155
+ else ['sqlite3', '~> 2.1', '/sqlite3/d']
156
+ end
157
+ "RUN sed -i \"#{sed_pattern}\" Gemfile\nRUN echo \"gem '#{gem_name}', '#{version}'\" >> Gemfile"
158
+ end
159
+
160
+ def validate_docker!
161
+ return if system('docker --version > /dev/null 2>&1')
162
+
163
+ raise Error, 'Docker is not installed or not in PATH'
164
+ end
165
+
166
+ def validate_gem_path!
167
+ expanded = File.expand_path(gem_path)
168
+ raise Error, "Gem path does not exist: #{expanded}" unless File.directory?(expanded)
169
+
170
+ # Check if gem has gemfiles/ directory - should use local mode instead
171
+ gemfiles_dir = File.join(expanded, 'gemfiles')
172
+ return unless File.directory?(gemfiles_dir)
173
+
174
+ raise Error, <<~ERROR
175
+ This gem has a 'gemfiles/' directory and should be tested in local mode.
176
+
177
+ Instead of:
178
+ railstest --gem-path #{gem_path}
179
+
180
+ Use local mode by running from the gem directory:
181
+ cd #{gem_path}
182
+ railstest
183
+ ERROR
184
+ end
185
+
186
+ def extract_gem_name(gemspec_path)
187
+ gemspec_files = Dir.glob(File.join(gemspec_path, '*.gemspec'))
188
+
189
+ raise Error, "No .gemspec file found in #{gemspec_path}" if gemspec_files.empty?
190
+
191
+ gemspec_file = gemspec_files.first
192
+ content = File.read(gemspec_file)
193
+
194
+ # Try to match spec.name = "gem_name" or s.name = 'gem_name' (handles both spec and s)
195
+ return ::Regexp.last_match(1) if content =~ /\w+\.name\s*=\s*["']([^"']+)["']/
196
+
197
+ raise Error, "Could not extract gem name from #{gemspec_file}"
198
+ end
199
+
200
+ def generate_dockerfile
201
+ if target_gem_mode?
202
+ generate_target_gem_dockerfile
203
+ else
204
+ generate_local_dockerfile
205
+ end
206
+ end
207
+
208
+ def generate_target_gem_dockerfile
209
+ has_dummy_app = File.exist?(File.join(expanded_gem_path, 'test/dummy/config/environment.rb'))
210
+
211
+ if has_dummy_app
212
+ # Rails engine with dummy app - mount gem and test from within it
213
+ <<~DOCKERFILE
214
+ # Dockerfile for running Rails engine tests
215
+
216
+ ARG RUBY_VERSION=3.3
217
+ FROM ruby:$RUBY_VERSION
218
+
219
+ ARG RAILS_VERSION
220
+
221
+ RUN apt-get update -qq && apt-get install -y build-essential git curl #{extra_apt_packages}
222
+
223
+ WORKDIR /app/test_app
224
+
225
+ # Install Rails version needed by the gem
226
+ RUN gem install rails --version "~> ${RAILS_VERSION}.0" --no-document
227
+
228
+ # Copy all gem files
229
+ COPY . .
230
+
231
+ RUN rm -f Gemfile.lock
232
+ #{adapter_setup}
233
+
234
+ RUN gem install bundler --quiet --no-document && bundle install --quiet
235
+ DOCKERFILE
236
+ else
237
+ # Regular Rails app or library - create new test app
238
+ <<~DOCKERFILE
239
+ # Dockerfile for running gem tests
240
+
241
+ ARG RUBY_VERSION=3.3
242
+ FROM ruby:$RUBY_VERSION
243
+
244
+ ARG RAILS_VERSION
245
+ ARG TARGET_GEM_NAME
246
+
247
+ RUN apt-get update -qq && apt-get install -y build-essential git curl
248
+
249
+ WORKDIR /app
250
+
251
+ # Create a new Rails application to host the gem tests
252
+ # Use full Rails (not minimal/api) since gem could extend any part of Rails
253
+ RUN gem install rails --version "~> ${RAILS_VERSION}.0" --no-document --quiet
254
+ RUN rails new test_app --skip-bundle
255
+
256
+ WORKDIR /app/test_app
257
+
258
+ #{adapter_setup}
259
+
260
+ # Remove existing gem entry if present, then add target gem with path
261
+ RUN sed -i "/gem ['\"]${TARGET_GEM_NAME}['\"]/d" Gemfile && \
262
+ echo "gem '${TARGET_GEM_NAME}', path: '/app/target_gem'" >> Gemfile
263
+
264
+ # Install dependencies - this gets cached if Gemfile doesn't change
265
+ RUN bundle install --quiet
266
+ DOCKERFILE
267
+ end
268
+ end
269
+
270
+ def generate_local_dockerfile
271
+ <<~DOCKERFILE
272
+ # Dockerfile for running tests
273
+
274
+ ARG RUBY_VERSION=3.3
275
+ FROM ruby:$RUBY_VERSION
276
+
277
+ ARG GEMFILE_PATH
278
+
279
+ RUN apt-get update -qq && apt-get install -y build-essential
280
+
281
+ WORKDIR /app
282
+ COPY . .
283
+
284
+ # Use the actual gemfile found in gemfiles/ directory
285
+ RUN BUNDLE_GEMFILE="${GEMFILE_PATH}" bundle install --quiet
286
+
287
+ # No ENTRYPOINT - commands will be passed directly to docker run
288
+ DOCKERFILE
289
+ end
290
+ end
291
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Railstest
4
+ SUPPORTED_VERSIONS = {
5
+ ruby: {
6
+ minimum: '3.2',
7
+ recommended: '4.0', # Latest stable
8
+ supported: ['3.2', '3.3', '3.4', '4.0'],
9
+ experimental: ['2.5', '2.6', '2.7', '3.0', '3.1'] # EOL
10
+ },
11
+ rails: {
12
+ minimum: '7.0',
13
+ recommended: '8.1', # Latest stable
14
+ supported: ['7.2', '8.0', '8.1'],
15
+ experimental: ['6.0', '6.1', '7.0', '7.1'] # EOL
16
+ },
17
+ # Ruby version => Working Rails versions
18
+ # Verified combinations from self-testing + known requirements from Rails
19
+ #
20
+ # Ruby < 3.2 is intentionally absent: every Rails version we target depends
21
+ # on zeitwerk, and zeitwerk >= 2.7.0 requires Ruby >= 3.2. A fresh
22
+ # `gem install rails` resolves to the latest zeitwerk, so it can no longer
23
+ # be installed on Ruby < 3.2 regardless of the Rails version requested.
24
+ compatibility: {
25
+ '4.0' => ['7.1', '7.2', '8.0', '8.1'], # Rails 8.x requires Ruby >= 3.2
26
+ '3.4' => ['7.1', '7.2', '8.0', '8.1'], # Rails 8.x requires Ruby >= 3.2
27
+ '3.3' => ['7.0', '7.1', '7.2', '8.0', '8.1'], # Rails 8.x requires Ruby >= 3.2, verified 7.x-8.0
28
+ '3.2' => ['7.0', '7.1', '7.2', '8.0', '8.1'], # Rails 8.x requires Ruby >= 3.2, verified 7.x-8.0
29
+ # zeitwerk >= 2.7.0 requires Ruby >= 3.2, so these can no longer
30
+ # fresh-install any zeitwerk-based Rails (6.0+).
31
+ '3.1' => [],
32
+ '3.0' => [],
33
+ '2.7' => [],
34
+ '2.6' => [],
35
+ '2.5' => []
36
+ },
37
+ notes: {
38
+ '2.5' => 'Unsupported: Rails depends on zeitwerk, which requires Ruby >= 3.2',
39
+ '2.6' => 'Unsupported: Rails depends on zeitwerk, which requires Ruby >= 3.2',
40
+ '2.7' => 'Unsupported: Rails depends on zeitwerk, which requires Ruby >= 3.2',
41
+ '3.0' => 'Unsupported: Rails depends on zeitwerk, which requires Ruby >= 3.2',
42
+ '3.1' => 'Unsupported: Rails depends on zeitwerk, which requires Ruby >= 3.2',
43
+ '8.0' => 'Requires Ruby 3.2+',
44
+ '8.1' => 'Requires Ruby 3.2+'
45
+ }
46
+ }.freeze
47
+
48
+ def self.compatible?(ruby_version, rails_version)
49
+ ruby_major_minor = normalize_version(ruby_version)
50
+ rails_major_minor = normalize_version(rails_version)
51
+
52
+ compat = SUPPORTED_VERSIONS[:compatibility][ruby_major_minor]
53
+ return nil unless compat # Unknown Ruby version
54
+
55
+ compat.include?(rails_major_minor)
56
+ end
57
+
58
+ def self.recommended_rails_versions(ruby_version)
59
+ ruby_major_minor = normalize_version(ruby_version)
60
+ SUPPORTED_VERSIONS[:compatibility][ruby_major_minor] || []
61
+ end
62
+
63
+ def self.note_for(version)
64
+ major_minor = normalize_version(version)
65
+ SUPPORTED_VERSIONS[:notes][major_minor]
66
+ end
67
+
68
+ def self.normalize_version(version)
69
+ # Convert "3.3.0" or "3.3" to "3.3"
70
+ version.to_s.match(/^(\d+\.\d+)/)[1]
71
+ rescue NoMethodError
72
+ version.to_s
73
+ end
74
+ end
@@ -0,0 +1,236 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'English'
4
+ module Railstest
5
+ class TestRunner
6
+ attr_reader :options, :docker_manager, :database_manager
7
+
8
+ def initialize(options)
9
+ @options = options
10
+ @docker_manager = DockerManager.new(
11
+ ruby_version: options[:ruby_version],
12
+ rails_version: options[:rails_version],
13
+ gem_path: options[:gem_path],
14
+ database: options[:database]
15
+ )
16
+ @database_manager = DatabaseManager.new(database: options[:database])
17
+ end
18
+
19
+ def run
20
+ # Setup signal handlers for graceful cleanup on Ctrl+C
21
+ setup_signal_handlers
22
+
23
+ # Validate that tests exist before building Docker image
24
+ validate_tests_exist!
25
+
26
+ docker_manager.build_image
27
+ database_manager.start
28
+
29
+ begin
30
+ database_manager.setup_database(docker_manager)
31
+ exit_status = run_tests
32
+ exit_status
33
+ ensure
34
+ database_manager.stop
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def validate_tests_exist!
41
+ gem_path = if docker_manager.target_gem_mode?
42
+ docker_manager.expanded_gem_path
43
+ else
44
+ Dir.pwd
45
+ end
46
+
47
+ # Check for test or spec directories
48
+ test_dir = File.join(gem_path, 'test')
49
+ spec_dir = File.join(gem_path, 'spec')
50
+
51
+ has_test_dir = File.directory?(test_dir)
52
+ has_spec_dir = File.directory?(spec_dir)
53
+
54
+ unless has_test_dir || has_spec_dir
55
+ raise Railstest::Error, <<~ERROR
56
+ No test directory found in gem.
57
+
58
+ Railstest requires either a 'test/' or 'spec/' directory with tests.
59
+
60
+ Gem path: #{gem_path}
61
+ ERROR
62
+ end
63
+
64
+ # Check if the directories actually contain test files
65
+ test_files = []
66
+ test_files += Dir.glob(File.join(test_dir, '**/*_test.rb')) if has_test_dir
67
+ test_files += Dir.glob(File.join(spec_dir, '**/*_spec.rb')) if has_spec_dir
68
+
69
+ return unless test_files.empty?
70
+
71
+ raise Railstest::Error, <<~ERROR
72
+ No test files found in gem.
73
+
74
+ Found directories:
75
+ #{has_test_dir ? ' - test/' : ''}
76
+ #{has_spec_dir ? ' - spec/' : ''}
77
+
78
+ But no test files (*_test.rb or *_spec.rb) were found.
79
+
80
+ Gem path: #{gem_path}
81
+ ERROR
82
+ end
83
+
84
+ def setup_signal_handlers
85
+ # Trap SIGINT (Ctrl+C) and SIGTERM to ensure cleanup
86
+ %w[INT TERM].each do |signal|
87
+ Signal.trap(signal) do
88
+ puts "\n\nInterrupted! Cleaning up..."
89
+ database_manager.stop
90
+ exit(130) # Standard exit code for SIGINT
91
+ end
92
+ end
93
+ end
94
+
95
+ def run_tests
96
+ test_framework = detect_test_framework
97
+ command = build_test_command(test_framework)
98
+
99
+ puts "Running tests with #{options[:database]}..."
100
+
101
+ # Use IO.popen to stream output in real-time
102
+ # Read in chunks to show test dots as they appear (not line-buffered)
103
+ IO.popen(command, err: %i[child out]) do |io|
104
+ loop do
105
+ chunk = io.readpartial(1024)
106
+ print chunk
107
+ $stdout.flush
108
+ rescue EOFError
109
+ break
110
+ end
111
+ end
112
+
113
+ $CHILD_STATUS.exitstatus
114
+ end
115
+
116
+ def detect_test_framework
117
+ # Check for spec directory
118
+ if docker_manager.target_gem_mode?
119
+ gem_path = docker_manager.expanded_gem_path
120
+ return :rspec if File.directory?(File.join(gem_path, 'spec'))
121
+ return :rails_test if File.directory?(File.join(gem_path, 'test'))
122
+
123
+ # Check Gemfile for rspec
124
+ gemfile_path = File.join(gem_path, 'Gemfile')
125
+ if File.exist?(gemfile_path)
126
+ gemfile_content = File.read(gemfile_path)
127
+ return :rspec if gemfile_content =~ /gem\s+['"]rspec/
128
+ end
129
+ else
130
+ return :rspec if File.directory?('spec')
131
+ return :rails_test if File.directory?('test')
132
+
133
+ if File.exist?('Gemfile')
134
+ gemfile_content = File.read('Gemfile')
135
+ return :rspec if gemfile_content =~ /gem\s+['"]rspec/
136
+ end
137
+ end
138
+
139
+ # Default to rails_test
140
+ :rails_test
141
+ end
142
+
143
+ def build_test_command(test_framework)
144
+ cmd = ['docker', 'run', '--rm', '--network=host']
145
+
146
+ # Environment variables
147
+ cmd << '-e' << "DATABASE=#{options[:database]}"
148
+ cmd << '-e' << "TARGET_DB=#{options[:database]}"
149
+ cmd << '-e' << 'RAILS_ENV=test'
150
+
151
+ # Volume mounts and working directory for target gem mode
152
+ if docker_manager.target_gem_mode?
153
+ has_dummy_app = File.exist?(File.join(docker_manager.expanded_gem_path, 'test/dummy/config/environment.rb'))
154
+
155
+ if has_dummy_app
156
+ # Rails engine: already baked into image via COPY during build - no volume mount needed
157
+ else
158
+ # Regular app: use target-gem volume mount
159
+ cmd << '-v' << "#{docker_manager.expanded_gem_path}:/app/target_gem"
160
+ end
161
+ cmd << '-w' << '/app/test_app'
162
+ else
163
+ # Local mode: use actual gemfile found in gemfiles/
164
+ gemfile = docker_manager.find_gemfile_for_version
165
+ cmd << '-e' << "BUNDLE_GEMFILE=/app/gemfiles/#{gemfile}"
166
+ cmd << '-w' << '/app'
167
+ end
168
+
169
+ cmd << docker_manager.image_name
170
+
171
+ # In target-gem mode, bundle is already installed during Docker build
172
+ if docker_manager.target_gem_mode?
173
+ test_cmd = build_test_subcommand(test_framework)
174
+ cmd << 'bash' << '-c' << test_cmd.to_s
175
+ else
176
+ # Local mode - bundle already installed during build
177
+ cmd.concat(build_test_subcommand_array(test_framework))
178
+ end
179
+
180
+ cmd
181
+ end
182
+
183
+ def build_test_subcommand(test_framework)
184
+ # Returns a shell command string for target-gem mode
185
+ has_dummy_app = File.exist?(File.join(docker_manager.expanded_gem_path, 'test/dummy/config/environment.rb'))
186
+
187
+ case test_framework
188
+ when :rspec
189
+ test_path = if has_dummy_app
190
+ options[:test_path] ? remap_path_for_container(options[:test_path]) : '/app/test_app/spec'
191
+ else
192
+ options[:test_path] ? remap_path_for_container(options[:test_path]) : '/app/target_gem/spec'
193
+ end
194
+ "bundle exec rspec #{test_path}"
195
+ when :rails_test
196
+ if has_dummy_app
197
+ # Rails engine: just run bin/rails test (discovers tests in dummy app)
198
+ options[:test_path] ? "bin/rails test #{remap_path_for_container(options[:test_path])}" : 'bin/rails test'
199
+ else
200
+ test_path = options[:test_path] ? remap_path_for_container(options[:test_path]) : '/app/target_gem/test'
201
+ "bin/rails test #{test_path}"
202
+ end
203
+ end
204
+ end
205
+
206
+ def build_test_subcommand_array(test_framework)
207
+ # Returns an array of command parts for local mode
208
+ case test_framework
209
+ when :rspec
210
+ cmd = %w[bundle exec rspec]
211
+ cmd << options[:test_path] if options[:test_path]
212
+ cmd
213
+ when :rails_test
214
+ # Check if bin/rails exists, otherwise use bundle exec rails
215
+ cmd = if File.exist?('bin/rails')
216
+ ['bin/rails', 'test']
217
+ else
218
+ %w[bundle exec rails test]
219
+ end
220
+ cmd << options[:test_path] if options[:test_path]
221
+ cmd
222
+ end
223
+ end
224
+
225
+ def remap_path_for_container(path)
226
+ # In target-gem mode, --path is interpreted relative to gem root
227
+ return path unless docker_manager.target_gem_mode?
228
+
229
+ # Always interpret as relative to gem root for consistency
230
+ # Remove leading slash if present to treat as relative
231
+ clean_path = path.start_with?('/') ? path[1..] : path
232
+
233
+ "/app/target_gem/#{clean_path}"
234
+ end
235
+ end
236
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Railstest
4
+ VERSION = '0.3.1'
5
+ end
data/lib/railstest.rb ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'railstest/version'
4
+ require_relative 'railstest/supported_versions'
5
+ require_relative 'railstest/docker_manager'
6
+ require_relative 'railstest/database_manager'
7
+ require_relative 'railstest/test_runner'
8
+ require_relative 'railstest/cli'
9
+
10
+ module Railstest
11
+ class Error < StandardError; end
12
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: railstest
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.1
5
+ platform: ruby
6
+ authors:
7
+ - Runar Ingebrigtsen
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: Test Rails gems with various Ruby, Rails, and database combinations using
13
+ Docker
14
+ email:
15
+ - ringe@rin.no
16
+ executables:
17
+ - railstest
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - CHANGELOG.md
22
+ - LICENSE.txt
23
+ - README.md
24
+ - bin/railstest
25
+ - docker-compose.yml
26
+ - lib/railstest.rb
27
+ - lib/railstest/cli.rb
28
+ - lib/railstest/database_manager.rb
29
+ - lib/railstest/docker_manager.rb
30
+ - lib/railstest/supported_versions.rb
31
+ - lib/railstest/test_runner.rb
32
+ - lib/railstest/version.rb
33
+ homepage: https://github.com/ringe/railstest
34
+ licenses:
35
+ - MIT
36
+ metadata:
37
+ homepage_uri: https://github.com/ringe/railstest
38
+ source_code_uri: https://github.com/ringe/railstest
39
+ changelog_uri: https://github.com/ringe/railstest/blob/main/CHANGELOG.md
40
+ rdoc_options: []
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ requirements: []
54
+ rubygems_version: 4.0.11
55
+ specification_version: 4
56
+ summary: Docker-based testing tool for Rails gems
57
+ test_files: []