kindergarten 0.0.5 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.travis.yml +9 -0
- data/Gemfile +17 -2
- data/README.md +1 -1
- data/TODO.md +11 -3
- data/kindergarten.gemspec +5 -4
- data/lib/kindergarten.rb +3 -2
- data/lib/kindergarten/exceptions.rb +36 -1
- data/lib/kindergarten/governesses/head_governess.rb +2 -1
- data/lib/kindergarten/perimeter.rb +27 -27
- data/lib/kindergarten/purpose.rb +41 -0
- data/lib/kindergarten/sandbox.rb +29 -15
- data/lib/kindergarten/version.rb +1 -1
- data/spec/kindergarten/governess_spec.rb +8 -8
- data/spec/kindergarten/perimeter_spec.rb +31 -28
- data/spec/kindergarten/sandbox_spec.rb +38 -4
- data/spec/orm/active_record_spec.rb +30 -30
- data/spec/orm_helper.rb +7 -4
- data/spec/support/dining_perimeter.rb +5 -3
- data/spec/support/drinking_perimeter.rb +11 -9
- data/spec/support/methodless_module.rb +3 -0
- data/spec/support/puppet_perimeter.rb +4 -2
- data/spec/support/purposeless_module.rb +7 -0
- data/spec/support/spec_perimeter.rb +3 -1
- metadata +34 -20
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
source 'https://rubygems.org'
|
|
2
2
|
|
|
3
|
-
#
|
|
4
|
-
|
|
3
|
+
# for travis, use a real gemfile
|
|
4
|
+
gem "cancan", "~> 1.6.8"
|
|
5
|
+
gem "activesupport", "> 3"
|
|
6
|
+
|
|
7
|
+
group :development do
|
|
8
|
+
gem "bundler", "~> 1.2"
|
|
9
|
+
gem "rake"
|
|
10
|
+
gem "rspec", '~> 2.11'
|
|
11
|
+
gem "activerecord", "> 3"
|
|
12
|
+
platforms :jruby do
|
|
13
|
+
gem 'jdbc-mysql'
|
|
14
|
+
gem 'activerecord-jdbcmysql-adapter'
|
|
15
|
+
end
|
|
16
|
+
platforms :ruby do
|
|
17
|
+
gem 'mysql2', :git => "git://github.com/brianmario/mysql2.git"
|
|
18
|
+
end
|
|
19
|
+
end
|
data/README.md
CHANGED
|
@@ -29,7 +29,7 @@ child = User.find(2)
|
|
|
29
29
|
# define a module (perimeter) for the child to play in
|
|
30
30
|
class MyPlayModule < Kindergarten::Perimeter
|
|
31
31
|
# use can-can rules to govern the perimeter
|
|
32
|
-
govern do
|
|
32
|
+
govern do
|
|
33
33
|
can :watch, Television
|
|
34
34
|
cannot :watch, CableTV
|
|
35
35
|
|
data/TODO.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# Kindergarten TODO
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Code
|
|
4
4
|
|
|
5
|
-
*
|
|
6
|
-
|
|
5
|
+
* Further implement ```sandbox.projects.all``` -> ```sandbox.$purpose.$method```
|
|
6
|
+
|
|
7
|
+
## Documentation
|
|
8
|
+
|
|
9
|
+
* Write more YARD docs
|
|
10
|
+
* Provide better insight into governess hierarchy
|
|
11
|
+
|
|
12
|
+
## Wiki
|
|
13
|
+
|
|
14
|
+
* Write some wiki pages based on the presentation
|
data/kindergarten.gemspec
CHANGED
|
@@ -16,10 +16,11 @@ Gem::Specification.new do |gem|
|
|
|
16
16
|
gem.version = Kindergarten::VERSION
|
|
17
17
|
|
|
18
18
|
gem.add_dependency('cancan', ['~> 1.6.8'])
|
|
19
|
-
gem.add_dependency('activesupport', ['
|
|
19
|
+
gem.add_dependency('activesupport', ['> 3'])
|
|
20
20
|
|
|
21
21
|
gem.add_development_dependency('rake')
|
|
22
|
-
gem.add_development_dependency('rspec', ['~> 2.
|
|
23
|
-
gem.add_development_dependency('activerecord', ['
|
|
24
|
-
gem.add_development_dependency('
|
|
22
|
+
gem.add_development_dependency('rspec', ['~> 2.11'])
|
|
23
|
+
gem.add_development_dependency('activerecord', ['> 3'])
|
|
24
|
+
gem.add_development_dependency('mysql2')
|
|
25
|
+
gem.add_development_dependency('jdbc-mysql')
|
|
25
26
|
end
|
data/lib/kindergarten.rb
CHANGED
|
@@ -3,9 +3,10 @@ require 'active_support/core_ext'
|
|
|
3
3
|
|
|
4
4
|
require "kindergarten/version"
|
|
5
5
|
require "kindergarten/sandbox"
|
|
6
|
-
require "kindergarten/
|
|
7
|
-
require "kindergarten/governesses"
|
|
6
|
+
require "kindergarten/purpose"
|
|
8
7
|
require "kindergarten/perimeter"
|
|
8
|
+
require "kindergarten/governesses"
|
|
9
|
+
require "kindergarten/exceptions"
|
|
9
10
|
|
|
10
11
|
module Kindergarten
|
|
11
12
|
class << self
|
|
@@ -12,8 +12,43 @@ module Kindergarten
|
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
class Sandbox
|
|
16
|
+
class NoPurposeError < NoMethodError
|
|
17
|
+
def initialize(purpose, sandbox)
|
|
18
|
+
@purpose = purpose
|
|
19
|
+
@sandbox = sandbox
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def to_s
|
|
23
|
+
"undefined purpose '#{@purpose}' for #{@sandbox}"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
15
28
|
class Perimeter
|
|
16
|
-
|
|
29
|
+
class NoExposedMethods < NoMethodError
|
|
30
|
+
def initialize(perimeter)
|
|
31
|
+
@perimeter = perimeter
|
|
32
|
+
super
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def to_s
|
|
36
|
+
"The module #{@perimeter.name} does not expose any methods."
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
class NoPurpose < ArgumentError
|
|
41
|
+
def initialize(perimeter)
|
|
42
|
+
@perimeter = perimeter
|
|
43
|
+
super
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def to_s
|
|
47
|
+
"The module #{@perimeter.name} does not have a purpose."
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Signals bad sandbox method implementation
|
|
17
52
|
class Unguarded < SecurityError; end
|
|
18
53
|
end
|
|
19
54
|
end
|
|
@@ -4,6 +4,7 @@ module Kindergarten
|
|
|
4
4
|
#
|
|
5
5
|
class HeadGoverness
|
|
6
6
|
include CanCan::Ability
|
|
7
|
+
attr_reader :child
|
|
7
8
|
|
|
8
9
|
def initialize(child)
|
|
9
10
|
@child = child
|
|
@@ -130,7 +131,7 @@ module Kindergarten
|
|
|
130
131
|
untaint = untaint_opts[key]
|
|
131
132
|
next if untaint == :pass
|
|
132
133
|
|
|
133
|
-
match = value.match(untaint)
|
|
134
|
+
match = "#{value}".match(untaint)
|
|
134
135
|
if match.nil?
|
|
135
136
|
scrubbed.delete key
|
|
136
137
|
else
|
|
@@ -5,7 +5,7 @@ module Kindergarten
|
|
|
5
5
|
# class ExamplePerimeter < Kindergarten::Perimeter
|
|
6
6
|
# purpose :books
|
|
7
7
|
#
|
|
8
|
-
# govern do
|
|
8
|
+
# govern do
|
|
9
9
|
# can :read, Book do |book|
|
|
10
10
|
# book.level <= 2
|
|
11
11
|
# end
|
|
@@ -21,13 +21,29 @@ module Kindergarten
|
|
|
21
21
|
#
|
|
22
22
|
class Perimeter
|
|
23
23
|
class << self
|
|
24
|
-
attr_reader :
|
|
24
|
+
attr_reader :exposed_methods, :govern_proc
|
|
25
25
|
|
|
26
|
-
#
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
# Defines a list of sandboxed methods
|
|
27
|
+
#
|
|
28
|
+
# Can be called multiple times to grow the list.
|
|
29
|
+
#
|
|
30
|
+
# @example
|
|
31
|
+
# class BondModule < Kindergarten::Perimeter
|
|
32
|
+
# # ...
|
|
33
|
+
# expose :m, :q
|
|
34
|
+
#
|
|
35
|
+
# # ...
|
|
36
|
+
# expose :enemies
|
|
37
|
+
# end
|
|
38
|
+
#
|
|
39
|
+
# BondModule.exposed_methods
|
|
40
|
+
# => [ :m, :q, :enemies ]
|
|
41
|
+
#
|
|
42
|
+
def expose(*list)
|
|
43
|
+
@exposed_methods ||= []
|
|
44
|
+
@exposed_methods |= list
|
|
30
45
|
end
|
|
46
|
+
alias_method :sandbox, :expose
|
|
31
47
|
|
|
32
48
|
# Instruct the Governess how to govern this perimeter
|
|
33
49
|
def govern(&proc)
|
|
@@ -88,31 +104,15 @@ module Kindergarten
|
|
|
88
104
|
end
|
|
89
105
|
end
|
|
90
106
|
|
|
107
|
+
delegate :scrub, :rinse, :guard, :unguarded,
|
|
108
|
+
:to => :governess
|
|
109
|
+
|
|
91
110
|
# @return [Array] List of sandbox methods
|
|
92
111
|
def sandbox_methods
|
|
93
|
-
self.class.
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
# @see Governess#scrub
|
|
97
|
-
def scrub(*args)
|
|
98
|
-
self.governess.scrub(*args)
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
# @see Governess#rinse
|
|
102
|
-
def rinse(*args)
|
|
103
|
-
self.governess.rinse(*args)
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
# @see Governess#guard
|
|
107
|
-
def guard(action, target)
|
|
108
|
-
self.governess.guard(action, target)
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
# @see Governess#unguarded
|
|
112
|
-
def unguarded(&block)
|
|
113
|
-
self.governess.unguarded(&block)
|
|
112
|
+
self.class.exposed_methods
|
|
114
113
|
end
|
|
115
114
|
|
|
115
|
+
# Perform a block under the watchful eye off the governess
|
|
116
116
|
def governed(method, unguarded=false, &block)
|
|
117
117
|
if unguarded == true
|
|
118
118
|
self.governess.unguarded do
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Kindergarten
|
|
2
|
+
# Keep track of a single purpose
|
|
3
|
+
class Purpose
|
|
4
|
+
attr_reader :name, :methods, :sandbox, :subscriptions
|
|
5
|
+
|
|
6
|
+
def initialize(name, sandbox)
|
|
7
|
+
@name = name
|
|
8
|
+
@sandbox = sandbox
|
|
9
|
+
@methods = {}
|
|
10
|
+
@subscriptions = []
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def add_perimeter(perimeter, instance)
|
|
14
|
+
if perimeter.exposed_methods.blank?
|
|
15
|
+
raise Kindergarten::Perimeter::NoExposedMethods.new(perimeter)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
perimeter.exposed_methods.each do |name|
|
|
19
|
+
if @methods.has_key?(name)
|
|
20
|
+
warn "WARNING: overriding already sandboxed method #{@name}.#{name}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
@methods[name] = instance
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def method_missing(name, *args, &block)
|
|
28
|
+
super
|
|
29
|
+
|
|
30
|
+
rescue NoMethodError => ex
|
|
31
|
+
unless methods.has_key?(name)
|
|
32
|
+
raise ex
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
perimeter = methods[name]
|
|
36
|
+
perimeter.governed(name, sandbox.unguarded?) do
|
|
37
|
+
perimeter.send(name, *args, &block)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
data/lib/kindergarten/sandbox.rb
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
module Kindergarten
|
|
2
2
|
class Sandbox
|
|
3
|
-
attr_reader :child, :governess, :perimeter
|
|
3
|
+
attr_reader :child, :governess, :perimeter, :purpose
|
|
4
4
|
|
|
5
5
|
def initialize(child)
|
|
6
6
|
@child = child
|
|
7
7
|
@governess = Kindergarten::HeadGoverness.new(child)
|
|
8
8
|
|
|
9
|
-
@
|
|
9
|
+
@purpose = {}
|
|
10
|
+
@perimeter = []
|
|
10
11
|
def @perimeter.include?(other)
|
|
11
12
|
(self.collect(&:class) & [ other.class ]).any?
|
|
12
13
|
end
|
|
@@ -25,50 +26,63 @@ module Kindergarten
|
|
|
25
26
|
|
|
26
27
|
perimeter = perimeter_class.new(child, governess)
|
|
27
28
|
|
|
29
|
+
raise ArgumentError.new(
|
|
30
|
+
"Module must inherit from Kindergarten::Perimeter"
|
|
31
|
+
) unless perimeter.kind_of?(Kindergarten::Perimeter)
|
|
32
|
+
|
|
33
|
+
self.extend_purpose(perimeter.class, perimeter)
|
|
34
|
+
|
|
28
35
|
# the head governess must know all the rules
|
|
29
36
|
unless governess == self.governess || perimeter_class.govern_proc.nil?
|
|
30
37
|
self.governess.instance_eval(&perimeter_class.govern_proc)
|
|
31
38
|
end
|
|
32
39
|
|
|
33
|
-
raise ArgumentError.new(
|
|
34
|
-
"Module must inherit from Kindergarten::Perimeter"
|
|
35
|
-
) unless perimeter.kind_of?(Kindergarten::Perimeter)
|
|
36
|
-
|
|
37
40
|
@perimeter << perimeter unless @perimeter.include?(perimeter)
|
|
38
41
|
end
|
|
39
42
|
end
|
|
40
43
|
alias_method :load_perimeter, :extend_perimeter
|
|
41
44
|
alias_method :load_module, :extend_perimeter
|
|
42
45
|
|
|
46
|
+
def extend_purpose(perimeter, instance)
|
|
47
|
+
name = perimeter.purpose || raise(
|
|
48
|
+
Kindergarten::Perimeter::NoPurpose.new(perimeter)
|
|
49
|
+
)
|
|
50
|
+
name = name.to_sym
|
|
51
|
+
|
|
52
|
+
self.purpose[name] ||= Kindergarten::Purpose.new(name, self)
|
|
53
|
+
self.purpose[name].add_perimeter(perimeter, instance)
|
|
54
|
+
end
|
|
55
|
+
|
|
43
56
|
def unguarded(&block)
|
|
44
57
|
@unguarded = true
|
|
45
58
|
yield
|
|
46
59
|
@unguarded = false
|
|
47
60
|
end
|
|
48
61
|
|
|
62
|
+
def unguarded?
|
|
63
|
+
@unguarded == true ? true : false
|
|
64
|
+
end
|
|
65
|
+
|
|
49
66
|
def allows?(action, target)
|
|
50
67
|
governess.can?(action, target)
|
|
51
68
|
end
|
|
52
69
|
alias_method :allowed?, :allows?
|
|
53
|
-
|
|
70
|
+
|
|
54
71
|
def disallows?(action, target)
|
|
55
72
|
governess.cannot?(action, target)
|
|
56
73
|
end
|
|
57
74
|
alias_method :disallowed?, :disallows?
|
|
58
75
|
|
|
76
|
+
# TODO: Find a purpose and call that - move this block to Purpose
|
|
59
77
|
def method_missing(name, *args, &block)
|
|
60
78
|
super
|
|
79
|
+
|
|
61
80
|
rescue NoMethodError => ex
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return perimeter.governed(name, @unguarded) do
|
|
65
|
-
perimeter.send(name, *args, &block)
|
|
66
|
-
end
|
|
67
|
-
end
|
|
81
|
+
unless purpose.has_key?(name)
|
|
82
|
+
raise Kindergarten::Sandbox::NoPurposeError.new(name, self)
|
|
68
83
|
end
|
|
69
84
|
|
|
70
|
-
|
|
71
|
-
raise ex
|
|
85
|
+
return purpose[name]
|
|
72
86
|
end
|
|
73
87
|
end
|
|
74
88
|
end
|
data/lib/kindergarten/version.rb
CHANGED
|
@@ -27,22 +27,22 @@ describe Kindergarten::HeadGoverness do
|
|
|
27
27
|
|
|
28
28
|
describe :washing do
|
|
29
29
|
it "should scrub attributes" do
|
|
30
|
-
attr = { a
|
|
30
|
+
attr = { :a => 1, :b => 2, :c => 3 }
|
|
31
31
|
|
|
32
32
|
scrubbed = @governess.scrub(attr, :a, :c)
|
|
33
33
|
scrubbed.should_not be_has_key(:b)
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
it "should return a ScrubbedHash after scrubbing" do
|
|
37
|
-
attr = { a
|
|
37
|
+
attr = { :a => 1, :b => 2, :c => 3 }
|
|
38
38
|
|
|
39
39
|
scrubbed = @governess.scrub(attr, :a, :c)
|
|
40
40
|
scrubbed.should be_kind_of(Kindergarten::ScrubbedHash)
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
it "should rinse attributes" do
|
|
44
|
-
attr = { a
|
|
45
|
-
rinsed = @governess.rinse(attr, a
|
|
44
|
+
attr = { :a => 1, :b => "2a", :c => 3 }
|
|
45
|
+
rinsed = @governess.rinse(attr, :a => /(\d+)/, :b => /(\D+)/)
|
|
46
46
|
|
|
47
47
|
rinsed.should_not be_has_key(:c)
|
|
48
48
|
rinsed[:a].should eq "1"
|
|
@@ -50,16 +50,16 @@ describe Kindergarten::HeadGoverness do
|
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
it "should pass attributes" do
|
|
53
|
-
attr = { a
|
|
54
|
-
rinsed = @governess.rinse(attr, a
|
|
53
|
+
attr = { :a => "1", :b => "2a", :c => "3" }
|
|
54
|
+
rinsed = @governess.rinse(attr, :a => :pass, :c => :pass)
|
|
55
55
|
|
|
56
56
|
rinsed.should_not be_has_key(:b)
|
|
57
57
|
rinsed[:a].should eq "1"
|
|
58
58
|
rinsed[:c].should eq "3"
|
|
59
59
|
end
|
|
60
60
|
it "should return a RinsedHash after rinsing" do
|
|
61
|
-
attr = { a
|
|
62
|
-
rinsed = @governess.rinse(attr, a
|
|
61
|
+
attr = { :a => "1", :b => "2a", :c => "3" }
|
|
62
|
+
rinsed = @governess.rinse(attr, :a => /(\d+)/, :b => /(\d+)/)
|
|
63
63
|
|
|
64
64
|
rinsed.should be_kind_of(Kindergarten::RinsedHash)
|
|
65
65
|
end
|
|
@@ -2,29 +2,32 @@ require 'spec_helper'
|
|
|
2
2
|
|
|
3
3
|
describe Kindergarten::Perimeter do
|
|
4
4
|
describe :class do
|
|
5
|
-
it "should have a :
|
|
6
|
-
SpecPerimeter.should respond_to(:
|
|
7
|
-
SpecPerimeter.should respond_to(:
|
|
5
|
+
it "should have a :expose method" do
|
|
6
|
+
SpecPerimeter.should respond_to(:expose)
|
|
7
|
+
SpecPerimeter.should respond_to(:exposed_methods)
|
|
8
8
|
end
|
|
9
|
-
it "should return
|
|
10
|
-
SpecPerimeter.
|
|
9
|
+
it "should return exposed methods" do
|
|
10
|
+
SpecPerimeter.exposed_methods.should_not be_empty
|
|
11
11
|
end
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
it "should have a :govern method" do
|
|
14
14
|
SpecPerimeter.should respond_to(:govern)
|
|
15
15
|
SpecPerimeter.should respond_to(:govern_proc)
|
|
16
16
|
end
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
it "should return a govern proc" do
|
|
19
19
|
SpecPerimeter.govern_proc.should be_kind_of(Proc)
|
|
20
20
|
end
|
|
21
|
+
|
|
22
|
+
it "should return a governess"
|
|
23
|
+
it "should return a purpose"
|
|
21
24
|
end
|
|
22
25
|
|
|
23
26
|
describe :instance do
|
|
24
27
|
it "should have an initialize method with 2 arguments" do
|
|
25
28
|
SpecPerimeter.instance.method(:initialize).arity.should == 2
|
|
26
29
|
end
|
|
27
|
-
|
|
30
|
+
|
|
28
31
|
it "should have a :guard method" do
|
|
29
32
|
SpecPerimeter.instance.should respond_to(:guard)
|
|
30
33
|
end
|
|
@@ -45,66 +48,66 @@ describe Kindergarten::Perimeter do
|
|
|
45
48
|
SpecPerimeter.instance.should respond_to(:sandbox_methods)
|
|
46
49
|
end
|
|
47
50
|
end
|
|
48
|
-
|
|
51
|
+
|
|
49
52
|
describe :sandbox do
|
|
50
53
|
before(:each) do
|
|
51
54
|
@sandbox = Kindergarten.sandbox("child")
|
|
52
55
|
@sandbox.extend_perimeter(SpecPerimeter)
|
|
53
56
|
end
|
|
54
|
-
|
|
57
|
+
|
|
55
58
|
it "should have the SpecPerimeter" do
|
|
56
59
|
@sandbox.perimeter.collect(&:class).should include(SpecPerimeter)
|
|
57
60
|
end
|
|
58
|
-
|
|
61
|
+
|
|
59
62
|
it "should fill the governess" do
|
|
60
63
|
@sandbox.governess.should_not be_empty
|
|
61
64
|
end
|
|
62
65
|
|
|
63
66
|
it "should have the sandboxed method" do
|
|
64
|
-
@sandbox.sandboxed.should eq "child"
|
|
67
|
+
@sandbox.testing.sandboxed.should eq "child"
|
|
65
68
|
end
|
|
66
|
-
|
|
69
|
+
|
|
67
70
|
it "should have the guarded method" do
|
|
68
71
|
expect {
|
|
69
|
-
@sandbox.guarded
|
|
72
|
+
@sandbox.testing.guarded
|
|
70
73
|
}.to raise_error(Kindergarten::AccessDenied)
|
|
71
74
|
end
|
|
72
|
-
|
|
75
|
+
|
|
73
76
|
it "should not have the unboxed method" do
|
|
74
77
|
expect {
|
|
75
|
-
@sanbox.unboxed
|
|
78
|
+
@sanbox.testing.unboxed
|
|
76
79
|
}.to raise_error(NoMethodError)
|
|
77
80
|
end
|
|
78
|
-
|
|
81
|
+
|
|
79
82
|
it "should have the not_guarded method" do
|
|
80
|
-
@sandbox.not_guarded.should eq "OK"
|
|
83
|
+
@sandbox.testing.not_guarded.should eq "OK"
|
|
81
84
|
end
|
|
82
|
-
|
|
85
|
+
|
|
83
86
|
it "should have the unsafe method" do
|
|
84
|
-
expect {
|
|
85
|
-
@sandbox.unsafe
|
|
87
|
+
expect {
|
|
88
|
+
@sandbox.testing.unsafe
|
|
86
89
|
}.to raise_error(Kindergarten::Perimeter::Unguarded)
|
|
87
90
|
end
|
|
88
91
|
end
|
|
89
|
-
|
|
92
|
+
|
|
90
93
|
describe :unguarded do
|
|
91
94
|
before(:each) do
|
|
92
95
|
@sandbox = Kindergarten.sandbox("child")
|
|
93
96
|
@sandbox.extend_perimeter(SpecPerimeter)
|
|
94
97
|
end
|
|
95
|
-
|
|
98
|
+
|
|
96
99
|
it "should allow the unsafe method" do
|
|
97
|
-
expect {
|
|
100
|
+
expect {
|
|
98
101
|
@sandbox.unguarded do
|
|
99
|
-
@sandbox.unsafe
|
|
102
|
+
@sandbox.testing.unsafe
|
|
100
103
|
end
|
|
101
104
|
}.to_not raise_error(Kindergarten::Perimeter::Unguarded)
|
|
102
105
|
end
|
|
103
|
-
|
|
106
|
+
|
|
104
107
|
it "should allow the not_guarded method" do
|
|
105
|
-
expect {
|
|
108
|
+
expect {
|
|
106
109
|
@sandbox.unguarded do
|
|
107
|
-
@sandbox.not_guarded
|
|
110
|
+
@sandbox.testing.not_guarded
|
|
108
111
|
end
|
|
109
112
|
}.to_not raise_error(Kindergarten::Perimeter::Unguarded)
|
|
110
113
|
end
|
|
@@ -33,20 +33,54 @@ describe Kindergarten::Sandbox do
|
|
|
33
33
|
sandbox.perimeter.empty?
|
|
34
34
|
}
|
|
35
35
|
end
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
describe :HeadGoverness do
|
|
38
38
|
before(:each) do
|
|
39
39
|
@sandbox = Kindergarten::Sandbox.new(:child)
|
|
40
|
-
@sandbox.extend_perimeter(SpecPerimeter, PuppetPerimeter)
|
|
40
|
+
@sandbox.extend_perimeter(SpecPerimeter, PuppetPerimeter)
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
it "should tell the outside what is allowed" do
|
|
44
44
|
@sandbox.should be_allowed(:view, "string")
|
|
45
45
|
end
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
it "should know the rules accross perimeters" do
|
|
48
|
-
puppet = @sandbox.grab_puppet
|
|
48
|
+
puppet = @sandbox.puppets.grab_puppet
|
|
49
49
|
@sandbox.should be_disallowed(:bbq, puppet)
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
|
+
|
|
53
|
+
describe :Loading do
|
|
54
|
+
before(:each) do
|
|
55
|
+
@sandbox = Kindergarten::Sandbox.new(:child)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "should not load a module that has no sandboxed methods" do
|
|
59
|
+
expect {
|
|
60
|
+
@sandbox.load_module(MethodlessModule)
|
|
61
|
+
}.to raise_error(Kindergarten::Perimeter::NoExposedMethods, /MethodlessModule does not expose any methods/)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "should not load a module that has no purpose" do
|
|
65
|
+
expect {
|
|
66
|
+
@sandbox.load_module(PurposelessModule)
|
|
67
|
+
}.to raise_error(Kindergarten::Perimeter::NoPurpose, /PurposelessModule does not have a purpose/)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
describe :Purpose do
|
|
72
|
+
before(:each) do
|
|
73
|
+
@sandbox = Kindergarten::Sandbox.new(:kid)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "should raise error for wrong purpose" do
|
|
77
|
+
expect {
|
|
78
|
+
@sandbox.empty.something
|
|
79
|
+
}.to raise_error(Kindergarten::Sandbox::NoPurposeError)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "should return a hash of purposes" do
|
|
83
|
+
@sandbox.purpose.should be_kind_of(Hash)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
52
86
|
end
|
|
@@ -10,7 +10,7 @@ class Migration < ActiveRecord::Migration
|
|
|
10
10
|
t.string :street
|
|
11
11
|
t.string :type
|
|
12
12
|
end
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
create_table :restaurants do |t|
|
|
15
15
|
t.string :name
|
|
16
16
|
t.text :description
|
|
@@ -30,7 +30,7 @@ end
|
|
|
30
30
|
|
|
31
31
|
class Restaurant < ActiveRecord::Base
|
|
32
32
|
include Kindergarten::ORM::Governess
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
force_rinsed
|
|
35
35
|
end
|
|
36
36
|
|
|
@@ -41,7 +41,7 @@ describe Kindergarten::ORM::ActiveRecord do
|
|
|
41
41
|
mig.suppress_messages do
|
|
42
42
|
mig.up
|
|
43
43
|
end
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
rescue => ex
|
|
46
46
|
unless ex.message =~ /already exists/
|
|
47
47
|
$stderr.puts "!!! #{ex.class}: #{ex.message}"
|
|
@@ -54,72 +54,72 @@ describe Kindergarten::ORM::ActiveRecord do
|
|
|
54
54
|
@sandbox = Kindergarten.sandbox(:child)
|
|
55
55
|
@sandbox.extend_perimeter(DrinkingPerimeter)
|
|
56
56
|
end
|
|
57
|
-
|
|
57
|
+
|
|
58
58
|
it "should create a bar" do
|
|
59
59
|
bar = nil
|
|
60
60
|
expect {
|
|
61
|
-
bar = @sandbox.create_bar( name
|
|
61
|
+
bar = @sandbox.get_drunk.create_bar( :name => "Foo", :decription => "A bar" )
|
|
62
62
|
}.to_not raise_error
|
|
63
|
-
|
|
63
|
+
|
|
64
64
|
bar.should be_kind_of(Bar)
|
|
65
65
|
end
|
|
66
|
-
|
|
66
|
+
|
|
67
67
|
it "should not create a bar w/o scrubbing" do
|
|
68
68
|
expect {
|
|
69
|
-
@sandbox.create_bar_wo( name
|
|
70
|
-
}.to raise_error(Kindergarten::ORM::Unscrubbed)
|
|
69
|
+
@sandbox.get_drunk.create_bar_wo( :name => "Foo", :decription => "A Bar" )
|
|
70
|
+
}.to raise_error(Kindergarten::ORM::Unscrubbed)
|
|
71
71
|
end
|
|
72
|
-
|
|
72
|
+
|
|
73
73
|
it "should protect the Joint" do
|
|
74
74
|
expect {
|
|
75
|
-
@sandbox.create_joint( name
|
|
76
|
-
}.to raise_error(Kindergarten::ORM::Unscrubbed)
|
|
75
|
+
@sandbox.get_drunk.create_joint( :name => "foo", :decription => "bar" )
|
|
76
|
+
}.to raise_error(Kindergarten::ORM::Unscrubbed)
|
|
77
77
|
end
|
|
78
|
-
|
|
78
|
+
|
|
79
79
|
it "should build a clean joint" do
|
|
80
80
|
expect {
|
|
81
|
-
@sandbox.build_joint(name
|
|
81
|
+
@sandbox.get_drunk.build_joint(:name => "clean")
|
|
82
82
|
}.to_not raise_error(Kindergarten::ORM::Unscrubbed)
|
|
83
83
|
end
|
|
84
|
-
|
|
84
|
+
|
|
85
85
|
it "should not build a dirty joint" do
|
|
86
86
|
expect {
|
|
87
|
-
@sandbox.build_dirty_joint
|
|
87
|
+
@sandbox.get_drunk.build_dirty_joint
|
|
88
88
|
}.to raise_error(Kindergarten::ORM::Unscrubbed)
|
|
89
89
|
end
|
|
90
|
-
|
|
90
|
+
|
|
91
91
|
it "should update a bar" do
|
|
92
|
-
bar = @sandbox.create_bar(name
|
|
92
|
+
bar = @sandbox.get_drunk.create_bar(:name => "Whiskey Inn")
|
|
93
93
|
expect {
|
|
94
|
-
@sandbox.update_bar(bar, name
|
|
94
|
+
@sandbox.get_drunk.update_bar(bar, :name => "Whiskey Out")
|
|
95
95
|
}.to_not raise_error(Kindergarten::ORM::Unscrubbed)
|
|
96
96
|
end
|
|
97
|
-
|
|
97
|
+
|
|
98
98
|
it "should not update a dirty bar" do
|
|
99
|
-
bar = @sandbox.create_bar(name
|
|
99
|
+
bar = @sandbox.get_drunk.create_bar(:name => "Whiskey Inn")
|
|
100
100
|
expect {
|
|
101
|
-
@sandbox.update_bar_dirty(bar, name
|
|
101
|
+
@sandbox.get_drunk.update_bar_dirty(bar, :name => "Whiskey Out")
|
|
102
102
|
}.to raise_error(Kindergarten::ORM::Unscrubbed)
|
|
103
|
-
end
|
|
103
|
+
end
|
|
104
104
|
end
|
|
105
|
-
|
|
105
|
+
|
|
106
106
|
describe :Dining do
|
|
107
107
|
before(:each) do
|
|
108
108
|
@sandbox = Kindergarten.sandbox(:child)
|
|
109
109
|
@sandbox.extend_perimeter(DiningPerimeter)
|
|
110
110
|
end
|
|
111
|
-
|
|
111
|
+
|
|
112
112
|
it "should not create a scrubbed restaurant" do
|
|
113
113
|
expect {
|
|
114
|
-
@sandbox.create_restaurant_scrubbed(name
|
|
114
|
+
@sandbox.eating.create_restaurant_scrubbed(:name => "China Wok")
|
|
115
115
|
}.to raise_error(Kindergarten::ORM::Unscrubbed)
|
|
116
116
|
end
|
|
117
|
-
|
|
117
|
+
|
|
118
118
|
it "should create a rinsed restaurant" do
|
|
119
119
|
expect {
|
|
120
|
-
@sandbox.create_restaurant(name
|
|
120
|
+
@sandbox.eating.create_restaurant(:name => "Lobster Inn")
|
|
121
121
|
}.to_not raise_error(Kindergarten::ORM::Unscrubbed)
|
|
122
122
|
end
|
|
123
123
|
end
|
|
124
|
-
|
|
125
|
-
end
|
|
124
|
+
|
|
125
|
+
end
|
data/spec/orm_helper.rb
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
adapter = RUBY_PLATFORM == 'java' ? 'jdbc/mysql' : 'mysql2'
|
|
2
|
+
require adapter
|
|
3
|
+
|
|
2
4
|
require 'active_record'
|
|
3
5
|
require "kindergarten/orm/governess"
|
|
4
6
|
|
|
@@ -9,7 +11,8 @@ logger.formatter = proc { |severity, datetime, progname, msg|
|
|
|
9
11
|
|
|
10
12
|
ActiveRecord::Base.logger = logger
|
|
11
13
|
ActiveRecord::Base.establish_connection(
|
|
12
|
-
:adapter => '
|
|
13
|
-
:database =>
|
|
14
|
+
:adapter => adapter.gsub('/', ''),
|
|
15
|
+
:database => 'kindergarten_test',
|
|
16
|
+
:username => 'root',
|
|
17
|
+
:encoding => 'utf8'
|
|
14
18
|
)
|
|
15
|
-
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
class DiningPerimeter < Kindergarten::Perimeter
|
|
2
|
+
purpose :eating
|
|
3
|
+
|
|
2
4
|
# should raise Unscrubbed
|
|
3
5
|
def create_restaurant_scrubbed(args)
|
|
4
6
|
Restaurant.create(scrub(args, :name, :description))
|
|
5
7
|
end
|
|
6
|
-
|
|
8
|
+
|
|
7
9
|
# should work
|
|
8
10
|
def create_restaurant(args)
|
|
9
11
|
safe = rinse(args, :name => /([\w\s\-]+)/, :description => :pass)
|
|
10
12
|
Restaurant.create(safe)
|
|
11
13
|
end
|
|
12
|
-
|
|
14
|
+
|
|
13
15
|
sandbox :create_restaurant_scrubbed, :create_restaurant
|
|
14
|
-
end
|
|
16
|
+
end
|
|
@@ -1,39 +1,41 @@
|
|
|
1
1
|
class DrinkingPerimeter < Kindergarten::Perimeter
|
|
2
|
+
purpose :get_drunk
|
|
3
|
+
|
|
2
4
|
# supposed to work
|
|
3
5
|
def create_bar(args)
|
|
4
6
|
Bar.create(scrub(args, :name, :description))
|
|
5
7
|
end
|
|
6
|
-
|
|
8
|
+
|
|
7
9
|
# should raise Unscrubbed
|
|
8
10
|
def create_bar_wo(args)
|
|
9
11
|
Bar.create(args)
|
|
10
12
|
end
|
|
11
|
-
|
|
13
|
+
|
|
12
14
|
# should raise Unscrubbed
|
|
13
15
|
def create_joint(args)
|
|
14
16
|
Joint.create(args)
|
|
15
17
|
end
|
|
16
|
-
|
|
18
|
+
|
|
17
19
|
# should not raise Unscrubbed
|
|
18
20
|
def build_joint(args)
|
|
19
21
|
Joint.new(scrub(args, :name))
|
|
20
22
|
end
|
|
21
|
-
|
|
23
|
+
|
|
22
24
|
# should raise Unscrubbed
|
|
23
25
|
def build_dirty_joint
|
|
24
|
-
Joint.new(name
|
|
26
|
+
Joint.new(:name => "dirty")
|
|
25
27
|
end
|
|
26
|
-
|
|
28
|
+
|
|
27
29
|
# should not raise Unscrubbed
|
|
28
30
|
def update_bar(bar, args)
|
|
29
31
|
bar.update_attributes(scrub(args, :name, :city, :street))
|
|
30
32
|
end
|
|
31
|
-
|
|
33
|
+
|
|
32
34
|
# should raise
|
|
33
35
|
def update_bar_dirty(bar, args)
|
|
34
36
|
bar.update_attributes(args)
|
|
35
37
|
end
|
|
36
|
-
|
|
38
|
+
|
|
37
39
|
sandbox :create_bar, :create_bar_wo, :create_joint, :build_joint,
|
|
38
40
|
:build_dirty_joint, :update_bar, :update_bar_dirty
|
|
39
|
-
end
|
|
41
|
+
end
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
class PuppetPerimeter < Kindergarten::Perimeter
|
|
2
|
+
purpose :puppets
|
|
3
|
+
|
|
2
4
|
class Puppet
|
|
3
5
|
end
|
|
4
6
|
|
|
5
|
-
govern do
|
|
7
|
+
govern do
|
|
6
8
|
can [:play_with,:dress,:nappy_change], Puppet
|
|
7
9
|
cannot [:tear, :bbq], Puppet
|
|
8
10
|
end
|
|
@@ -16,4 +18,4 @@ class PuppetPerimeter < Kindergarten::Perimeter
|
|
|
16
18
|
end
|
|
17
19
|
|
|
18
20
|
sandbox :grab_puppet, :play_puppet
|
|
19
|
-
end
|
|
21
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kindergarten
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,11 +9,11 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2012-10-
|
|
12
|
+
date: 2012-10-29 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: cancan
|
|
16
|
-
requirement: &
|
|
16
|
+
requirement: &24991920 !ruby/object:Gem::Requirement
|
|
17
17
|
none: false
|
|
18
18
|
requirements:
|
|
19
19
|
- - ~>
|
|
@@ -21,21 +21,21 @@ dependencies:
|
|
|
21
21
|
version: 1.6.8
|
|
22
22
|
type: :runtime
|
|
23
23
|
prerelease: false
|
|
24
|
-
version_requirements: *
|
|
24
|
+
version_requirements: *24991920
|
|
25
25
|
- !ruby/object:Gem::Dependency
|
|
26
26
|
name: activesupport
|
|
27
|
-
requirement: &
|
|
27
|
+
requirement: &24991400 !ruby/object:Gem::Requirement
|
|
28
28
|
none: false
|
|
29
29
|
requirements:
|
|
30
|
-
- -
|
|
30
|
+
- - ! '>'
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '3
|
|
32
|
+
version: '3'
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
|
-
version_requirements: *
|
|
35
|
+
version_requirements: *24991400
|
|
36
36
|
- !ruby/object:Gem::Dependency
|
|
37
37
|
name: rake
|
|
38
|
-
requirement: &
|
|
38
|
+
requirement: &24991020 !ruby/object:Gem::Requirement
|
|
39
39
|
none: false
|
|
40
40
|
requirements:
|
|
41
41
|
- - ! '>='
|
|
@@ -43,32 +43,43 @@ dependencies:
|
|
|
43
43
|
version: '0'
|
|
44
44
|
type: :development
|
|
45
45
|
prerelease: false
|
|
46
|
-
version_requirements: *
|
|
46
|
+
version_requirements: *24991020
|
|
47
47
|
- !ruby/object:Gem::Dependency
|
|
48
48
|
name: rspec
|
|
49
|
-
requirement: &
|
|
49
|
+
requirement: &24990460 !ruby/object:Gem::Requirement
|
|
50
50
|
none: false
|
|
51
51
|
requirements:
|
|
52
52
|
- - ~>
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '2.
|
|
54
|
+
version: '2.11'
|
|
55
55
|
type: :development
|
|
56
56
|
prerelease: false
|
|
57
|
-
version_requirements: *
|
|
57
|
+
version_requirements: *24990460
|
|
58
58
|
- !ruby/object:Gem::Dependency
|
|
59
59
|
name: activerecord
|
|
60
|
-
requirement: &
|
|
60
|
+
requirement: &24989940 !ruby/object:Gem::Requirement
|
|
61
61
|
none: false
|
|
62
62
|
requirements:
|
|
63
|
-
- -
|
|
63
|
+
- - ! '>'
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: '3'
|
|
66
|
+
type: :development
|
|
67
|
+
prerelease: false
|
|
68
|
+
version_requirements: *24989940
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: mysql2
|
|
71
|
+
requirement: &24989560 !ruby/object:Gem::Requirement
|
|
72
|
+
none: false
|
|
73
|
+
requirements:
|
|
74
|
+
- - ! '>='
|
|
64
75
|
- !ruby/object:Gem::Version
|
|
65
|
-
version: '
|
|
76
|
+
version: '0'
|
|
66
77
|
type: :development
|
|
67
78
|
prerelease: false
|
|
68
|
-
version_requirements: *
|
|
79
|
+
version_requirements: *24989560
|
|
69
80
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
71
|
-
requirement: &
|
|
81
|
+
name: jdbc-mysql
|
|
82
|
+
requirement: &24989100 !ruby/object:Gem::Requirement
|
|
72
83
|
none: false
|
|
73
84
|
requirements:
|
|
74
85
|
- - ! '>='
|
|
@@ -76,7 +87,7 @@ dependencies:
|
|
|
76
87
|
version: '0'
|
|
77
88
|
type: :development
|
|
78
89
|
prerelease: false
|
|
79
|
-
version_requirements: *
|
|
90
|
+
version_requirements: *24989100
|
|
80
91
|
description: A kindergarten with a perimeter, a governess and a sandbox
|
|
81
92
|
email:
|
|
82
93
|
- hartog@organisedminds.com
|
|
@@ -102,6 +113,7 @@ files:
|
|
|
102
113
|
- lib/kindergarten/orm/active_record.rb
|
|
103
114
|
- lib/kindergarten/orm/governess.rb
|
|
104
115
|
- lib/kindergarten/perimeter.rb
|
|
116
|
+
- lib/kindergarten/purpose.rb
|
|
105
117
|
- lib/kindergarten/sandbox.rb
|
|
106
118
|
- lib/kindergarten/version.rb
|
|
107
119
|
- spec/kindergarten/governess_spec.rb
|
|
@@ -116,7 +128,9 @@ files:
|
|
|
116
128
|
- spec/support/dining_perimeter.rb
|
|
117
129
|
- spec/support/drinking_perimeter.rb
|
|
118
130
|
- spec/support/log/.gitkeep
|
|
131
|
+
- spec/support/methodless_module.rb
|
|
119
132
|
- spec/support/puppet_perimeter.rb
|
|
133
|
+
- spec/support/purposeless_module.rb
|
|
120
134
|
- spec/support/spec_perimeter.rb
|
|
121
135
|
homepage: ''
|
|
122
136
|
licenses: []
|