rspec-path_matchers 0.1.0
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/.commitlintrc.yml +37 -0
- data/.husky/commit-msg +1 -0
- data/.release-please-manifest.json +3 -0
- data/.rspec +3 -0
- data/.rubocop.yml +15 -0
- data/.vscode/settings.json +2 -0
- data/CHANGELOG.md +43 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE.txt +21 -0
- data/README.md +409 -0
- data/Rakefile +73 -0
- data/design.rb +76 -0
- data/lib/rspec/path_matchers/matchers/base.rb +197 -0
- data/lib/rspec/path_matchers/matchers/directory_contents_inspector.rb +57 -0
- data/lib/rspec/path_matchers/matchers/have_directory.rb +126 -0
- data/lib/rspec/path_matchers/matchers/have_file.rb +45 -0
- data/lib/rspec/path_matchers/matchers/have_no_entry.rb +49 -0
- data/lib/rspec/path_matchers/matchers/have_symlink.rb +43 -0
- data/lib/rspec/path_matchers/options/atime.rb +51 -0
- data/lib/rspec/path_matchers/options/birthtime.rb +60 -0
- data/lib/rspec/path_matchers/options/content.rb +59 -0
- data/lib/rspec/path_matchers/options/ctime.rb +51 -0
- data/lib/rspec/path_matchers/options/group.rb +63 -0
- data/lib/rspec/path_matchers/options/json_content.rb +43 -0
- data/lib/rspec/path_matchers/options/mode.rb +51 -0
- data/lib/rspec/path_matchers/options/mtime.rb +51 -0
- data/lib/rspec/path_matchers/options/owner.rb +63 -0
- data/lib/rspec/path_matchers/options/size.rb +51 -0
- data/lib/rspec/path_matchers/options/symlink_atime.rb +51 -0
- data/lib/rspec/path_matchers/options/symlink_birthtime.rb +60 -0
- data/lib/rspec/path_matchers/options/symlink_ctime.rb +51 -0
- data/lib/rspec/path_matchers/options/symlink_group.rb +63 -0
- data/lib/rspec/path_matchers/options/symlink_mtime.rb +51 -0
- data/lib/rspec/path_matchers/options/symlink_owner.rb +63 -0
- data/lib/rspec/path_matchers/options/symlink_target.rb +54 -0
- data/lib/rspec/path_matchers/options/symlink_target_exist.rb +54 -0
- data/lib/rspec/path_matchers/options/symlink_target_type.rb +59 -0
- data/lib/rspec/path_matchers/options/yaml_content.rb +44 -0
- data/lib/rspec/path_matchers/options.rb +33 -0
- data/lib/rspec/path_matchers/version.rb +7 -0
- data/lib/rspec/path_matchers.rb +33 -0
- data/package.json +11 -0
- data/release-please-config.json +36 -0
- metadata +280 -0
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module PathMatchers
|
5
|
+
module Options
|
6
|
+
# atime: <expected>
|
7
|
+
class Atime
|
8
|
+
def self.key = :atime
|
9
|
+
|
10
|
+
def self.description(expected)
|
11
|
+
RSpec::PathMatchers.matcher?(expected) ? expected.description : expected.inspect
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.validate_expected(expected, failure_messages)
|
15
|
+
return if expected == NOT_GIVEN ||
|
16
|
+
expected.is_a?(Time) || expected.is_a?(DateTime) ||
|
17
|
+
RSpec::PathMatchers.matcher?(expected)
|
18
|
+
|
19
|
+
failure_messages <<
|
20
|
+
"expected `#{key}:` to be a Matcher, Time, or DateTime, but was #{expected.inspect}"
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns nil if the expected value matches the actual value
|
24
|
+
# @param path [String] the path of the entry to check
|
25
|
+
# @return [String, nil]
|
26
|
+
#
|
27
|
+
def self.match(path, expected, failure_messages)
|
28
|
+
actual = File.stat(path).atime
|
29
|
+
case expected
|
30
|
+
when Time, DateTime then match_time(actual, expected, failure_messages)
|
31
|
+
else match_matcher(actual, expected, failure_messages)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# private methods
|
36
|
+
|
37
|
+
private_class_method def self.match_time(actual, expected, failure_messages)
|
38
|
+
return if expected.to_time == actual
|
39
|
+
|
40
|
+
failure_messages << "expected #{key} to be #{expected.to_time.inspect}, but was #{actual.inspect}"
|
41
|
+
end
|
42
|
+
|
43
|
+
private_class_method def self.match_matcher(actual, expected, failure_messages)
|
44
|
+
return if expected.matches?(actual)
|
45
|
+
|
46
|
+
failure_messages << "expected #{key} to #{expected.description}, but was #{actual.inspect}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module PathMatchers
|
5
|
+
module Options
|
6
|
+
# birthtime: <expected>
|
7
|
+
class Birthtime
|
8
|
+
def self.key = :birthtime
|
9
|
+
|
10
|
+
def self.description(expected)
|
11
|
+
RSpec::PathMatchers.matcher?(expected) ? expected.description : expected.inspect
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.validate_expected(expected, failure_messages)
|
15
|
+
return if expected == NOT_GIVEN ||
|
16
|
+
expected.is_a?(Time) || expected.is_a?(DateTime) ||
|
17
|
+
RSpec::PathMatchers.matcher?(expected)
|
18
|
+
|
19
|
+
failure_messages <<
|
20
|
+
"expected `#{key}:` to be a Matcher, Time, or DateTime, but was #{expected.inspect}"
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns nil if the expected birthtime matches the actual birthtime
|
24
|
+
# @param path [String] the path of the entry to check
|
25
|
+
# @param expected [Object] the expected value to match against the actual value
|
26
|
+
# @param failure_messages [Array<String>] the array to append failure messages to
|
27
|
+
# @return [Void]
|
28
|
+
#
|
29
|
+
def self.match(path, expected, failure_messages) # rubocop:disable Metrics/MethodLength
|
30
|
+
begin
|
31
|
+
actual = File.stat(path).birthtime
|
32
|
+
rescue NotImplementedError
|
33
|
+
message = "WARNING: #{key} expectations are not supported for #{path} and will be skipped"
|
34
|
+
RSpec.configuration.reporter.message(message)
|
35
|
+
return
|
36
|
+
end
|
37
|
+
|
38
|
+
case expected
|
39
|
+
when Time, DateTime then match_time(actual, expected, failure_messages)
|
40
|
+
else match_matcher(actual, expected, failure_messages)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# private methods
|
45
|
+
|
46
|
+
private_class_method def self.match_time(actual, expected, failure_messages)
|
47
|
+
return if expected.to_time == actual
|
48
|
+
|
49
|
+
failure_messages << "expected #{key} to be #{expected.to_time.inspect}, but was #{actual.inspect}"
|
50
|
+
end
|
51
|
+
|
52
|
+
private_class_method def self.match_matcher(actual, expected, failure_messages)
|
53
|
+
return if expected.matches?(actual)
|
54
|
+
|
55
|
+
failure_messages << "expected #{key} to #{expected.description}, but was #{actual.inspect}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module PathMatchers
|
5
|
+
module Options
|
6
|
+
# content: <expected>
|
7
|
+
class Content
|
8
|
+
def self.key = :content
|
9
|
+
|
10
|
+
def self.description(expected)
|
11
|
+
RSpec::PathMatchers.matcher?(expected) ? expected.description : expected.inspect
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.validate_expected(expected, failure_messages)
|
15
|
+
return if expected == NOT_GIVEN ||
|
16
|
+
expected.is_a?(String) ||
|
17
|
+
expected.is_a?(Regexp) ||
|
18
|
+
RSpec::PathMatchers.matcher?(expected)
|
19
|
+
|
20
|
+
failure_messages <<
|
21
|
+
"expected `#{key}:` to be a String, Regexp, or Matcher, but was #{expected.inspect}"
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns nil if the path matches the expected content
|
25
|
+
# @param path [String] the path of the entry to check
|
26
|
+
# @return [String, nil]
|
27
|
+
#
|
28
|
+
def self.match(path, expected, failure_messages)
|
29
|
+
actual = File.read(path)
|
30
|
+
case expected
|
31
|
+
when String then match_string(actual, expected, failure_messages)
|
32
|
+
when Regexp then match_regexp(actual, expected, failure_messages)
|
33
|
+
else match_matcher(actual, expected, failure_messages)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# private methods
|
38
|
+
|
39
|
+
private_class_method def self.match_string(actual, expected, failure_messages)
|
40
|
+
return if expected == actual
|
41
|
+
|
42
|
+
failure_messages << "expected content to be #{expected.inspect}"
|
43
|
+
end
|
44
|
+
|
45
|
+
private_class_method def self.match_regexp(actual, expected, failure_messages)
|
46
|
+
return if expected.match?(actual)
|
47
|
+
|
48
|
+
failure_messages << "expected content to match #{expected.inspect}"
|
49
|
+
end
|
50
|
+
|
51
|
+
private_class_method def self.match_matcher(actual, expected, failure_messages)
|
52
|
+
return if expected.matches?(actual)
|
53
|
+
|
54
|
+
failure_messages << "expected content to #{expected.description}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module PathMatchers
|
5
|
+
module Options
|
6
|
+
# ctime: <expected>
|
7
|
+
class Ctime
|
8
|
+
def self.key = :ctime
|
9
|
+
|
10
|
+
def self.description(expected)
|
11
|
+
RSpec::PathMatchers.matcher?(expected) ? expected.description : expected.inspect
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.validate_expected(expected, failure_messages)
|
15
|
+
return if expected == NOT_GIVEN ||
|
16
|
+
expected.is_a?(Time) || expected.is_a?(DateTime) ||
|
17
|
+
RSpec::PathMatchers.matcher?(expected)
|
18
|
+
|
19
|
+
failure_messages <<
|
20
|
+
"expected `#{key}:` to be a Matcher, Time, or DateTime, but was #{expected.inspect}"
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns nil if the path matches the expected size
|
24
|
+
# @param path [String] the path of the entry to check
|
25
|
+
# @return [String, nil]
|
26
|
+
#
|
27
|
+
def self.match(path, expected, failure_messages)
|
28
|
+
actual = File.stat(path).ctime
|
29
|
+
case expected
|
30
|
+
when Time, DateTime then match_time(actual, expected, failure_messages)
|
31
|
+
else match_matcher(actual, expected, failure_messages)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# private methods
|
36
|
+
|
37
|
+
private_class_method def self.match_time(actual, expected, failure_messages)
|
38
|
+
return if expected.to_time == actual
|
39
|
+
|
40
|
+
failure_messages << "expected ctime to be #{expected.to_time.inspect}, but was #{actual.inspect}"
|
41
|
+
end
|
42
|
+
|
43
|
+
private_class_method def self.match_matcher(actual, expected, failure_messages)
|
44
|
+
return if expected.matches?(actual)
|
45
|
+
|
46
|
+
failure_messages << "expected ctime to #{expected.description}, but was #{actual.inspect}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module PathMatchers
|
5
|
+
module Options
|
6
|
+
# group: <expected>
|
7
|
+
class Group
|
8
|
+
def self.key = :group
|
9
|
+
|
10
|
+
def self.description(expected)
|
11
|
+
RSpec::PathMatchers.matcher?(expected) ? expected.description : expected.inspect
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.validate_expected(expected, failure_messages)
|
15
|
+
return if expected == NOT_GIVEN ||
|
16
|
+
expected.is_a?(String) ||
|
17
|
+
RSpec::PathMatchers.matcher?(expected)
|
18
|
+
|
19
|
+
failure_messages <<
|
20
|
+
"expected `#{key}:` to be a Matcher or a String, but was #{expected.inspect}"
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns nil if the path is owned by the expected owner
|
24
|
+
# @param path [String] the path of the entry to check
|
25
|
+
# @return [String, nil]
|
26
|
+
#
|
27
|
+
def self.match(path, expected, failure_messages)
|
28
|
+
return if unsupported_platform?
|
29
|
+
|
30
|
+
actual = Etc.getgrgid(File.stat(path).gid).name
|
31
|
+
|
32
|
+
case expected
|
33
|
+
when String then match_string(actual, expected, failure_messages)
|
34
|
+
else match_matcher(actual, expected, failure_messages)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# private methods
|
39
|
+
|
40
|
+
private_class_method def self.unsupported_platform?
|
41
|
+
return false if Etc.respond_to?(:getgrgid)
|
42
|
+
|
43
|
+
# If the platform doesn't support Group checks, warn the user and skip the check
|
44
|
+
message = 'WARNING: Group expectations are not supported on this platform and will be skipped.'
|
45
|
+
RSpec.configuration.reporter.message(message)
|
46
|
+
true
|
47
|
+
end
|
48
|
+
|
49
|
+
private_class_method def self.match_string(actual, expected, failure_messages)
|
50
|
+
return if expected == actual
|
51
|
+
|
52
|
+
failure_messages << "expected group to be #{expected.inspect}, but was #{actual.inspect}"
|
53
|
+
end
|
54
|
+
|
55
|
+
private_class_method def self.match_matcher(actual, expected, failure_messages)
|
56
|
+
return if expected.matches?(actual)
|
57
|
+
|
58
|
+
failure_messages << "expected group to #{expected.description}, but was #{actual.inspect}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module RSpec
|
6
|
+
module PathMatchers
|
7
|
+
module Options
|
8
|
+
# json_content: <expected>
|
9
|
+
class JsonContent
|
10
|
+
def self.key = :json_content
|
11
|
+
|
12
|
+
def self.description(expected)
|
13
|
+
return 'be json content' if expected == true
|
14
|
+
|
15
|
+
expected.description
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.validate_expected(expected, failure_messages)
|
19
|
+
return if expected == NOT_GIVEN ||
|
20
|
+
expected == true ||
|
21
|
+
RSpec::PathMatchers.matcher?(expected)
|
22
|
+
|
23
|
+
failure_messages <<
|
24
|
+
"expected `#{key}:` to be a Matcher or true, but was #{expected.inspect}"
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns nil if the path matches the expected content
|
28
|
+
# @param path [String] the path of the entry to check
|
29
|
+
# @return [String, nil]
|
30
|
+
#
|
31
|
+
def self.match(path, expected, failure_messages)
|
32
|
+
actual = JSON.parse(File.read(path))
|
33
|
+
|
34
|
+
return if expected == true
|
35
|
+
|
36
|
+
failure_messages << "expected JSON content to #{expected.description}" unless expected.matches?(actual)
|
37
|
+
rescue JSON::ParserError => e
|
38
|
+
failure_messages << "expected valid JSON content, but got error: #{e.message}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module PathMatchers
|
5
|
+
module Options
|
6
|
+
# mode: <expected>
|
7
|
+
class Mode
|
8
|
+
def self.key = :mode
|
9
|
+
|
10
|
+
def self.description(expected)
|
11
|
+
RSpec::PathMatchers.matcher?(expected) ? expected.description : expected.inspect
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.validate_expected(expected, failure_messages)
|
15
|
+
return if expected == NOT_GIVEN ||
|
16
|
+
expected.is_a?(String) ||
|
17
|
+
RSpec::PathMatchers.matcher?(expected)
|
18
|
+
|
19
|
+
failure_messages <<
|
20
|
+
"expected `#{key}:` to be a Matcher or a String, but was #{expected.inspect}"
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns nil if the path matches the expected mode
|
24
|
+
# @param path [String] the path of the entry to check
|
25
|
+
# @return [String, nil]
|
26
|
+
#
|
27
|
+
def self.match(path, expected, failure_messages)
|
28
|
+
actual = File.stat(path).mode.to_s(8)[-4..] # Get the last 4 characters of the octal mode
|
29
|
+
case expected
|
30
|
+
when String then match_string(actual, expected, failure_messages)
|
31
|
+
else match_matcher(actual, expected, failure_messages)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# private methods
|
36
|
+
|
37
|
+
private_class_method def self.match_string(actual, expected, failure_messages)
|
38
|
+
return if expected == actual
|
39
|
+
|
40
|
+
failure_messages << "expected mode to be #{expected.inspect}, but was #{actual.inspect}"
|
41
|
+
end
|
42
|
+
|
43
|
+
private_class_method def self.match_matcher(actual, expected, failure_messages)
|
44
|
+
return if expected.matches?(actual)
|
45
|
+
|
46
|
+
failure_messages << "expected mode to #{expected.description}, but was #{actual.inspect}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module PathMatchers
|
5
|
+
module Options
|
6
|
+
# mtime: <expected>
|
7
|
+
class Mtime
|
8
|
+
def self.key = :mtime
|
9
|
+
|
10
|
+
def self.description(expected)
|
11
|
+
RSpec::PathMatchers.matcher?(expected) ? expected.description : expected.inspect
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.validate_expected(expected, failure_messages)
|
15
|
+
return if expected == NOT_GIVEN ||
|
16
|
+
expected.is_a?(Time) || expected.is_a?(DateTime) ||
|
17
|
+
RSpec::PathMatchers.matcher?(expected)
|
18
|
+
|
19
|
+
failure_messages <<
|
20
|
+
"expected `#{key}:` to be a Matcher, Time, or DateTime, but was #{expected.inspect}"
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns nil if the path matches the expected size
|
24
|
+
# @param path [String] the path of the entry to check
|
25
|
+
# @return [String, nil]
|
26
|
+
#
|
27
|
+
def self.match(path, expected, failure_messages)
|
28
|
+
actual = File.stat(path).mtime
|
29
|
+
case expected
|
30
|
+
when Time, DateTime then match_time(actual, expected, failure_messages)
|
31
|
+
else match_matcher(actual, expected, failure_messages)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# private methods
|
36
|
+
|
37
|
+
private_class_method def self.match_time(actual, expected, failure_messages)
|
38
|
+
return if expected.to_time == actual
|
39
|
+
|
40
|
+
failure_messages << "expected mtime to be #{expected.to_time.inspect}, but was #{actual.inspect}"
|
41
|
+
end
|
42
|
+
|
43
|
+
private_class_method def self.match_matcher(actual, expected, failure_messages)
|
44
|
+
return if expected.matches?(actual)
|
45
|
+
|
46
|
+
failure_messages << "expected mtime to #{expected.description}, but was #{actual.inspect}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module PathMatchers
|
5
|
+
module Options
|
6
|
+
# owner: <expected>
|
7
|
+
class Owner
|
8
|
+
def self.key = :owner
|
9
|
+
|
10
|
+
def self.description(expected)
|
11
|
+
RSpec::PathMatchers.matcher?(expected) ? expected.description : expected.inspect
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.validate_expected(expected, failure_messages)
|
15
|
+
return if expected == NOT_GIVEN ||
|
16
|
+
expected.is_a?(String) ||
|
17
|
+
RSpec::PathMatchers.matcher?(expected)
|
18
|
+
|
19
|
+
failure_messages <<
|
20
|
+
"expected `#{key}:` to be a Matcher or a String, but was #{expected.inspect}"
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns nil if the path is owned by the expected owner
|
24
|
+
# @param path [String] the path of the entry to check
|
25
|
+
# @return [String, nil]
|
26
|
+
#
|
27
|
+
def self.match(path, expected, failure_messages)
|
28
|
+
return if unsupported_platform?
|
29
|
+
|
30
|
+
actual = Etc.getpwuid(File.stat(path).uid).name
|
31
|
+
|
32
|
+
case expected
|
33
|
+
when String then match_string(actual, expected, failure_messages)
|
34
|
+
else match_matcher(actual, expected, failure_messages)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# private methods
|
39
|
+
|
40
|
+
private_class_method def self.unsupported_platform?
|
41
|
+
return false if Etc.respond_to?(:getpwuid)
|
42
|
+
|
43
|
+
# If the platform doesn't support ownership, warn the user and skip the check
|
44
|
+
message = 'WARNING: Owner expectations are not supported on this platform and will be skipped.'
|
45
|
+
RSpec.configuration.reporter.message(message)
|
46
|
+
true
|
47
|
+
end
|
48
|
+
|
49
|
+
private_class_method def self.match_string(actual, expected, failure_messages)
|
50
|
+
return if expected == actual
|
51
|
+
|
52
|
+
failure_messages << "expected owner to be #{expected.inspect}, but was #{actual.inspect}"
|
53
|
+
end
|
54
|
+
|
55
|
+
private_class_method def self.match_matcher(actual, expected, failure_messages)
|
56
|
+
return if expected.matches?(actual)
|
57
|
+
|
58
|
+
failure_messages << "expected owner to #{expected.description}, but was #{actual.inspect}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module PathMatchers
|
5
|
+
module Options
|
6
|
+
# size: <expected>
|
7
|
+
class Size
|
8
|
+
def self.key = :size
|
9
|
+
|
10
|
+
def self.description(expected)
|
11
|
+
RSpec::PathMatchers.matcher?(expected) ? expected.description : expected.to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.validate_expected(expected, failure_messages)
|
15
|
+
return if expected == NOT_GIVEN ||
|
16
|
+
expected.is_a?(Integer) ||
|
17
|
+
RSpec::PathMatchers.matcher?(expected)
|
18
|
+
|
19
|
+
failure_messages <<
|
20
|
+
"expected `#{key}:` to be a Matcher or an Integer, but was #{expected.inspect}"
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns nil if the path matches the expected size
|
24
|
+
# @param path [String] the path of the entry to check
|
25
|
+
# @return [String, nil]
|
26
|
+
#
|
27
|
+
def self.match(path, expected, failure_messages)
|
28
|
+
actual = File.size(path)
|
29
|
+
case expected
|
30
|
+
when Integer then match_integer(actual, expected, failure_messages)
|
31
|
+
else match_matcher(actual, expected, failure_messages)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# private methods
|
36
|
+
|
37
|
+
private_class_method def self.match_integer(actual, expected, failure_messages)
|
38
|
+
return if expected == actual
|
39
|
+
|
40
|
+
failure_messages << "expected size to be #{expected.inspect}, but was #{actual.inspect}"
|
41
|
+
end
|
42
|
+
|
43
|
+
private_class_method def self.match_matcher(actual, expected, failure_messages)
|
44
|
+
return if expected.matches?(actual)
|
45
|
+
|
46
|
+
failure_messages << "expected size to #{expected.description}, but was #{actual.inspect}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module PathMatchers
|
5
|
+
module Options
|
6
|
+
# atime: <expected>
|
7
|
+
class SymlinkAtime
|
8
|
+
def self.key = :atime
|
9
|
+
|
10
|
+
def self.description(expected)
|
11
|
+
RSpec::PathMatchers.matcher?(expected) ? expected.description : expected.inspect
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.validate_expected(expected, failure_messages)
|
15
|
+
return if expected == NOT_GIVEN ||
|
16
|
+
expected.is_a?(Time) || expected.is_a?(DateTime) ||
|
17
|
+
RSpec::PathMatchers.matcher?(expected)
|
18
|
+
|
19
|
+
failure_messages <<
|
20
|
+
"expected `#{key}:` to be a Matcher, Time, or DateTime, but was #{expected.inspect}"
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns nil if the expected value matches the actual value
|
24
|
+
# @param path [String] the path of the entry to check
|
25
|
+
# @return [String, nil]
|
26
|
+
#
|
27
|
+
def self.match(path, expected, failure_messages)
|
28
|
+
actual = File.lstat(path).atime
|
29
|
+
case expected
|
30
|
+
when Time, DateTime then match_time(actual, expected, failure_messages)
|
31
|
+
else match_matcher(actual, expected, failure_messages)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# private methods
|
36
|
+
|
37
|
+
private_class_method def self.match_time(actual, expected, failure_messages)
|
38
|
+
return if expected.to_time == actual
|
39
|
+
|
40
|
+
failure_messages << "expected #{key} to be #{expected.to_time.inspect}, but was #{actual.inspect}"
|
41
|
+
end
|
42
|
+
|
43
|
+
private_class_method def self.match_matcher(actual, expected, failure_messages)
|
44
|
+
return if expected.matches?(actual)
|
45
|
+
|
46
|
+
failure_messages << "expected #{key} to #{expected.description}, but was #{actual.inspect}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module PathMatchers
|
5
|
+
module Options
|
6
|
+
# birthtime: <expected>
|
7
|
+
class SymlinkBirthtime
|
8
|
+
def self.key = :birthtime
|
9
|
+
|
10
|
+
def self.description(expected)
|
11
|
+
RSpec::PathMatchers.matcher?(expected) ? expected.description : expected.inspect
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.validate_expected(expected, failure_messages)
|
15
|
+
return if expected == NOT_GIVEN ||
|
16
|
+
expected.is_a?(Time) || expected.is_a?(DateTime) ||
|
17
|
+
RSpec::PathMatchers.matcher?(expected)
|
18
|
+
|
19
|
+
failure_messages <<
|
20
|
+
"expected `#{key}:` to be a Matcher, Time, or DateTime, but was #{expected.inspect}"
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns nil if the expected birthtime matches the actual birthtime
|
24
|
+
# @param path [String] the path of the entry to check
|
25
|
+
# @param expected [Object] the expected value to match against the actual value
|
26
|
+
# @param failure_messages [Array<String>] the array to append failure messages to
|
27
|
+
# @return [Void]
|
28
|
+
#
|
29
|
+
def self.match(path, expected, failure_messages) # rubocop:disable Metrics/MethodLength
|
30
|
+
begin
|
31
|
+
actual = File.lstat(path).birthtime
|
32
|
+
rescue NotImplementedError
|
33
|
+
message = "WARNING: #{key} expectations are not supported for #{path} and will be skipped"
|
34
|
+
RSpec.configuration.reporter.message(message)
|
35
|
+
return
|
36
|
+
end
|
37
|
+
|
38
|
+
case expected
|
39
|
+
when Time, DateTime then match_time(actual, expected, failure_messages)
|
40
|
+
else match_matcher(actual, expected, failure_messages)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# private methods
|
45
|
+
|
46
|
+
private_class_method def self.match_time(actual, expected, failure_messages)
|
47
|
+
return if expected.to_time == actual
|
48
|
+
|
49
|
+
failure_messages << "expected #{key} to be #{expected.to_time.inspect}, but was #{actual.inspect}"
|
50
|
+
end
|
51
|
+
|
52
|
+
private_class_method def self.match_matcher(actual, expected, failure_messages)
|
53
|
+
return if expected.matches?(actual)
|
54
|
+
|
55
|
+
failure_messages << "expected #{key} to #{expected.description}, but was #{actual.inspect}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|