admission 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +37 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/Gemfile +6 -0
- data/LICENSE +674 -0
- data/README.md +2 -0
- data/admission.gemspec +18 -0
- data/bin/rspec +8 -0
- data/lib/admission.rb +9 -0
- data/lib/admission/ability.rb +140 -0
- data/lib/admission/admission.rb +6 -0
- data/lib/admission/arbitration.rb +126 -0
- data/lib/admission/denied.rb +15 -0
- data/lib/admission/privilege.rb +129 -0
- data/lib/admission/rails.rb +94 -0
- data/lib/admission/resource_arbitration.rb +112 -0
- data/lib/admission/status.rb +38 -0
- data/lib/admission/version.rb +3 -0
- data/spec/integration/_helper.rb +2 -0
- data/spec/integration/action_arbitrating_spec.rb +119 -0
- data/spec/integration/resource_arbitrating_spec.rb +246 -0
- data/spec/rspec_config.rb +103 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/test_context/country.rb +24 -0
- data/spec/test_context/index.rb +7 -0
- data/spec/test_context/person.rb +31 -0
- data/spec/test_context/persons_fixtures.rb +43 -0
- data/spec/test_context/privileges_and_rules.rb +114 -0
- data/spec/unit/_helper.rb +1 -0
- data/spec/unit/ability_spec.rb +29 -0
- data/spec/unit/privilege/order_definer_spec.rb +184 -0
- data/spec/unit/privilege_spec.rb +146 -0
- data/spec/unit/request_arbitration_spec.rb +31 -0
- metadata +76 -0
@@ -0,0 +1,103 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# The generated `.rspec` file contains `--require spec_helper` which will cause
|
4
|
+
# this file to always be loaded, without a need to explicitly require it in any
|
5
|
+
# files.
|
6
|
+
#
|
7
|
+
# Given that it is always loaded, you are encouraged to keep this file as
|
8
|
+
# light-weight as possible. Requiring heavyweight dependencies from this file
|
9
|
+
# will add to the boot time of your test suite on EVERY test run, even for an
|
10
|
+
# individual file that may not need all of that loaded. Instead, consider making
|
11
|
+
# a separate helper file that requires the additional dependencies and performs
|
12
|
+
# the additional setup, and require it from the spec files that actually need
|
13
|
+
# it.
|
14
|
+
#
|
15
|
+
# The `.rspec` file also contains a few flags that are not defaults but that
|
16
|
+
# users commonly want.
|
17
|
+
#
|
18
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
19
|
+
RSpec.configure do |config|
|
20
|
+
# rspec-expectations config goes here. You can use an alternate
|
21
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
22
|
+
# assertions if you prefer.
|
23
|
+
config.expect_with :rspec do |expectations|
|
24
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
25
|
+
# and `failure_message` of custom matchers include text for helper methods
|
26
|
+
# defined using `chain`, e.g.:
|
27
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
28
|
+
# # => "be bigger than 2 and smaller than 4"
|
29
|
+
# ...rather than:
|
30
|
+
# # => "be bigger than 2"
|
31
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
32
|
+
end
|
33
|
+
|
34
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
35
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
36
|
+
config.mock_with :rspec do |mocks|
|
37
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
38
|
+
# a real object. This is generally recommended, and will default to
|
39
|
+
# `true` in RSpec 4.
|
40
|
+
mocks.verify_partial_doubles = true
|
41
|
+
end
|
42
|
+
|
43
|
+
# This option will default to `:apply_to_host_groups` in RSpec 4 (and will
|
44
|
+
# have no way to turn it off -- the option exists only for backwards
|
45
|
+
# compatibility in RSpec 3). It causes shared context metadata to be
|
46
|
+
# inherited by the metadata hash of host groups and examples, rather than
|
47
|
+
# triggering implicit auto-inclusion in groups with matching metadata.
|
48
|
+
config.shared_context_metadata_behavior = :apply_to_host_groups
|
49
|
+
|
50
|
+
# The settings below are suggested to provide a good initial experience
|
51
|
+
# with RSpec, but feel free to customize to your heart's content.
|
52
|
+
=begin
|
53
|
+
# This allows you to limit a spec run to individual examples or groups
|
54
|
+
# you care about by tagging them with `:focus` metadata. When nothing
|
55
|
+
# is tagged with `:focus`, all examples get run. RSpec also provides
|
56
|
+
# aliases for `it`, `describe`, and `context` that include `:focus`
|
57
|
+
# metadata: `fit`, `fdescribe` and `fcontext`, respectively.
|
58
|
+
config.filter_run_when_matching :focus
|
59
|
+
|
60
|
+
# Allows RSpec to persist some state between runs in order to support
|
61
|
+
# the `--only-failures` and `--next-failure` CLI options. We recommend
|
62
|
+
# you configure your source control system to ignore this file.
|
63
|
+
config.example_status_persistence_file_path = "spec/examples.txt"
|
64
|
+
|
65
|
+
# Limits the available syntax to the non-monkey patched syntax that is
|
66
|
+
# recommended. For more details, see:
|
67
|
+
# - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
|
68
|
+
# - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
69
|
+
# - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
|
70
|
+
config.disable_monkey_patching!
|
71
|
+
|
72
|
+
# This setting enables warnings. It's recommended, but in some cases may
|
73
|
+
# be too noisy due to issues in dependencies.
|
74
|
+
config.warnings = true
|
75
|
+
|
76
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
77
|
+
# file, and it's useful to allow more verbose output when running an
|
78
|
+
# individual spec file.
|
79
|
+
if config.files_to_run.one?
|
80
|
+
# Use the documentation formatter for detailed output,
|
81
|
+
# unless a formatter has already been configured
|
82
|
+
# (e.g. via a command-line flag).
|
83
|
+
config.default_formatter = 'doc'
|
84
|
+
end
|
85
|
+
|
86
|
+
# Print the 10 slowest examples and example groups at the
|
87
|
+
# end of the spec run, to help surface which specs are running
|
88
|
+
# particularly slow.
|
89
|
+
config.profile_examples = 10
|
90
|
+
|
91
|
+
# Run specs in random order to surface order dependencies. If you find an
|
92
|
+
# order dependency and want to debug it, you can fix the order by providing
|
93
|
+
# the seed, which is printed after each run.
|
94
|
+
# --seed 1234
|
95
|
+
config.order = :random
|
96
|
+
|
97
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
98
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
99
|
+
# test failures related to randomization by passing the same `--seed` value
|
100
|
+
# as the one that triggered the failure.
|
101
|
+
Kernel.srand config.seed
|
102
|
+
=end
|
103
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# COUNTRIES = [
|
2
|
+
# :czech,
|
3
|
+
# :deutschland,
|
4
|
+
# :taiwan,
|
5
|
+
# :russia,
|
6
|
+
# :australia,
|
7
|
+
# :moon
|
8
|
+
# ]
|
9
|
+
#
|
10
|
+
# class << COUNTRIES
|
11
|
+
#
|
12
|
+
# def europe? country
|
13
|
+
# %i[czech deutschland russia].include? country
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# def safe? country
|
17
|
+
# %i[czech deutschland taiwan].include? country
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# def are_you_dispensable? person
|
21
|
+
# not (%i[russia] & person.countries).empty?
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
class Person
|
3
|
+
|
4
|
+
attr_reader :name, :sex, :countries
|
5
|
+
attr_reader :privileges, :rules
|
6
|
+
|
7
|
+
FEMALE = 0
|
8
|
+
MALE = 1
|
9
|
+
APACHE_HELICOPTER = 2
|
10
|
+
|
11
|
+
def initialize name, sex, countries
|
12
|
+
@name = name
|
13
|
+
@sex = sex
|
14
|
+
@countries = countries
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
# privileges per country
|
19
|
+
|
20
|
+
def not_woman?
|
21
|
+
@sex != FEMALE
|
22
|
+
end
|
23
|
+
|
24
|
+
def person
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
# def self.reduce_privileges **per_country
|
29
|
+
# end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
|
2
|
+
fixtures = {
|
3
|
+
|
4
|
+
peasant_girl: [
|
5
|
+
Person::FEMALE,
|
6
|
+
[]
|
7
|
+
],
|
8
|
+
|
9
|
+
napoleon: [
|
10
|
+
Person::MALE,
|
11
|
+
[]
|
12
|
+
# {all: 'harambe'}
|
13
|
+
],
|
14
|
+
|
15
|
+
franz_joseph: [
|
16
|
+
Person::MALE,
|
17
|
+
[:czech, :australia]
|
18
|
+
# {czech: 'supernatural-primordial', taiwan: 'supernatural-god'}
|
19
|
+
]
|
20
|
+
|
21
|
+
}
|
22
|
+
|
23
|
+
privileges_data_reducer = -> (privileges_data) {
|
24
|
+
privileges_data.to_a.reduce [] do |list, per_country_definition|
|
25
|
+
country, privileges_names = per_country_definition
|
26
|
+
raise "bad country #{country}" unless COUNTRIES.include? country
|
27
|
+
privileges_names = [privileges_names] unless privileges_names.is_a? Array
|
28
|
+
|
29
|
+
privileges = privileges_names.map do |name|
|
30
|
+
privilege = Admission::Privilege.get_from_order PRIVILEGES_ORDER, *name.split('-')
|
31
|
+
privilege.dup_with_context country
|
32
|
+
end
|
33
|
+
|
34
|
+
list + privileges
|
35
|
+
end
|
36
|
+
}
|
37
|
+
|
38
|
+
Person::FIXTURES = ->(name) {
|
39
|
+
*attrs, privileges = fixtures[name]
|
40
|
+
person = Person.new name, *attrs
|
41
|
+
person.instance_variable_set :@privileges, privileges_data_reducer.(privileges)
|
42
|
+
person
|
43
|
+
}
|
@@ -0,0 +1,114 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
PRIVILEGES_ORDER = Admission::Privilege.define_order do
|
4
|
+
privilege :vassal, levels: %i[lord]
|
5
|
+
privilege :human, levels: %i[count king]
|
6
|
+
privilege :emperor, inherits: %i[vassal human]
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
ACTIONS_RULES = Admission::Arbitration.define_rules PRIVILEGES_ORDER do
|
11
|
+
|
12
|
+
privilege :human do
|
13
|
+
allow_all{ not_woman? }
|
14
|
+
forbid :raise_taxes
|
15
|
+
forbid :impose_corvee
|
16
|
+
|
17
|
+
forbid :impose_draft
|
18
|
+
forbid :act_as_god
|
19
|
+
end
|
20
|
+
|
21
|
+
privilege :human, :count do
|
22
|
+
allow_all do |country|
|
23
|
+
countries.include? country
|
24
|
+
end
|
25
|
+
allow :impose_corvee do |country|
|
26
|
+
countries.include? country
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
privilege :human, :king do
|
31
|
+
allow_all
|
32
|
+
allow :raise_taxes
|
33
|
+
end
|
34
|
+
|
35
|
+
privilege :vassal, :lord do
|
36
|
+
allow :impose_draft
|
37
|
+
end
|
38
|
+
|
39
|
+
privilege :emperor do
|
40
|
+
allow :act_as_god
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
RESOURCE_RULES = Admission::ResourceArbitration.define_rules PRIVILEGES_ORDER do
|
47
|
+
|
48
|
+
# `allow_all` & inheriting `:forbidden`
|
49
|
+
|
50
|
+
privilege :human do
|
51
|
+
allow_all(:actions){ not_woman? }
|
52
|
+
forbid :actions, :raise_taxes
|
53
|
+
forbid :actions, :impose_corvee
|
54
|
+
|
55
|
+
forbid :actions, :impose_draft
|
56
|
+
forbid :actions, :act_as_god
|
57
|
+
end
|
58
|
+
|
59
|
+
privilege :human, :count do
|
60
|
+
allow_all :actions do |country|
|
61
|
+
countries.include? country
|
62
|
+
end
|
63
|
+
allow :actions, :impose_corvee do |country|
|
64
|
+
countries.include? country
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
privilege :human, :king do
|
69
|
+
allow_all :actions
|
70
|
+
allow :actions, :raise_taxes
|
71
|
+
end
|
72
|
+
|
73
|
+
privilege :vassal, :lord do
|
74
|
+
allow :actions, :impose_draft
|
75
|
+
end
|
76
|
+
|
77
|
+
privilege :emperor do
|
78
|
+
allow :actions, :act_as_god
|
79
|
+
end
|
80
|
+
|
81
|
+
# `allow_resource` scoping & inheritance
|
82
|
+
|
83
|
+
privilege :vassal do
|
84
|
+
|
85
|
+
allow_resource Person, :show do |person, _|
|
86
|
+
raise 'person is nil' unless person
|
87
|
+
self == person
|
88
|
+
end
|
89
|
+
|
90
|
+
allow :persons, :index do |country|
|
91
|
+
countries.include? country
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
privilege :vassal, :lord do
|
97
|
+
|
98
|
+
allow_resource(Person, :show){ true }
|
99
|
+
|
100
|
+
allow_resource Person, %i[index update] do |person, country|
|
101
|
+
allowance = countries.include? country
|
102
|
+
next allowance unless person
|
103
|
+
|
104
|
+
allowance && person.countries.include?(country)
|
105
|
+
end
|
106
|
+
|
107
|
+
allow_resource Person, :destroy do |person, country|
|
108
|
+
person.countries.include?(country) &&
|
109
|
+
person.sex != Person::APACHE_HELICOPTER
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative '../spec_helper'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# require_relative '../spec_helper'
|
2
|
+
# require_relative '../test_context/index'
|
3
|
+
#
|
4
|
+
# RSpec.describe Admission::Ability do
|
5
|
+
#
|
6
|
+
# let(:nobody_ability){ Admission::Ability.new Person::FIXTURES[:nobody] }
|
7
|
+
# let(:haramber_ability){ Admission::Ability.new Person::FIXTURES[:harambe] }
|
8
|
+
#
|
9
|
+
#
|
10
|
+
# describe '#new' do
|
11
|
+
#
|
12
|
+
# it 'creates instance with no privileges' do
|
13
|
+
# expect(nobody_ability.instance_variable_get :@no_privileges).to be
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# it 'creates instance with some privileges' do
|
17
|
+
# expect(haramber_ability.instance_variable_get :@no_privileges).not_to be
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# # describe '#process' do
|
23
|
+
# #
|
24
|
+
# # it '' do
|
25
|
+
# # end
|
26
|
+
# #
|
27
|
+
# # end
|
28
|
+
#
|
29
|
+
# end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
require_relative '../_helper'
|
2
|
+
|
3
|
+
RSpec.describe Admission::Privilege::OrderDefiner do
|
4
|
+
|
5
|
+
def define_privileges &block
|
6
|
+
Admission::Privilege::OrderDefiner.define &block
|
7
|
+
end
|
8
|
+
|
9
|
+
def privilege *args, inherits: nil
|
10
|
+
p = Admission::Privilege.new *args
|
11
|
+
p.inherits_from inherits if inherits
|
12
|
+
p
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:definer){ Admission::Privilege::OrderDefiner.new }
|
16
|
+
|
17
|
+
|
18
|
+
describe '.define' do
|
19
|
+
|
20
|
+
it 'builds empty index' do
|
21
|
+
index = define_privileges{}
|
22
|
+
expect(index).to be_a(Hash)
|
23
|
+
expect(index).to be_empty
|
24
|
+
expect(index).to be_frozen
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'builds single privilege' do
|
28
|
+
index = define_privileges{ privilege :man, levels: %i[commoner count] }
|
29
|
+
expect(index.keys).to eq(%i[man])
|
30
|
+
expect(index[:man].keys).to eq(%i[^ base commoner count])
|
31
|
+
expect(index[:man][:base].inherited).to be_nil
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'builds with inheritance' do
|
35
|
+
index = define_privileges do
|
36
|
+
privilege :man
|
37
|
+
privilege :vassal, levels: %i[lord], inherits: :man
|
38
|
+
end
|
39
|
+
|
40
|
+
# structure
|
41
|
+
expect(index.keys).to eq(%i[man vassal])
|
42
|
+
expect(index[:man].keys).to eq(%i[^ base])
|
43
|
+
expect(index[:vassal].keys).to eq(%i[^ base lord])
|
44
|
+
|
45
|
+
# inheritance
|
46
|
+
expect(index[:man][:base].inherited).to be_nil
|
47
|
+
expect(index[:vassal][:base].inherited).to eql([privilege(:man)])
|
48
|
+
expect(index[:vassal][:lord].inherited).to eql([privilege(:vassal)])
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
describe '#privilege' do
|
55
|
+
|
56
|
+
it 'adds privilege with no levels' do
|
57
|
+
definer.privilege :man
|
58
|
+
expect(definer.definitions.size).to eq(1)
|
59
|
+
expect(definer.definitions[:man][:inherits]).to be_nil
|
60
|
+
expect(definer.definitions[:man][:levels]).to eql([privilege(:man)])
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'adds privilege with no levels by string' do
|
64
|
+
definer.privilege 'man'
|
65
|
+
expect(definer.definitions.size).to eq(1)
|
66
|
+
expect(definer.definitions[:man][:inherits]).to be_nil
|
67
|
+
expect(definer.definitions[:man][:levels]).to eql([privilege(:man)])
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'adds privilege array of levels' do
|
71
|
+
definer.privilege :man, levels: %i[commoner count]
|
72
|
+
expect(definer.definitions.size).to eq(1)
|
73
|
+
expect(definer.definitions[:man][:inherits]).to be_nil
|
74
|
+
expect(definer.definitions[:man][:levels]).to eql([
|
75
|
+
privilege(:man), privilege(:man, :commoner), privilege(:man, :count)
|
76
|
+
])
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'adds privilege that inherits single other' do
|
80
|
+
definer.privilege :vassal, inherits: :man
|
81
|
+
expect(definer.definitions.size).to eq(1)
|
82
|
+
expect(definer.definitions[:vassal][:inherits]).to eq([:man])
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'adds privilege that inherits multiple others' do
|
86
|
+
definer.privilege :vassal, inherits: %i[man woman apache-helicopter]
|
87
|
+
expect(definer.definitions.size).to eq(1)
|
88
|
+
expect(definer.definitions[:vassal][:inherits]).to eq([:man, :woman, :'apache-helicopter'])
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'adds multiple privileges' do
|
92
|
+
definer.privilege :man
|
93
|
+
definer.privilege :vassal
|
94
|
+
expect(definer.definitions.keys).to eq(%i[man vassal])
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
describe '#setup_inheritance' do
|
101
|
+
|
102
|
+
it 'sets inheritance' do
|
103
|
+
definer.privilege :man
|
104
|
+
definer.privilege :vassal, inherits: :man
|
105
|
+
definer.send :setup_inheritance
|
106
|
+
|
107
|
+
vassal = definer.definitions[:vassal]
|
108
|
+
expect(vassal[:levels]).to eql([privilege(:vassal)])
|
109
|
+
expect(vassal[:levels].first.inherited).to eql([privilege(:man)])
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'sets inheritance to top level' do
|
113
|
+
definer.privilege :man, levels: %i[commoner count]
|
114
|
+
definer.privilege :vassal, inherits: :man
|
115
|
+
definer.send :setup_inheritance
|
116
|
+
|
117
|
+
vassal = definer.definitions[:vassal]
|
118
|
+
expect(vassal[:levels]).to eql([privilege(:vassal)])
|
119
|
+
expect(vassal[:levels].first.inherited).to eql([privilege(:man, :count)])
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'sets inheritance throughout levels' do
|
123
|
+
definer.privilege :man
|
124
|
+
definer.privilege :vassal, inherits: :man, levels: %i[lord]
|
125
|
+
definer.send :setup_inheritance
|
126
|
+
|
127
|
+
vassal = definer.definitions[:vassal]
|
128
|
+
expect(vassal[:levels]).to eql([privilege(:vassal), privilege(:vassal, :lord)])
|
129
|
+
expect(vassal[:levels][0].inherited).to eql([privilege(:man)])
|
130
|
+
expect(vassal[:levels][1].inherited).to eql([privilege(:vassal)])
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
describe '#build_index' do
|
137
|
+
|
138
|
+
it 'returns hash with single privileges' do
|
139
|
+
definer.privilege :man
|
140
|
+
index = definer.send :build_index
|
141
|
+
expect(index).to be_a(Hash)
|
142
|
+
expect(index.keys).to eq([:man])
|
143
|
+
|
144
|
+
man = index.values.first
|
145
|
+
expect(man.keys).to eq(%i[^ base])
|
146
|
+
expect(man.values).to eql([privilege(:man), privilege(:man)])
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'builds index for privilege with levels' do
|
150
|
+
definer.privilege :man, levels: %i[commoner count]
|
151
|
+
index = definer.send :build_index
|
152
|
+
expect(index).to be_a(Hash)
|
153
|
+
expect(index.keys).to eq([:man])
|
154
|
+
|
155
|
+
man = index[:man]
|
156
|
+
expect(man.keys).to eq(%i[^ base commoner count])
|
157
|
+
expect(man[:'^']).to eql(privilege :man, :count)
|
158
|
+
expect(man[:base]).to eql(privilege :man)
|
159
|
+
expect(man[:commoner]).to eql(privilege :man, :commoner)
|
160
|
+
expect(man[:count]).to eql(privilege :man, :count)
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'returns hash with more privileges' do
|
164
|
+
definer.privilege :man
|
165
|
+
definer.privilege :vassal, levels: %i[lord]
|
166
|
+
index = definer.send :build_index
|
167
|
+
expect(index).to be_a(Hash)
|
168
|
+
expect(index.keys).to eq([:man, :vassal])
|
169
|
+
|
170
|
+
man = index[:man]
|
171
|
+
expect(man.keys).to eq(%i[^ base])
|
172
|
+
expect(man[:'^']).to eql(privilege :man)
|
173
|
+
expect(man[:base]).to eql(privilege :man)
|
174
|
+
|
175
|
+
vassal = index[:vassal]
|
176
|
+
expect(vassal.keys).to eq(%i[^ base lord])
|
177
|
+
expect(vassal[:'^']).to eql(privilege :vassal, :lord)
|
178
|
+
expect(vassal[:base]).to eql(privilege :vassal)
|
179
|
+
expect(vassal[:lord]).to eql(privilege :vassal, :lord)
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|