admission 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,11 @@
1
+ require_relative '../lib/admission'
2
+ require_relative 'rspec_config'
3
+
4
+ require 'byebug'
5
+
6
+ def with_bug
7
+ $bug = true
8
+ yield
9
+ ensure
10
+ $bug = false
11
+ end
@@ -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,7 @@
1
+ require_relative '../../lib/admission'
2
+
3
+ require_relative 'country'
4
+ require_relative 'person'
5
+
6
+ require_relative 'privileges_and_rules'
7
+ require_relative 'persons_fixtures'
@@ -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