File: path_test.rb

package info (click to toggle)
ruby-bootsnap 1.18.6-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 524 kB
  • sloc: ruby: 3,718; ansic: 756; sh: 14; makefile: 9
file content (129 lines) | stat: -rw-r--r-- 4,948 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# frozen_string_literal: true

require "test_helper"
require "bootsnap/load_path_cache"

module Bootsnap
  module LoadPathCache
    class PathTest < Minitest::Test
      include LoadPathCacheHelper

      def setup
        super
        @cache = Object.new
      end

      def test_stability
        require "time"

        time_file       = Time.method(:rfc2822).source_location[0]
        volatile        = Path.new(__FILE__)
        stable          = Path.new(time_file)
        unknown         = Path.new("/who/knows")
        lib             = Path.new("#{RbConfig::CONFIG['rubylibdir']}/a")
        site            = Path.new("#{RbConfig::CONFIG['sitedir']}/b")
        absolute_prefix = RbConfig::CONFIG["host_os"] =~ /mswin|mingw|cygwin/ ? ENV["SystemDrive"] : ""
        bundler         = Path.new("#{absolute_prefix}/bp/3")

        Bundler.stubs(:bundle_path).returns("#{absolute_prefix}/bp")

        assert(stable.stable?, "The stable path #{stable.path.inspect} was unexpectedly not stable.")
        refute(stable.volatile?, "The stable path #{stable.path.inspect} was unexpectedly volatile.")
        assert(volatile.volatile?, "The volatile path #{volatile.path.inspect} was unexpectedly not volatile.")
        refute(volatile.stable?, "The volatile path #{volatile.path.inspect} was unexpectedly stable.")
        assert(unknown.volatile?, "The unknown path #{unknown.path.inspect} was unexpectedly not volatile.")
        refute(unknown.stable?, "The unknown path #{unknown.path.inspect} was unexpectedly stable.")

        assert(lib.stable?, "The lib path #{lib.path.inspect} was unexpectedly not stable.")
        refute(site.stable?, "The site path #{site.path.inspect} was unexpectedly stable.")
        assert(bundler.stable?, "The bundler path #{bundler.path.inspect} was unexpectedly not stable.")
      end

      def test_non_directory?
        if RbConfig::CONFIG["host_os"] =~ /mswin|mingw|cygwin/
          refute(Path.new("c:/dev").non_directory?)
          refute(Path.new("c:/nope").non_directory?)
          # there isn't a direct analog i could think of
          # assert(Path.new('/dev/null').non_directory?)
          assert(Path.new("#{ENV['WinDir']}/System32/Drivers/Etc/hosts").non_directory?)
        else
          refute(Path.new("/dev").non_directory?)
          refute(Path.new("/nope").non_directory?)
          assert(Path.new("/dev/null").non_directory?)
          assert(Path.new("/etc/hosts").non_directory?)
        end
      end

      def test_volatile_cache_valid_when_mtime_has_not_changed
        with_caching_fixtures do |dir, _a, _a_b, _a_b_c|
          entries, dirs = PathScanner.call(dir)
          path = Path.new(dir) # volatile, since it'll be in /tmp

          @cache.expects(:get).with(path.expanded_path).returns([100, entries, dirs])

          path.entries_and_dirs(@cache)
        end
      end

      def test_volatile_cache_invalid_when_mtime_changed
        with_caching_fixtures do |dir, _a, a_b, _a_b_c|
          entries, dirs = PathScanner.call(dir)
          path = Path.new(dir) # volatile, since it'll be in /tmp

          FileUtils.touch(a_b, mtime: Time.at(101))

          @cache.expects(:get).with(path.expanded_path).returns([100, entries, dirs])
          @cache.expects(:set).with(path.expanded_path, [101, entries, dirs])

          # next read doesn't regen
          @cache.expects(:get).with(path.expanded_path).returns([101, entries, dirs])

          path.entries_and_dirs(@cache)
          path.entries_and_dirs(@cache)
        end
      end

      def test_volatile_cache_generated_when_missing
        with_caching_fixtures do |dir, _a, _a_b, _a_b_c|
          entries, dirs = PathScanner.call(dir)
          path = Path.new(dir) # volatile, since it'll be in /tmp

          @cache.expects(:get).with(path.expanded_path).returns(nil)
          @cache.expects(:set).with(path.expanded_path, [100, entries, dirs])

          path.entries_and_dirs(@cache)
        end
      end

      def test_stable_cache_does_not_notice_when_mtime_changes
        with_caching_fixtures do |dir, _a, a_b, _a_b_c|
          entries, dirs = PathScanner.call(dir)
          path = Path.new(dir) # volatile, since it'll be in /tmp
          path.expects(:stable?).returns(true)

          FileUtils.touch(a_b, mtime: Time.at(101))

          # It's unfortunate that we're stubbing the impl of #fetch here.
          PathScanner.expects(:call).never
          @cache.expects(:get).with(path.expanded_path).returns([100, entries, dirs])

          path.entries_and_dirs(@cache)
        end
      end

      private

      def with_caching_fixtures
        Dir.mktmpdir do |dir|
          a     = "#{dir}/a"
          a_b   = "#{dir}/a/b"
          a_b_c = "#{dir}/a/b/c.rb"
          FileUtils.mkdir_p(a_b)
          [a_b_c, a_b, a, dir].each { |f| FileUtils.touch(f, mtime: Time.at(100)) }

          yield(dir, a, a_b, a_b_c)
        end
      end
    end
  end
end