reality-facets 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitattributes +6 -0
- data/.gitignore +9 -0
- data/.ruby-version +1 -0
- data/.travis.yml +11 -0
- data/CONTRIBUTING.md +26 -0
- data/Gemfile +5 -0
- data/LICENSE +201 -0
- data/README.md +8 -0
- data/Rakefile +18 -0
- data/lib/reality/facets.rb +25 -0
- data/lib/reality/facets/core.rb +19 -0
- data/lib/reality/facets/facet.rb +80 -0
- data/lib/reality/facets/facet_container.rb +143 -0
- data/lib/reality/facets/faceted_model.rb +98 -0
- data/lib/reality/facets/target_manager.rb +143 -0
- data/reality-facets.gemspec +30 -0
- data/test/facets/test_facet.rb +80 -0
- data/test/facets/test_facet_container.rb +64 -0
- data/test/facets/test_faceted_model.rb +267 -0
- data/test/facets/test_target_manager.rb +196 -0
- data/test/helper.rb +27 -0
- metadata +137 -0
@@ -0,0 +1,98 @@
|
|
1
|
+
#
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
|
+
# you may not use this file except in compliance with the License.
|
4
|
+
# You may obtain a copy of the License at
|
5
|
+
#
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
#
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
11
|
+
# See the License for the specific language governing permissions and
|
12
|
+
# limitations under the License.
|
13
|
+
#
|
14
|
+
|
15
|
+
module Reality #nodoc
|
16
|
+
module Facets #nodoc
|
17
|
+
|
18
|
+
# Module that should be mixed into all model objects that have facets.
|
19
|
+
# Implementation should define a method `facet_container` that retrieves
|
20
|
+
# the associated manager.
|
21
|
+
module Faceted
|
22
|
+
|
23
|
+
def facet_enabled?(facet_key)
|
24
|
+
method_name = :"#{facet_key}?"
|
25
|
+
self.respond_to?(method_name) ? self.send(method_name) : false
|
26
|
+
end
|
27
|
+
|
28
|
+
def facet(facet_key)
|
29
|
+
self.send(facet_key)
|
30
|
+
end
|
31
|
+
|
32
|
+
def enabled_facets
|
33
|
+
(@enabled_facets ||= []).dup
|
34
|
+
end
|
35
|
+
|
36
|
+
def enable_facet(key)
|
37
|
+
Facets.error("Facet #{key} already enabled.") if self.facet_enabled?(key)
|
38
|
+
self.activate_facet(key)
|
39
|
+
end
|
40
|
+
|
41
|
+
def enable_facets!(*keys)
|
42
|
+
keys = keys[0] if keys.size == 1 && keys[0].is_a?(Array)
|
43
|
+
keys.flatten.each do |key|
|
44
|
+
enable_facet(key)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def enable_facets(*keys)
|
49
|
+
keys = keys[0] if keys.size == 1 && keys[0].is_a?(Array)
|
50
|
+
keys.flatten.each do |key|
|
51
|
+
self.activate_facet(key) unless self.facet_enabled?(key)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def disable_facet(key)
|
56
|
+
Facets.error("Facet #{key} not enabled.") unless self.facet_enabled?(key)
|
57
|
+
self.deactivate_facet(key)
|
58
|
+
end
|
59
|
+
|
60
|
+
def disable_facets!(*keys)
|
61
|
+
keys = keys[0] if keys.size == 1 && keys[0].is_a?(Array)
|
62
|
+
keys.flatten.each do |key|
|
63
|
+
disable_facet(key)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def disable_facets(*keys)
|
68
|
+
keys = keys[0] if keys.size == 1 && keys[0].is_a?(Array)
|
69
|
+
keys.flatten.each do |key|
|
70
|
+
disable_facet(key) if self.facet_enabled?(key)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def disable_facets_not_in(keys)
|
75
|
+
keys = keys[0] if keys.size == 1 && keys[0].is_a?(Array)
|
76
|
+
(self.enabled_facets - keys).each do |facet_key|
|
77
|
+
self.disable_facet(facet_key) if self.facet_enabled?(facet_key)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
protected
|
82
|
+
|
83
|
+
def extension_point(action)
|
84
|
+
Facets.debug "Facet '#{self}' extension point #{action} started"
|
85
|
+
facet_container.extension_point(self, action)
|
86
|
+
Facets.debug "Facet '#{self}' extension point #{action} completed"
|
87
|
+
end
|
88
|
+
|
89
|
+
def activate_facet(facet_key)
|
90
|
+
facet_container.activate_facet(self, facet_key)
|
91
|
+
end
|
92
|
+
|
93
|
+
def deactivate_facet(facet_key)
|
94
|
+
facet_container.deactivate_facet(self, facet_key)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
#
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
|
+
# you may not use this file except in compliance with the License.
|
4
|
+
# You may obtain a copy of the License at
|
5
|
+
#
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
#
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
11
|
+
# See the License for the specific language governing permissions and
|
12
|
+
# limitations under the License.
|
13
|
+
#
|
14
|
+
|
15
|
+
module Reality #nodoc
|
16
|
+
module Facets #nodoc
|
17
|
+
|
18
|
+
# A descriptor describing a base type in the system model.
|
19
|
+
class Target
|
20
|
+
def initialize(target_manager, model_class, key, container_key, options)
|
21
|
+
@target_manager = target_manager
|
22
|
+
@model_class = model_class
|
23
|
+
@key = key.to_sym
|
24
|
+
@access_method = (options[:access_method] || Reality::Naming.pluralize(@key)).to_sym
|
25
|
+
@inverse_access_method = (options[:inverse_access_method] || @key).to_sym
|
26
|
+
@container_key = container_key.nil? ? nil : container_key.to_sym
|
27
|
+
@extension_module = nil
|
28
|
+
|
29
|
+
if @container_key && !target_manager.target_by_key?(@container_key)
|
30
|
+
raise "Target '#{key}' defines container as '#{@container_key}' but no such target exists."
|
31
|
+
end
|
32
|
+
|
33
|
+
@target_manager.send(:register_target, self)
|
34
|
+
end
|
35
|
+
|
36
|
+
attr_reader :target_manager
|
37
|
+
attr_reader :model_class
|
38
|
+
attr_reader :key
|
39
|
+
attr_reader :container_key
|
40
|
+
attr_reader :access_method
|
41
|
+
attr_reader :inverse_access_method
|
42
|
+
|
43
|
+
def extension_module
|
44
|
+
unless @extension_module
|
45
|
+
outer_module = target_manager.container.facet_definitions
|
46
|
+
module_name = "#{::Reality::Naming.pascal_case(key)}Extension"
|
47
|
+
outer_module.class_eval "module #{module_name}\n end"
|
48
|
+
@extension_module = outer_module.const_get(module_name)
|
49
|
+
@extension_module.send(:include, Faceted)
|
50
|
+
@extension_module.class_eval("def parent; #{self.container_key}; end") if self.container_key
|
51
|
+
@extension_module.class_eval 'def facet_container; @facet_container; end'
|
52
|
+
end
|
53
|
+
@extension_module
|
54
|
+
end
|
55
|
+
|
56
|
+
def apply_extension_to(object)
|
57
|
+
raise "Can not apply extension to model object of type #{object.class} as it is not of expected model type #{model_class.name} for target #{key}" unless object.is_a?(model_class)
|
58
|
+
raise "Attempted to apply extension multiple time to model object of type #{model_class.name} for target #{key}" if object.instance_variable_defined?('@facet_extension_active')
|
59
|
+
object.class.send(:include, extension_module)
|
60
|
+
object.instance_variable_set('@facet_container', target_manager.container)
|
61
|
+
object.instance_variable_set('@facet_extension_active', true)
|
62
|
+
|
63
|
+
if self.container_key
|
64
|
+
container = object.send(self.container_key)
|
65
|
+
container.enabled_facets.each do |facet_key|
|
66
|
+
object.send(:"_enable_facet_#{facet_key}!")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
object
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class TargetManager
|
74
|
+
attr_reader :container
|
75
|
+
|
76
|
+
def initialize(container)
|
77
|
+
@container = container
|
78
|
+
end
|
79
|
+
|
80
|
+
def is_target_valid?(key)
|
81
|
+
target_map.keys.include?(key)
|
82
|
+
end
|
83
|
+
|
84
|
+
def target_keys
|
85
|
+
target_map.keys
|
86
|
+
end
|
87
|
+
|
88
|
+
def targets
|
89
|
+
target_map.values
|
90
|
+
end
|
91
|
+
|
92
|
+
def target_by_key?(key)
|
93
|
+
!!target_map[key]
|
94
|
+
end
|
95
|
+
|
96
|
+
def target_by_key(key)
|
97
|
+
target = target_map[key.to_sym]
|
98
|
+
raise "Can not find target with key '#{key}'" unless target
|
99
|
+
target
|
100
|
+
end
|
101
|
+
|
102
|
+
def target_by_model_class(model_class)
|
103
|
+
target_map.each do |key, target|
|
104
|
+
return target if target.model_class == model_class
|
105
|
+
end
|
106
|
+
raise "Can not find target with model class '#{model_class.name}'"
|
107
|
+
end
|
108
|
+
|
109
|
+
def apply_extension(model)
|
110
|
+
self.target_by_model_class(model.class).apply_extension_to(model)
|
111
|
+
end
|
112
|
+
|
113
|
+
def target(model_class, key, container_key = nil, options = {})
|
114
|
+
Target.new(self, model_class, key, container_key, options)
|
115
|
+
end
|
116
|
+
|
117
|
+
def targets_by_container(container_key)
|
118
|
+
target_map.values.select { |target| target.container_key == container_key }
|
119
|
+
end
|
120
|
+
|
121
|
+
def lock_targets
|
122
|
+
@targets_locked = true
|
123
|
+
end
|
124
|
+
|
125
|
+
def reset_targets
|
126
|
+
target_map.clear
|
127
|
+
@targets_locked = false
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
|
132
|
+
def register_target(target)
|
133
|
+
raise "Attempting to define target #{target.key} when targets have been locked." if (@targets_locked ||= false)
|
134
|
+
raise "Attempting to redefine target #{target.key}" if target_map[target.key]
|
135
|
+
target_map[target.key] = target
|
136
|
+
end
|
137
|
+
|
138
|
+
def target_map
|
139
|
+
@target_map ||= Reality::OrderedHash.new
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{reality-facets}
|
5
|
+
s.version = '1.0.0'
|
6
|
+
s.platform = Gem::Platform::RUBY
|
7
|
+
|
8
|
+
s.authors = ['Peter Donald']
|
9
|
+
s.email = %q{peter@realityforge.org}
|
10
|
+
|
11
|
+
s.homepage = %q{https://github.com/realityforge/reality-facets}
|
12
|
+
s.summary = %q{A basic toolkit for binding facets or extensions to model objects.}
|
13
|
+
s.description = %q{A basic toolkit for binding facets or extensions to model objects.}
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {spec}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
18
|
+
s.default_executable = []
|
19
|
+
s.require_paths = %w(lib)
|
20
|
+
|
21
|
+
s.has_rdoc = false
|
22
|
+
s.rdoc_options = %w(--line-numbers --inline-source --title reality-facets)
|
23
|
+
|
24
|
+
s.add_dependency 'reality-core', '= 1.4.0'
|
25
|
+
s.add_dependency 'reality-naming', '= 1.4.0'
|
26
|
+
s.add_dependency 'reality-orderedhash', '= 1.0.0'
|
27
|
+
|
28
|
+
s.add_development_dependency(%q<minitest>, ['= 5.9.1'])
|
29
|
+
s.add_development_dependency(%q<test-unit>, ['= 3.1.5'])
|
30
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require File.expand_path('../../helper', __FILE__)
|
2
|
+
|
3
|
+
class Reality::Facets::TestFacet < Reality::TestCase
|
4
|
+
class Component < Reality.base_element(:name => true, :container_key => :project, :pre_config_code => 'Reality::TestCase::TestFacetContainer.target_manager.apply_extension(self)')
|
5
|
+
end
|
6
|
+
|
7
|
+
class Project < Reality.base_element(:name => true, :pre_config_code => 'Reality::TestCase::TestFacetContainer.target_manager.apply_extension(self)')
|
8
|
+
def component(name, options = {}, &block)
|
9
|
+
component_map[name.to_s] = Component.new(self, name, options, &block)
|
10
|
+
end
|
11
|
+
|
12
|
+
def comps
|
13
|
+
component_map.values
|
14
|
+
end
|
15
|
+
|
16
|
+
def component_map
|
17
|
+
@component_map ||= {}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_basic_operation
|
22
|
+
|
23
|
+
assert_equal false, TestFacetContainer.facet_by_name?(:gwt)
|
24
|
+
assert_equal false, TestFacetContainer.facet_by_name?(:gwt_rpc)
|
25
|
+
assert_equal false, TestFacetContainer.facet_by_name?(:imit)
|
26
|
+
|
27
|
+
TestFacetContainer.target_manager.target(Project, :project)
|
28
|
+
TestFacetContainer.target_manager.target(Component,
|
29
|
+
:component,
|
30
|
+
:project,
|
31
|
+
:access_method => :comps,
|
32
|
+
:inverse_access_method => :comp)
|
33
|
+
|
34
|
+
Reality::Facets::Facet.new(TestFacetContainer, :gwt)
|
35
|
+
Reality::Facets::Facet.new(TestFacetContainer, :gwt_rpc, :required_facets => [:gwt])
|
36
|
+
|
37
|
+
Reality::Facets::Facet.new(TestFacetContainer, :imit, :suggested_facets => [:gwt_rpc]) do |f|
|
38
|
+
f.enhance(Project) do
|
39
|
+
def name
|
40
|
+
"Gwt#{project.name}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
f.enhance(Component)
|
44
|
+
end
|
45
|
+
|
46
|
+
assert_equal true, TestFacetContainer.facet_by_name?(:gwt)
|
47
|
+
assert_equal true, TestFacetContainer.facet_by_name?(:gwt_rpc)
|
48
|
+
assert_equal true, TestFacetContainer.facet_by_name?(:imit)
|
49
|
+
|
50
|
+
project = Project.new(:MyProject) do |p|
|
51
|
+
p.enable_facets(:imit)
|
52
|
+
p.component(:MyComponent)
|
53
|
+
end
|
54
|
+
component = project.comps[0]
|
55
|
+
|
56
|
+
assert_equal true, project.gwt?
|
57
|
+
assert_equal false, project.respond_to?(:gwt)
|
58
|
+
assert_equal false, project.respond_to?(:facet_gwt)
|
59
|
+
assert_equal true, project.gwt_rpc?
|
60
|
+
assert_equal false, project.respond_to?(:gwt_rpc)
|
61
|
+
assert_equal false, project.respond_to?(:facet_gwt_rpc)
|
62
|
+
assert_equal true, project.imit?
|
63
|
+
assert_equal true, project.respond_to?(:imit)
|
64
|
+
assert_equal true, project.respond_to?(:facet_imit)
|
65
|
+
assert_equal 'GwtMyProject', project.imit.name
|
66
|
+
|
67
|
+
# These methods all test that FacetModule has been mixed in.
|
68
|
+
assert_equal 'GwtMyProject', project.facet(:imit).name
|
69
|
+
assert_equal true, project.facet_enabled?(:imit)
|
70
|
+
|
71
|
+
assert_equal [:gwt, :gwt_rpc, :imit], project.enabled_facets
|
72
|
+
assert_equal [:gwt, :gwt_rpc, :imit], component.enabled_facets
|
73
|
+
|
74
|
+
# Ensure there is a link back to the container using inverse_access_method
|
75
|
+
assert_equal project, project.imit.project
|
76
|
+
assert_equal project, project.imit.parent
|
77
|
+
assert_equal component, component.imit.comp
|
78
|
+
assert_equal component, component.imit.parent
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require File.expand_path('../../helper', __FILE__)
|
2
|
+
|
3
|
+
class Reality::Facets::TestFacetContainer < Reality::TestCase
|
4
|
+
class Component < Reality.base_element(:name => true)
|
5
|
+
end
|
6
|
+
|
7
|
+
class Component2 < Reality.base_element(:name => true)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_basic_operation
|
11
|
+
|
12
|
+
assert_equal false, TestFacetContainer.facet_by_name?(:gwt)
|
13
|
+
assert_equal false, TestFacetContainer.facet?(:gwt)
|
14
|
+
assert_equal false, TestFacetContainer.facet_by_name?(:gwt_rpc)
|
15
|
+
assert_equal false, TestFacetContainer.facet?(:gwt_rpc)
|
16
|
+
assert_equal [], TestFacetContainer.facet_keys
|
17
|
+
assert_equal 0, TestFacetContainer.facets.size
|
18
|
+
|
19
|
+
assert_raise_message("Unknown facet 'gwt'") { TestFacetContainer.facet_by_name(:gwt) }
|
20
|
+
assert_raise_message("Unknown facet 'gwt_rpc'") { TestFacetContainer.facet_by_name(:gwt_rpc) }
|
21
|
+
|
22
|
+
# Make sure we can add targets
|
23
|
+
TestFacetContainer.target_manager.target(Component, :component)
|
24
|
+
|
25
|
+
TestFacetContainer.facet(:gwt)
|
26
|
+
|
27
|
+
# targets should be locked after first facet defined
|
28
|
+
assert_raise_message('Attempting to define target component when targets have been locked.') do
|
29
|
+
TestFacetContainer.target_manager.target(Component, :component)
|
30
|
+
end
|
31
|
+
|
32
|
+
assert_equal true, TestFacetContainer.facet_by_name?(:gwt)
|
33
|
+
assert_equal true, TestFacetContainer.facet?(:gwt)
|
34
|
+
assert_equal false, TestFacetContainer.facet_by_name?(:gwt_rpc)
|
35
|
+
assert_equal false, TestFacetContainer.facet?(:gwt_rpc)
|
36
|
+
assert_equal %w(gwt), TestFacetContainer.facet_keys
|
37
|
+
assert_equal 1, TestFacetContainer.facets.size
|
38
|
+
|
39
|
+
assert_raise_message("Unknown facet 'gwt_rpc'") { TestFacetContainer.facet_by_name(:gwt_rpc) }
|
40
|
+
|
41
|
+
assert_equal TestFacetContainer, TestFacetContainer.facet_by_name(:gwt).facet_container
|
42
|
+
assert_equal :gwt, TestFacetContainer.facet_by_name(:gwt).key
|
43
|
+
assert_equal [], TestFacetContainer.facet_by_name(:gwt).required_facets
|
44
|
+
assert_equal [], TestFacetContainer.facet_by_name(:gwt).suggested_facets
|
45
|
+
|
46
|
+
TestFacetContainer.facet(:gwt_rpc => [:gwt])
|
47
|
+
|
48
|
+
assert_equal true, TestFacetContainer.facet_by_name?(:gwt)
|
49
|
+
assert_equal true, TestFacetContainer.facet?(:gwt)
|
50
|
+
assert_equal true, TestFacetContainer.facet_by_name?(:gwt_rpc)
|
51
|
+
assert_equal true, TestFacetContainer.facet?(:gwt_rpc)
|
52
|
+
assert_equal %w(gwt gwt_rpc), TestFacetContainer.facet_keys
|
53
|
+
assert_equal 2, TestFacetContainer.facets.size
|
54
|
+
|
55
|
+
assert_equal TestFacetContainer, TestFacetContainer.facet_by_name(:gwt_rpc).facet_container
|
56
|
+
assert_equal :gwt_rpc, TestFacetContainer.facet_by_name(:gwt_rpc).key
|
57
|
+
assert_equal [:gwt], TestFacetContainer.facet_by_name(:gwt_rpc).required_facets
|
58
|
+
assert_equal [], TestFacetContainer.facet_by_name(:gwt_rpc).suggested_facets
|
59
|
+
|
60
|
+
assert_raise_message('Attempting to redefine facet gwt') { TestFacetContainer.facet(:gwt) }
|
61
|
+
|
62
|
+
assert_raise_message("Unknown definition form '{:x=>:y, :z=>1}'") { TestFacetContainer.facet(:x => :y, :z => 1) }
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,267 @@
|
|
1
|
+
require File.expand_path('../../helper', __FILE__)
|
2
|
+
|
3
|
+
class Reality::Facets::TestFacetedModel < Reality::TestCase
|
4
|
+
class Attribute < Reality.base_element(:name => true, :container_key => :entity)
|
5
|
+
def qualified_name
|
6
|
+
"#{entity.qualified_name}.#{name}"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Entity < Reality.base_element(:name => true, :container_key => :repository)
|
11
|
+
def qualified_name
|
12
|
+
"#{repository.name}.#{name}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def attribute(name, options = {}, &block)
|
16
|
+
attribute_map[name.to_s] = Attribute.new(self, name, options, &block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def attributes
|
20
|
+
attribute_map.values
|
21
|
+
end
|
22
|
+
|
23
|
+
def attribute_map
|
24
|
+
@attribute_map ||= {}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Repository < Reality.base_element(:name => true)
|
29
|
+
def entity(name, options = {}, &block)
|
30
|
+
entity_map[name.to_s] = Entity.new(self, name, options, &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def entities
|
34
|
+
entity_map.values
|
35
|
+
end
|
36
|
+
|
37
|
+
def entity_map
|
38
|
+
@entity_map ||= {}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_activation
|
43
|
+
TestFacetContainer.target_manager.target(Repository, :repository)
|
44
|
+
TestFacetContainer.target_manager.target(Entity, :entity, :repository)
|
45
|
+
TestFacetContainer.target_manager.target(Attribute, :attribute, :entity)
|
46
|
+
|
47
|
+
TestFacetContainer.facet(:json)
|
48
|
+
TestFacetContainer.facet(:jpa)
|
49
|
+
TestFacetContainer.facet(:gwt)
|
50
|
+
TestFacetContainer.facet(:gwt_rpc => [:gwt])
|
51
|
+
TestFacetContainer.facet(:imit => [:gwt_rpc]) do |f|
|
52
|
+
f.suggested_facets << :jpa
|
53
|
+
end
|
54
|
+
|
55
|
+
assert_equal 5, TestFacetContainer.facets.size
|
56
|
+
|
57
|
+
repository = Repository.new(:MyRepo) do |r|
|
58
|
+
TestFacetContainer.target_manager.apply_extension(r)
|
59
|
+
|
60
|
+
r.enable_facet(:json)
|
61
|
+
|
62
|
+
r.entity(:MyEntityA) do |e|
|
63
|
+
TestFacetContainer.target_manager.apply_extension(e)
|
64
|
+
e.attribute(:MyAttr1) do |a|
|
65
|
+
TestFacetContainer.target_manager.apply_extension(a)
|
66
|
+
end
|
67
|
+
e.disable_facet(:json)
|
68
|
+
e.attribute(:MyAttr2) do |a|
|
69
|
+
TestFacetContainer.target_manager.apply_extension(a)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
r.entity(:MyEntityB) do |e|
|
74
|
+
TestFacetContainer.target_manager.apply_extension(e)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
entity1 = repository.entities[0]
|
79
|
+
attribute1 = entity1.attributes[0]
|
80
|
+
attribute2 = entity1.attributes[1]
|
81
|
+
entity2 = repository.entities[1]
|
82
|
+
|
83
|
+
assert_equal [:json], repository.enabled_facets
|
84
|
+
assert_equal [], entity1.enabled_facets
|
85
|
+
assert_equal [:json], entity2.enabled_facets
|
86
|
+
assert_equal [], attribute1.enabled_facets
|
87
|
+
assert_equal [], attribute2.enabled_facets
|
88
|
+
|
89
|
+
repository.enable_facet(:imit)
|
90
|
+
assert_raise_message('Facet imit already enabled.') { repository.enable_facet(:imit) }
|
91
|
+
|
92
|
+
assert_equal [:json, :gwt, :gwt_rpc, :jpa, :imit], repository.enabled_facets
|
93
|
+
assert_equal [:gwt, :gwt_rpc, :jpa, :imit], entity1.enabled_facets
|
94
|
+
assert_equal [:json, :gwt, :gwt_rpc, :jpa, :imit], entity2.enabled_facets
|
95
|
+
assert_equal [:gwt, :gwt_rpc, :jpa, :imit], attribute1.enabled_facets
|
96
|
+
assert_equal [:gwt, :gwt_rpc, :jpa, :imit], attribute2.enabled_facets
|
97
|
+
|
98
|
+
entity1.disable_facet(:gwt)
|
99
|
+
|
100
|
+
assert_equal [:json, :gwt, :gwt_rpc, :jpa, :imit], repository.enabled_facets
|
101
|
+
assert_equal [:jpa], entity1.enabled_facets
|
102
|
+
assert_equal [:json, :gwt, :gwt_rpc, :jpa, :imit], entity2.enabled_facets
|
103
|
+
assert_equal [:jpa], attribute1.enabled_facets
|
104
|
+
assert_equal [:jpa], attribute2.enabled_facets
|
105
|
+
|
106
|
+
entity1.enable_facet(:json)
|
107
|
+
|
108
|
+
assert_equal [:json, :gwt, :gwt_rpc, :jpa, :imit], repository.enabled_facets
|
109
|
+
assert_equal [:jpa, :json], entity1.enabled_facets
|
110
|
+
assert_equal [:json, :gwt, :gwt_rpc, :jpa, :imit], entity2.enabled_facets
|
111
|
+
assert_equal [:jpa, :json], attribute1.enabled_facets
|
112
|
+
assert_equal [:jpa, :json], attribute2.enabled_facets
|
113
|
+
|
114
|
+
repository.disable_facet(:json)
|
115
|
+
|
116
|
+
assert_equal [:gwt, :gwt_rpc, :jpa, :imit], repository.enabled_facets
|
117
|
+
assert_equal [:jpa], entity1.enabled_facets
|
118
|
+
assert_equal [:gwt, :gwt_rpc, :jpa, :imit], entity2.enabled_facets
|
119
|
+
assert_equal [:jpa], attribute1.enabled_facets
|
120
|
+
assert_equal [:jpa], attribute2.enabled_facets
|
121
|
+
|
122
|
+
repository.enable_facets([:json])
|
123
|
+
|
124
|
+
assert_equal [:gwt, :gwt_rpc, :jpa, :imit, :json], repository.enabled_facets
|
125
|
+
assert_equal [:jpa, :json], entity1.enabled_facets
|
126
|
+
assert_equal [:gwt, :gwt_rpc, :jpa, :imit, :json], entity2.enabled_facets
|
127
|
+
assert_equal [:jpa, :json], attribute1.enabled_facets
|
128
|
+
assert_equal [:jpa, :json], attribute2.enabled_facets
|
129
|
+
|
130
|
+
# No-op as all enabled
|
131
|
+
repository.enable_facets([:json])
|
132
|
+
|
133
|
+
assert_equal [:gwt, :gwt_rpc, :jpa, :imit, :json], repository.enabled_facets
|
134
|
+
assert_equal [:jpa, :json], entity1.enabled_facets
|
135
|
+
assert_equal [:gwt, :gwt_rpc, :jpa, :imit, :json], entity2.enabled_facets
|
136
|
+
assert_equal [:jpa, :json], attribute1.enabled_facets
|
137
|
+
assert_equal [:jpa, :json], attribute2.enabled_facets
|
138
|
+
|
139
|
+
assert_raise_message('Facet json already enabled.') { repository.enable_facets!([:json]) }
|
140
|
+
|
141
|
+
# Try using brackets
|
142
|
+
repository.disable_facets([:json, :imit])
|
143
|
+
repository.enable_facets([:imit, :json])
|
144
|
+
|
145
|
+
assert_equal [:gwt, :gwt_rpc, :jpa, :imit, :json], repository.enabled_facets
|
146
|
+
assert_equal [:jpa, :gwt, :gwt_rpc, :imit, :json], entity1.enabled_facets
|
147
|
+
assert_equal [:gwt, :gwt_rpc, :jpa, :imit, :json], entity2.enabled_facets
|
148
|
+
assert_equal [:jpa, :gwt, :gwt_rpc, :imit, :json], attribute1.enabled_facets
|
149
|
+
assert_equal [:jpa, :gwt, :gwt_rpc, :imit, :json], attribute2.enabled_facets
|
150
|
+
|
151
|
+
# Try using raw facet list
|
152
|
+
repository.disable_facets(:json, :imit)
|
153
|
+
repository.enable_facets(:imit, :json)
|
154
|
+
|
155
|
+
assert_equal [:gwt, :gwt_rpc, :jpa, :imit, :json], repository.enabled_facets
|
156
|
+
assert_equal [:jpa, :gwt, :gwt_rpc, :imit, :json], entity1.enabled_facets
|
157
|
+
assert_equal [:gwt, :gwt_rpc, :jpa, :imit, :json], entity2.enabled_facets
|
158
|
+
assert_equal [:jpa, :gwt, :gwt_rpc, :imit, :json], attribute1.enabled_facets
|
159
|
+
assert_equal [:jpa, :gwt, :gwt_rpc, :imit, :json], attribute2.enabled_facets
|
160
|
+
|
161
|
+
# Try forcing
|
162
|
+
repository.disable_facets(:json, :imit)
|
163
|
+
repository.enable_facets!(:imit, :json)
|
164
|
+
|
165
|
+
assert_equal [:gwt, :gwt_rpc, :jpa, :imit, :json], repository.enabled_facets
|
166
|
+
assert_equal [:jpa, :gwt, :gwt_rpc, :imit, :json], entity1.enabled_facets
|
167
|
+
assert_equal [:gwt, :gwt_rpc, :jpa, :imit, :json], entity2.enabled_facets
|
168
|
+
assert_equal [:jpa, :gwt, :gwt_rpc, :imit, :json], attribute1.enabled_facets
|
169
|
+
assert_equal [:jpa, :gwt, :gwt_rpc, :imit, :json], attribute2.enabled_facets
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_extension_point
|
173
|
+
TestFacetContainer.target_manager.target(Repository, :repository)
|
174
|
+
TestFacetContainer.target_manager.target(Entity, :entity, :repository)
|
175
|
+
TestFacetContainer.target_manager.target(Attribute, :attribute, :entity)
|
176
|
+
|
177
|
+
TestFacetContainer.facet(:json) do |f|
|
178
|
+
f.enhance(Entity) do
|
179
|
+
def hook2?
|
180
|
+
@hook2 ||= false
|
181
|
+
end
|
182
|
+
|
183
|
+
def hook2
|
184
|
+
@hook2 = true
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
TestFacetContainer.facet(:jpa) do |f|
|
190
|
+
f.enhance(Repository) do
|
191
|
+
def hook1?
|
192
|
+
@hook1 ||= false
|
193
|
+
end
|
194
|
+
|
195
|
+
def hook1
|
196
|
+
@hook1 = true
|
197
|
+
end
|
198
|
+
|
199
|
+
def hook2?
|
200
|
+
@hook2 ||= false
|
201
|
+
end
|
202
|
+
|
203
|
+
def hook2
|
204
|
+
@hook2 = true
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
f.enhance(Attribute) do
|
209
|
+
def hook2?
|
210
|
+
@hook2 ||= false
|
211
|
+
end
|
212
|
+
|
213
|
+
def hook2
|
214
|
+
@hook2 = true
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
repository = Repository.new(:MyRepo) do |r|
|
220
|
+
TestFacetContainer.target_manager.apply_extension(r)
|
221
|
+
|
222
|
+
r.enable_facets(:json, :jpa)
|
223
|
+
|
224
|
+
r.entity(:MyEntityA) do |e|
|
225
|
+
TestFacetContainer.target_manager.apply_extension(e)
|
226
|
+
e.disable_facet(:json)
|
227
|
+
e.attribute(:MyAttr1) do |a|
|
228
|
+
TestFacetContainer.target_manager.apply_extension(a)
|
229
|
+
end
|
230
|
+
e.attribute(:MyAttr2) do |a|
|
231
|
+
TestFacetContainer.target_manager.apply_extension(a)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
r.entity(:MyEntityB) do |e|
|
236
|
+
TestFacetContainer.target_manager.apply_extension(e)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
entity1 = repository.entities[0]
|
241
|
+
entity2 = repository.entities[1]
|
242
|
+
attribute1 = entity1.attributes[0]
|
243
|
+
attribute2 = entity1.attributes[1]
|
244
|
+
|
245
|
+
assert_equal false, repository.jpa.hook1?
|
246
|
+
assert_equal false, repository.jpa.hook2?
|
247
|
+
assert_equal false, entity2.json.hook2?
|
248
|
+
assert_equal false, attribute1.jpa.hook2?
|
249
|
+
assert_equal false, attribute2.jpa.hook2?
|
250
|
+
|
251
|
+
repository.send(:extension_point, :hook1)
|
252
|
+
|
253
|
+
assert_equal true, repository.jpa.hook1?
|
254
|
+
assert_equal false, repository.jpa.hook2?
|
255
|
+
assert_equal false, entity2.json.hook2?
|
256
|
+
assert_equal false, attribute1.jpa.hook2?
|
257
|
+
assert_equal false, attribute2.jpa.hook2?
|
258
|
+
|
259
|
+
repository.send(:extension_point, :hook2)
|
260
|
+
|
261
|
+
assert_equal true, repository.jpa.hook1?
|
262
|
+
assert_equal true, repository.jpa.hook2?
|
263
|
+
assert_equal true, entity2.json.hook2?
|
264
|
+
assert_equal true, attribute1.jpa.hook2?
|
265
|
+
assert_equal true, attribute2.jpa.hook2?
|
266
|
+
end
|
267
|
+
end
|