File: test_css_cache.rb

package info (click to toggle)
ruby-nokogiri 1.11.1%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 5,576 kB
  • sloc: xml: 28,086; ruby: 18,456; java: 13,067; ansic: 5,138; yacc: 265; sh: 208; makefile: 27
file content (147 lines) | stat: -rw-r--r-- 3,602 bytes parent folder | download
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
require "helper"

class TestCssCacheAccess < Nokogiri::TestCase
  def setup
    super
    @css = "a1 > b2 > c3"
    @parse_result = Nokogiri::CSS.parse(@css)
    @to_xpath_result = @parse_result.map(&:to_xpath)

    Nokogiri::CSS::Parser.clear_cache
    Nokogiri::CSS::Parser.class_eval do
      class << @cache
        alias :old_bracket :[]

        def access_count
          @access_count ||= 0
        end

        def [](key)
          @access_count ||= 0
          @access_count += 1
          old_bracket(key)
        end
      end
    end

    assert Nokogiri::CSS::Parser.cache_on?
  end

  def teardown
    Nokogiri::CSS::Parser.clear_cache(true)
    Nokogiri::CSS::Parser.set_cache true
    super
  end

  [false, true].each do |cache_setting|
    define_method "test_css_cache_#{cache_setting ? "true" : "false"}" do
      Nokogiri::CSS::Parser.set_cache cache_setting

      Nokogiri::CSS.xpath_for(@css)
      Nokogiri::CSS.xpath_for(@css)
      Nokogiri::CSS::Parser.new.xpath_for(@css)
      Nokogiri::CSS::Parser.new.xpath_for(@css)

      if cache_setting
        assert_equal(1, Nokogiri::CSS::Parser.class_eval { @cache.count })
        assert_equal(4, Nokogiri::CSS::Parser.class_eval { @cache.access_count })
      else
        assert_equal(0, Nokogiri::CSS::Parser.class_eval { @cache.count })
        assert_equal(0, Nokogiri::CSS::Parser.class_eval { @cache.access_count })
      end
    end
  end
end

class TestCssCache < Nokogiri::TestCase
  def teardown
    Nokogiri::CSS::Parser.set_cache true
    super
  end

  def test_enabled_cache_is_used
    Nokogiri::CSS::Parser.clear_cache
    Nokogiri::CSS::Parser.set_cache true

    css = ".foo .bar .baz"
    cache = Nokogiri::CSS::Parser.instance_variable_get("@cache")

    assert_nil cache[css]
    Nokogiri::CSS.xpath_for(css)
    assert cache[css]

    cache[css] = "this is an injected value"
    assert_equal "this is an injected value", Nokogiri::CSS.xpath_for(css)
  end

  def test_disabled_cache_is_not_used
    Nokogiri::CSS::Parser.clear_cache
    Nokogiri::CSS::Parser.set_cache false

    css = ".foo .bar .baz"
    cache = Nokogiri::CSS::Parser.instance_variable_get("@cache")

    assert_nil cache[css]
    Nokogiri::CSS.xpath_for(css)
    assert_nil cache[css]
  end

  def test_without_cache_avoids_cache
    Nokogiri::CSS::Parser.clear_cache
    Nokogiri::CSS::Parser.set_cache true

    css = ".foo .bar .baz"
    cache = Nokogiri::CSS::Parser.instance_variable_get("@cache")

    assert_nil cache[css]
    Nokogiri::CSS::Parser.without_cache do
      Nokogiri::CSS.xpath_for(css)
    end
    assert_nil cache[css]
  end

  def test_without_cache_resets_cache_value
    Nokogiri::CSS::Parser.set_cache true

    Nokogiri::CSS::Parser.without_cache do
      assert !Nokogiri::CSS::Parser.cache_on?
    end
    assert Nokogiri::CSS::Parser.cache_on?
  end

  def test_without_cache_resets_cache_value_even_after_exception
    Nokogiri::CSS::Parser.set_cache true

    assert_raises(RuntimeError) do
      Nokogiri::CSS::Parser.without_cache do
        raise RuntimeError
      end
    end
    assert Nokogiri::CSS::Parser.cache_on?
  end

  def test_race_condition
    # https://github.com/sparklemotion/nokogiri/issues/1935
    threads = []

    Nokogiri::CSS::Parser.set_cache true

    threads << Thread.new do
      Nokogiri::CSS::Parser.without_cache do
        sleep 0.02
      end
    end

    threads << Thread.new do
      sleep 0.01

      Nokogiri::CSS::Parser.without_cache do
        sleep 0.02
      end
    end

    threads.each(&:join)

    assert Nokogiri::CSS::Parser.cache_on?
  end
end