Skip to content

Commit c712b23

Browse files
committed
feat: ensure windows compatibility for Ruby MRI
Add a CI build and make sure all tests pass on Windows or don't run them if not supported on Windows.
1 parent 90e183e commit c712b23

File tree

5 files changed

+41
-20
lines changed

5 files changed

+41
-20
lines changed

.github/workflows/continuous_integration.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ on:
77
workflow_dispatch:
88

99
# Supported platforms / Ruby versions:
10-
# - Ubuntu: MRI (3.2, 3.3, 3.4), TruffleRuby (24), JRuby (9.4)
10+
# - Ubuntu: MRI (3.2, 3.3, 3.4)
1111
# - Windows: MRI (3.2)
1212

1313
jobs:
@@ -30,6 +30,10 @@ jobs:
3030
ruby: ["3.2", "3.4"]
3131
operating-system: [ubuntu-latest]
3232
fail_on_low_coverage: [true]
33+
include:
34+
- # Only test with minimal Ruby version on Windows
35+
ruby: 3.2
36+
operating-system: windows-latest
3337

3438
steps:
3539
- name: Checkout

spec/rspec/path_matchers/be_dir_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,12 @@
215215
end
216216

217217
describe 'the mode: option' do
218+
before(:all) do
219+
# :nocov: this line is platform-specific
220+
skip 'File mode tests are only applicable on Unix-like platforms' unless UNIX_LIKE_PLATFORM
221+
# :nocov:
222+
end
223+
218224
subject { expect(path).to be_dir(mode: expected_mode) }
219225

220226
before { FileUtils.mkdir(path) }

spec/rspec/path_matchers/be_file_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,12 @@
572572
end
573573

574574
describe 'the mode: option' do
575+
before(:all) do
576+
# :nocov: this line is platform-specific
577+
skip 'File mode tests are only applicable on Unix-like platforms' unless UNIX_LIKE_PLATFORM
578+
# :nocov:
579+
end
580+
575581
subject { expect(path).to be_file(mode: expected_mode) }
576582

577583
before { FileUtils.touch(path) }

spec/rspec/path_matchers/failure_messages_spec.rb

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@
2222
app_path = File.join(base_dir, 'app')
2323
Dir.mkdir(app_path)
2424
FileUtils.chmod(0o700, app_path)
25+
# Mock the mtime to eliminate the potential for a different timezone output in the failure message
26+
mock_file_stat(app_path, mtime: mocked_now - 200)
2527

26-
matcher = be_dir(mode: '0755')
28+
matcher = be_dir(mtime: be_within(50).of(mocked_now))
2729
matcher.matches?(app_path)
2830

2931
expected_message = <<~MSG.chomp
3032
#{app_path} was not as expected:
31-
expected mode to be "0755", but it was "0700"
33+
expected mtime to be within 50 of 1967-03-15 00:16:00.000000000 -0700, but it was 1967-03-15 00:12:40 -0700
3234
MSG
3335
expect(matcher.failure_message).to eq(expected_message)
3436
end
@@ -60,20 +62,19 @@
6062
setup_path = File.join(bin_path, 'setup')
6163
Dir.mkdir(bin_path)
6264
File.write(setup_path, '#!/bin/sh')
63-
FileUtils.chmod(0o755, setup_path)
64-
mock_file_stat(setup_path, uid: 9999, mode: 0o100755)
65-
mock_user_name(9999, 'testuser')
65+
# Mock the mtime to eliminate the potential for a different timezone output in the failure message
66+
mock_file_stat(setup_path, mtime: mocked_now - 1, size: 9)
6667

6768
matcher = be_dir.containing(
68-
file('setup', mode: '0644', owner: 'root')
69+
file('setup', mtime: mocked_now, size: be_zero)
6970
)
7071
matcher.matches?(bin_path)
7172

