summaryrefslogtreecommitdiffhomepage
path: root/spec/entity_manager_spec.rb
blob: 3e62e28daa0f7eb44d83c3d213e5bc4a8544d075 (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
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
152
153
154
155
156
157
158
# frozen_string_literal: true

require_relative '../lib/felecs'

# class EntitiesTest < Minitest::Test

describe 'Entities' do
  before :all do
    $VERBOSE = nil
    @component_manager ||= FelECS::Components.new('TestEntity', :param1, param2: 'def')
    @component_manager1 ||= FelECS::Components.new('TestEntity1', :param1, param2: 'def')
    @component_manager2 ||= FelECS::Components.new('TestEntity2', :param1, param2: 'def')
  end

  before :each do
    @orig_stderr = $stderr
    $stderr = StringIO.new
    @ent0 = FelECS::Entities.new
    @ent1 = FelECS::Entities.new
    @ent2 = FelECS::Entities.new
    @cmp0 = @component_manager.new
    @cmp1 = @component_manager.new
    @cmp2 = @component_manager.new
  end

  after :each do
    $stderr = @orig_stderr
    FelECS::Entities.reverse_each(&:delete)
    @component_manager.reverse_each(&:delete)
    @component_manager1.reverse_each(&:delete)
    @component_manager2.reverse_each(&:delete)
  end

  it 'can iterate over component groups' do
    cmp_1_1 = @component_manager1.new(param1: 1)
    cmp_1_2 = @component_manager1.new(param1: 1)
    cmp_1_3 = @component_manager1.new(param1: 1)
    cmp_remove = @component_manager2.new
    @ent0.add cmp_1_1, @cmp0, cmp_1_1, @component_manager2.new
    @ent1.add cmp_1_2, @cmp1, cmp_1_2, cmp_remove
    @ent2.add cmp_1_3, @component_manager2.new
    @ent1.remove cmp_remove
    FelECS::Entities.group(@component_manager1, @component_manager2) do |cmp1, _cmp2, _ent|
      cmp1.param1 += 1
    end
    cmp_1_1.param1
    expect(cmp_1_1.param1).to eq(2)
    expect(cmp_1_2.param1).to eq(1)
    expect(cmp_1_3.param1).to eq(2)
  end

  it 'can iterate over a single component in a group' do
    @ent0.add @cmp0
    @ent1.add @cmp1
    @ent2.add @cmp2
    @cmp0.param1 = @cmp1.param1 = @cmp2.param1 = 1
    FelECS::Entities.group(@component_manager) do |cmp, _ent|
      cmp.param1 += 1
    end
    expect(@cmp0.param1).to eq(2)
    expect(@cmp1.param1).to eq(2)
    expect(@cmp2.param1).to eq(2)
  end

  it 'can iterate over no components in a group' do
    @cmp0.param1 = 1
    @ent0.add @cmp0
    FelECS::Entities.group do
      @cmp0.param1 = 0
    end
    expect(@cmp0.param1).to eq(1)
  end

  it 'can get a single component' do
    expect { @ent0.component[@component_manager] }.to raise_error(RuntimeError)
    @ent0.add @cmp0
    expect(@ent0.component[@component_manager]).to eq(@cmp0)
    expect(@ent0.component[@component_manager]).to eq(@ent0.component(@component_manager))
    @ent0.add @cmp1
    @ent0.component[@component_manager]
    $stderr.rewind
    $stderr.string.chomp.should eq("This entity has MANY of this component but you called the method that is intended for having a single of this component type.\nYou may have a bug in your logic.")
    @ent0.components[@component_manager].reverse_each do |component|
      @ent0.remove component
    end
    expect { @ent0.component[@component_manager] }.to raise_error(RuntimeError)
  end

  it 'responds to array methods' do
    expect(FelECS::Entities.respond_to?(:[])).to be true
    expect(FelECS::Entities.respond_to?(:each)).to be true
    FelECS::Entities.each do |entity|
      expect(entity.respond_to?(:components)).to be true
    end
    expect(FelECS::Entities.respond_to?(:filter)).to be true
    expect(FelECS::Entities.respond_to?(:first)).to be true
    expect(FelECS::Entities.respond_to?(:last)).to be true
    expect(FelECS::Entities.respond_to?(:somethingwrong)).to be false
  end

  it 'dont respond to missing methods' do
    expect { FelECS::Entities.somethingwrong }.to raise_error(NoMethodError)
  end

  it 'won\'t add duplicate entities' do
    @ent0.add @cmp0, @cmp0, @cmp1, @cmp1
    expect(@ent0.components[@component_manager].count).to eq(2)
  end

  it 'can be accessed' do
    expect(FelECS::Entities[0].respond_to?(:components)).to eq(true)
    expect(FelECS::Entities[1].respond_to?(:components)).to eq(true)
    expect(FelECS::Entities[2].respond_to?(:components)).to eq(true)
  end

  it 'can have components attached' do
    @ent0.add @cmp0
    expect(@ent0.component[@component_manager]).to eq(@cmp0)

    @ent1.add @cmp1, @cmp2
    expect(@ent1.components[@component_manager].length).to eq(2)
    expect(@ent1.components[@component_manager].include?(@cmp1)).to be true
    expect(@ent1.components[@component_manager].include?(@cmp2)).to be true
  end

  it 'can have components removed' do
    @ent0.add @cmp0
    expect(@ent0.remove(@cmp0)).to be true
    expect(@cmp0.entities.empty?).to be true
    expect(@ent0.components[@component_manager].nil?).to be true
    @ent0.add @cmp0
    @cmp0.delete
    expect(@ent0.components[@component_manager].nil?).to be true
  end

  it 'can have many components added then removed' do
    @ent0.add @cmp0, @cmp1, @cmp2
    @ent1.add @cmp0, @cmp1
    @ent2.add @cmp1, @cmp2
    expect(@ent0.components).to eq({ @component_manager => [@cmp0, @cmp1, @cmp2] })
    expect(@cmp0.entities).to eq([@ent0, @ent1])
    expect(@cmp1.entities).to eq([@ent0, @ent1, @ent2])
    expect(@cmp2.entities).to eq([@ent0, @ent2])
    @ent1.delete
    expect(@cmp0.entities).to eq([@ent0])
    expect(@cmp1.entities).to eq([@ent0, @ent2])
    expect(@cmp2.entities).to eq([@ent0, @ent2])
    @cmp1.delete
    expect(@ent0.components).to eq({ @component_manager => [@cmp0, @cmp2] })
    @component_manager.reverse_each(&:delete)
    expect(@component_manager.length).to eq(0)
    expect(@component_manager.empty?).to be true
    expect(@ent0.components).to eq({})
    expect(@ent2.components).to eq({})
    FelECS::Entities.reverse_each(&:delete)
    expect(FelECS::Entities.empty?).to be true
  end
end