File: graph_node_spec.rb

package info (click to toggle)
ruby-semantic-puppet 1.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 292 kB
  • sloc: ruby: 2,898; makefile: 6
file content (151 lines) | stat: -rw-r--r-- 4,369 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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
require 'spec_helper'
require 'semantic_puppet/dependency/graph_node'

describe SemanticPuppet::Dependency::GraphNode do
  let(:klass) do
    Class.new do
      include SemanticPuppet::Dependency::GraphNode

      attr_accessor :name

      def initialize(name, *satisfying)
        @name = name
        @satisfying = satisfying
        @satisfying.each { |x| add_dependency(x.name) }
      end

      # @override
      def satisfies_dependency?(node)
        @satisfying.include?(node)
      end
    end
  end

  def instance(*args)
    name = args.first.name unless args.empty?
    klass.new(name || 'unnamed', *args)
  end

  context 'dependencies' do
    subject { instance() }

    example 'are added by #add_dependency' do
      subject.add_dependency('foo')
      subject.add_dependency('bar')
      subject.add_dependency('baz')
      expect(subject.dependency_names).to match_array %w[ foo bar baz ]
    end

    example 'are maintained in the #dependencies Hash' do
      expect(subject.dependencies).to be_empty
      subject.add_dependency('foo')
      expect(subject.dependencies).to have_key 'foo'
      expect(subject.dependencies).to respond_to :to_a
    end
  end

  describe '#<<' do
    let(:foo) { double('Node', :name => 'foo') }
    let(:bar1) { double('Node', :name => 'bar', :'<=>' => 0) }
    let(:bar2) { double('Node', :name => 'bar', :'<=>' => 0) }
    let(:bar3) { double('Node', :name => 'bar') }
    let(:baz) { double('Node', :name => 'baz') }

    subject { instance(foo, bar1, bar2) }

    it 'appends satisfying nodes to the dependencies' do
      subject << foo << bar1 << bar2
      expect(Array(subject.dependencies['foo'])).to match_array [ foo ]
      expect(Array(subject.dependencies['bar'])).to match_array [ bar1, bar2 ]
    end

    it 'does not append nodes with unknown names' do
      subject << baz
      expect(Array(subject.dependencies['baz'])).to be_empty
    end

    it 'does not append unsatisfying nodes' do
      subject << bar3
      expect(Array(subject.dependencies['bar'])).to be_empty
    end

    it 'sorts once the dependencies for a specific node' do
      expect(subject.dependencies['bar']).to receive(:sort!).once
      subject << [bar1, bar2]
    end

    it 'sorts the dependencies for each addition to the same node' do
      expect(subject.dependencies['bar']).to receive(:sort!).twice
      subject << bar1 << bar2
    end
  end

  describe '#satisfied' do
    let(:foo) { double('Node', :name => 'foo') }
    let(:bar) { double('Node', :name => 'bar') }

    subject { instance(foo, bar) }

    it 'is unsatisfied when no nodes have been appended' do
      expect(subject).to_not be_satisfied
    end

    it 'is unsatisfied when any dependencies are missing' do
      subject << foo
      expect(subject).to_not be_satisfied
    end

    it 'is satisfied when all dependencies are fulfilled' do
      subject << foo << bar
      expect(subject).to be_satisfied
    end
  end

  describe '#populate_children' do
    let(:foo) { double('Node', :name => 'foo') }
    let(:bar1) { double('Node', :name => 'bar', :'<=>' => 0) }
    let(:bar2) { double('Node', :name => 'bar', :'<=>' => 0) }
    let(:baz1) { double('Node', :name => 'baz', :'<=>' => 0) }
    let(:baz2) { double('Node', :name => 'baz', :'<=>' => 0) }
    let(:quxx) { double('Node', :name => 'quxx') }

    subject do
      graph = instance(foo, bar1, bar2, baz1, baz2)
      graph << foo << bar1 << bar2 << baz1 << baz2
    end

    it 'saves all relevant nodes as its children' do
      nodes = [ foo, bar2, baz1, quxx ]
      nodes.each do |node|
        allow(node).to receive(:populate_children)
      end

      subject.populate_children(nodes)

      expected = { 'foo' => foo, 'bar' => bar2, 'baz' => baz1 }
      expect(subject.children).to eql expected
    end

    it 'accepts a graph solution and populates it across all nodes' do
      nodes = [ foo, bar2, baz1 ]
      nodes.each do |node|
        expect(node).to receive(:populate_children).with(nodes)
      end

      subject.populate_children(nodes)
    end
  end

  describe '#<=>' do
    it 'can be compared' do
      a = instance(double('Node', :name => 'a'))
      b = instance(double('Node', :name => 'b'))

      expect(a).to be < b
      expect(b).to be > a
      expect([b, a].sort).to eql [a, b]
      expect([a, b].sort).to eql [a, b]
    end
  end

end