summaryrefslogtreecommitdiff
path: root/spec/ring_spec.rb
blob: 4c7efbb5478d882fe0ef754338ce30988a6f5519 (plain)
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
# frozen_string_literal: true

describe Pry::Ring do
  let(:ring) { described_class.new(3) }

  describe "#<<" do
    it "adds elements as is when the ring is not full" do
      ring << 1 << 2 << 3
      expect(ring.to_a).to eq([1, 2, 3])
    end

    it "overwrites elements when the ring is full" do
      ring << 1 << 2 << 3 << 4 << 5
      expect(ring.to_a).to eq([3, 4, 5])
    end

    it "keeps duplicate elements" do
      ring << 1 << 1 << 1 << 1
      expect(ring.to_a).to eq([1, 1, 1])
    end
  end

  describe "#[]" do
    context "when the ring is empty" do
      it "returns nil" do
        expect(ring[0]).to be_nil
      end
    end

    context "when the ring is not full" do
      before { ring << 1 << 2 << 3 }

      it "reads elements" do
        expect(ring[0]).to eq(1)
        expect(ring[1]).to eq(2)
        expect(ring[2]).to eq(3)

        expect(ring[-1]).to eq(3)
        expect(ring[-2]).to eq(2)
        expect(ring[-3]).to eq(1)
      end

      it "reads elements via range" do
        expect(ring[1..2]).to eq([2, 3])
        expect(ring[-2..-1]).to eq([2, 3])
      end
    end

    context "when the ring is full" do
      before { ring << 1 << 2 << 3 << 4 << 5 }

      it "reads elements" do
        expect(ring[0]).to eq(3)
        expect(ring[1]).to eq(4)
        expect(ring[2]).to eq(5)

        expect(ring[-1]).to eq(5)
        expect(ring[-2]).to eq(4)
        expect(ring[-3]).to eq(3)
      end

      it "returns the first element when accessed through 0..0" do
        expect(ring[0..0]).to eq([3])
      end

      it "reads elements via inclusive range" do
        expect(ring[1..2]).to eq([4, 5])
        expect(ring[-2..-1]).to eq([4, 5])
        expect(ring[-2..3]).to eq([4, 5])

        expect(ring[0..-1]).to eq([3, 4, 5])

        expect(ring[2..-1]).to eq([5])
        expect(ring[-1..10]).to eq([5])

        expect(ring[-1..0]).to eq([])
        expect(ring[-1..1]).to eq([])
      end

      it "reads elements via exclusive range" do
        expect(ring[1...2]).to eq([4])
        expect(ring[-2...-1]).to eq([4])
        expect(ring[-2...3]).to eq([4, 5])

        expect(ring[0...-1]).to eq([3, 4])

        expect(ring[2...-1]).to eq([])
        expect(ring[-1...10]).to eq([5])

        expect(ring[-1...0]).to eq([])
        expect(ring[-1...1]).to eq([])
      end
    end
  end

  describe "#to_a" do
    it "returns a duplicate of internal buffer" do
      array = ring.to_a
      ring << 1
      expect(array.count).to eq(0)
      expect(ring.count).to eq(1)
    end
  end

  describe "#clear" do
    it "resets ring to initial state" do
      ring << 1
      expect(ring.count).to eq(1)
      expect(ring.to_a).to eq([1])

      ring.clear
      expect(ring.count).to eq(0)
      expect(ring.to_a).to eq([])
    end
  end
end