7273
expected_message = <<~MSG.chomp
7374
#{bin_path} was not as expected:
7475
- setup
75-
expected mode to be "0644", but it was "0755"
76-
expected owner to be "root", but it was "testuser"
76+
expected mtime to be 1967-03-15 00:16:00 -0700, but it was 1967-03-15 00:15:59 -0700
77+
expected size to be zero, but it was 9
7778
MSG
7879
expect(matcher.failure_message).to eq(expected_message)
7980
end
@@ -92,14 +93,11 @@
9293
FileUtils.mkdir_p(lib_dir)
9394
File.write(setup_path, '#!/bin/sh')
9495
File.write(version_path, version_rb_content)
95-
FileUtils.chmod(0o755, setup_path)
96-
97-
mock_file_stat(setup_path, uid: 9999, mode: 0o100755)
98-
mock_user_name(9999, 'owner')
96+
mock_file_stat(setup_path, mtime: mocked_now - 11, size: 9)
9997

10098
matcher = be_dir.containing(
10199
dir('bin').containing(
102-
file('setup', mode: '0644', owner: 'root')
100+
file('setup', mtime: be_within(10).of(mocked_now), size: be_zero)
103101
),
104102
dir('lib').containing(
105103
dir('new_project').containing(
@@ -112,8 +110,8 @@
112110
expected_message = <<~MSG.chomp
113111
#{base_dir} was not as expected:
114112
- bin/setup
115-
expected mode to be "0644", but it was "0755"
116-
expected owner to be "root", but it was "owner"
113+
expected mtime to be within 10 of 1967-03-15 00:16:00.000000000 -0700, but it was 1967-03-15 00:15:49 -0700
114+
expected size to be zero, but it was 9
117115
- lib/new_project/version.rb
118116
expected content to include "VERSION = \\"0.1.1\\"", but it was #{version_rb_content.inspect}
119117
MSG

spec/spec_helper.rb

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
end
2020

2121
# Guard for Unix-specific tests, as Windows does not have the same ownership concepts
22-
UNIX_PLATFORM = RUBY_PLATFORM !~ /cygwin|mswin|mingw|bccwin|wince|emx/
22+
UNIX_LIKE_PLATFORM = RUBY_PLATFORM !~ /cygwin|mswin|mingw|bccwin|wince|emx/
2323

2424
# Helper method to get the current user for ownership tests
2525
def current_user
@@ -66,13 +66,13 @@ def mock_group_name(gid, name)
6666
def mock_file_stat(
6767
path,
6868
atime: mocked_now, birthtime: mocked_now, ctime: mocked_now, mtime: mocked_now,
69-
uid: 9999, gid: 9999, mode: 0o644
69+
uid: 9999, gid: 9999, mode: 0o644, size: 0
7070
)
7171
allow(File).to(
7272
receive(:stat).with(path).and_return(
7373
double(
7474
atime:, birthtime:, ctime:, mtime:,
75-
uid:, gid:, mode:
75+
uid:, gid:, mode:, size:
7676
)
7777
)
7878
)
@@ -102,7 +102,14 @@ def expectation_not_met_error = RSpec::Expectations::ExpectationNotMetError
102102
def ci_build? = ENV.fetch('GITHUB_ACTIONS', 'false') == 'true'
103103

104104
SimpleCov::RSpec.start(list_uncovered_lines: ci_build?) do
105-
minimum_coverage line: 100, branch: 100
105+
minimum_coverage line: 100, branch: 100 if UNIX_LIKE_PLATFORM
106+
107+
add_filter '/spec/'
108+
add_filter '/vendor/'
109+
add_filter '/lib/rspec/path_matchers/version.rb'
110+
add_filter '/lib/rspec/path_matchers/cli.rb'
111+
add_filter '/lib/rspec/path_matchers/cli_options.rb'
112+
add_filter '/lib/rspec/path_matchers/cli_parser.rb'
106113
end
107114

108115
require 'rspec/path_matchers'

0 commit comments

Comments
 (0)