cantango-config 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +40 -0
  4. data/Gemfile.lock +163 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.mdown +21 -0
  7. data/Rakefile +49 -0
  8. data/VERSION +1 -0
  9. data/cantango-config.gemspec +145 -0
  10. data/lib/cantango/adapter/compiler.rb +9 -0
  11. data/lib/cantango/adapter/moneta.rb +23 -0
  12. data/lib/cantango/config.rb +12 -0
  13. data/lib/cantango/configuration/ability.rb +14 -0
  14. data/lib/cantango/configuration/account.rb +23 -0
  15. data/lib/cantango/configuration/accounts.rb +8 -0
  16. data/lib/cantango/configuration/adapters.rb +24 -0
  17. data/lib/cantango/configuration/autoload.rb +38 -0
  18. data/lib/cantango/configuration/candidate_registry.rb +94 -0
  19. data/lib/cantango/configuration/categories.rb +57 -0
  20. data/lib/cantango/configuration/debug.rb +41 -0
  21. data/lib/cantango/configuration/engine.rb +33 -0
  22. data/lib/cantango/configuration/engines.rb +97 -0
  23. data/lib/cantango/configuration/factory.rb +59 -0
  24. data/lib/cantango/configuration/guest.rb +57 -0
  25. data/lib/cantango/configuration/hash_registry.rb +91 -0
  26. data/lib/cantango/configuration/hooks.rb +12 -0
  27. data/lib/cantango/configuration/localhosts.rb +12 -0
  28. data/lib/cantango/configuration/models/actions.rb +26 -0
  29. data/lib/cantango/configuration/models/active_record.rb +22 -0
  30. data/lib/cantango/configuration/models/data_mapper.rb +12 -0
  31. data/lib/cantango/configuration/models/generic.rb +12 -0
  32. data/lib/cantango/configuration/models/mongo.rb +12 -0
  33. data/lib/cantango/configuration/models/mongo_mapper.rb +11 -0
  34. data/lib/cantango/configuration/models/mongoid.rb +13 -0
  35. data/lib/cantango/configuration/models.rb +77 -0
  36. data/lib/cantango/configuration/modes.rb +21 -0
  37. data/lib/cantango/configuration/orms.rb +8 -0
  38. data/lib/cantango/configuration/registry.rb +56 -0
  39. data/lib/cantango/configuration/user.rb +47 -0
  40. data/lib/cantango/configuration/users.rb +8 -0
  41. data/lib/cantango/configuration.rb +99 -0
  42. data/spec/cantango/config_spec.rb +8 -0
  43. data/spec/cantango/configuration/ability_spec.rb +13 -0
  44. data/spec/cantango/configuration/account_spec.rb +21 -0
  45. data/spec/cantango/configuration/accounts_spec.rb +18 -0
  46. data/spec/cantango/configuration/adapters_spec.rb +30 -0
  47. data/spec/cantango/configuration/autoload_spec.rb +52 -0
  48. data/spec/cantango/configuration/candidate_registry_spec.rb +12 -0
  49. data/spec/cantango/configuration/categories_spec.rb +58 -0
  50. data/spec/cantango/configuration/debug_spec.rb +39 -0
  51. data/spec/cantango/configuration/engines/engine_shared.rb +22 -0
  52. data/spec/cantango/configuration/engines_spec.rb +102 -0
  53. data/spec/cantango/configuration/factory_spec.rb +18 -0
  54. data/spec/cantango/configuration/guest/find_guest_default_way_spec.rb +32 -0
  55. data/spec/cantango/configuration/guest_spec.rb +61 -0
  56. data/spec/cantango/configuration/hash_registry_spec.rb +22 -0
  57. data/spec/cantango/configuration/localhosts_spec.rb +9 -0
  58. data/spec/cantango/configuration/models_spec.rb +47 -0
  59. data/spec/cantango/configuration/orms_spec.rb +9 -0
  60. data/spec/cantango/configuration/registry_spec.rb +15 -0
  61. data/spec/cantango/configuration/shared/candidate_registry_ex.rb +47 -0
  62. data/spec/cantango/configuration/shared/factory_ex.rb +40 -0
  63. data/spec/cantango/configuration/shared/hash_registry_ex.rb +55 -0
  64. data/spec/cantango/configuration/shared/modes_ex.rb +14 -0
  65. data/spec/cantango/configuration/shared/registry_ex.rb +40 -0
  66. data/spec/cantango/configuration/shared/role_registry_ex.rb +22 -0
  67. data/spec/cantango/configuration/user_spec.rb +45 -0
  68. data/spec/cantango/configuration/users_spec.rb +18 -0
  69. data/spec/cantango/configuration_spec.rb +112 -0
  70. data/spec/db/database.yml +4 -0
  71. data/spec/factories/project.rb +6 -0
  72. data/spec/fixtures/models/admin.rb +2 -0
  73. data/spec/fixtures/models/admin_account.rb +22 -0
  74. data/spec/fixtures/models/items.rb +8 -0
  75. data/spec/fixtures/models/permission.rb +12 -0
  76. data/spec/fixtures/models/project.rb +2 -0
  77. data/spec/fixtures/models/simple_roles.rb +49 -0
  78. data/spec/fixtures/models/user.rb +52 -0
  79. data/spec/fixtures/models/user_account.rb +21 -0
  80. data/spec/fixtures/models.rb +2 -0
  81. data/spec/migrations/001_create_projects.rb +12 -0
  82. data/spec/spec_helper.rb +35 -0
  83. metadata +231 -0
@@ -0,0 +1,94 @@
1
+ require 'singleton'
2
+ require 'sugar-high/kind_of'
3
+
4
+ module CanTango
5
+ class Configuration
6
+ class CandidateRegistry
7
+ def register label, value
8
+ raise "first arg must be a label, was: #{label}" if !label.kind_of_label?
9
+ raise "second arg must be a valid Class, was: #{value}" if !valid? value
10
+ name_registry.register label.to_sym
11
+ class_registry.register value
12
+ end
13
+ alias_method :[]=, :register
14
+
15
+ def << hash
16
+ raise "Must be a hash" if !hash.is_a? Hash
17
+ hash.each_pair do |key, value|
18
+ register key, value
19
+ end
20
+ end
21
+
22
+ def registered
23
+ name_registry.registered
24
+ end
25
+ alias_method :registered_names, :registered
26
+
27
+ def clean!
28
+ name_registry.clean!
29
+ class_registry.clean!
30
+ end
31
+ alias_method :clear!, :clean!
32
+
33
+ def registered_classes
34
+ class_registry.registered
35
+ end
36
+
37
+ def registered? name
38
+ name_registry.registered? name
39
+ end
40
+
41
+ def registered_class? name
42
+ class_registry.registered? name
43
+ end
44
+
45
+ def name_registry
46
+ NameRegistry.instance
47
+ end
48
+
49
+ def class_registry
50
+ ClassRegistry.instance
51
+ end
52
+
53
+ def value_methods
54
+ class_registry.value_methods
55
+ end
56
+
57
+ def value_types
58
+ class_registry.types
59
+ end
60
+
61
+ class NameRegistry < Registry
62
+ include Singleton
63
+ end
64
+
65
+ class ClassRegistry < Registry
66
+ include Singleton
67
+
68
+ def types
69
+ [Class]
70
+ end
71
+
72
+ def value_methods
73
+ []
74
+ end
75
+ end
76
+
77
+ protected
78
+
79
+ def valid? value
80
+ valid_by_type?(value) && valid_by_methods?(value)
81
+ end
82
+
83
+ def valid_by_type? value
84
+ return true if value_types.blank?
85
+ value.any_kind_of?(*value_types)
86
+ end
87
+
88
+ def valid_by_methods? value
89
+ return true if value_methods.blank?
90
+ value_methods.all?{|m| value.respond_to(m)}
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,57 @@
1
+ module CanTango
2
+ class Configuration
3
+ class Categories < HashRegistry
4
+
5
+ include Singleton
6
+
7
+ def [] label
8
+ models = super
9
+ raise "Category '#{label}' either not exists or invalid!" if !models.kind_of?(Array)
10
+ models
11
+ end
12
+
13
+ def category label, &block
14
+ cat = Category.new self[label]
15
+ yield cat if block
16
+ cat
17
+ end
18
+
19
+ # test if a any of the categories contain the subject
20
+ def has_any? subject, &block
21
+ found = registered.any? {|cat, subjects| subjects.include? subject }
22
+ yield if found && block
23
+ found
24
+ end
25
+
26
+ # find the category of a subject if such a category exists
27
+ def category_names_of_subject subject, &block
28
+ categories_of_subject(subject).keys
29
+ end
30
+
31
+ # find the category of a subject if such a category exists
32
+ def categories_of_subject subject, &block
33
+ found_categories = registered.select do |cat, subjects|
34
+ subjects.include? subject.to_s
35
+ end
36
+ found_categories.empty? ? {} : found_categories
37
+ end
38
+
39
+ class Category
40
+ def initialize *subjects
41
+ @subjects = subjects.flatten
42
+ end
43
+
44
+ def subjects
45
+ @subjects ||= []
46
+ end
47
+
48
+ # test if a particular category has a certain subject
49
+ def has_any? subject, &block
50
+ found = subjects.include? subject
51
+ yield if found && block
52
+ found
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,41 @@
1
+ module CanTango
2
+ class Configuration
3
+ # Note: This config feature is currently not used, but could potentially be of use in the future
4
+ class Debug
5
+ include Singleton
6
+
7
+ def set state = :on
8
+ raise ArgumentError, "Must be :on or :off" unless !state || [:on, :off].include?(state)
9
+ @state = state || :on
10
+ end
11
+
12
+ def on?
13
+ @state == :on
14
+ end
15
+
16
+ def off?
17
+ !on?
18
+ end
19
+
20
+ def debug_writer= proc
21
+ raise ArgumentError, "Debug writer must be callable (lambda or Proc), was: #{proc}" if !callable?(proc)
22
+ @debug_writer = proc
23
+ end
24
+
25
+ def write msg
26
+ @debug_writer ||= Proc.new{|msg| puts msg}
27
+ @debug_writer.call(msg)
28
+ end
29
+
30
+ protected
31
+
32
+ def callable? obj
33
+ obj && obj.respond_to?(:call)
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+
40
+
41
+
@@ -0,0 +1,33 @@
1
+ require 'singleton'
2
+
3
+ module CanTango
4
+ class Configuration
5
+ class Engine
6
+ include Singleton
7
+ include CanTango::Configuration::Modes
8
+
9
+ def set state = :on
10
+ raise ArgumentError, "Must be :on or :off" unless !state || [:on, :off].include?(state)
11
+ @state = state || :on
12
+ end
13
+
14
+ def reset!
15
+ @state = nil
16
+ end
17
+
18
+ def on?
19
+ @state == :on
20
+ end
21
+
22
+ def off?
23
+ !on?
24
+ end
25
+
26
+ protected
27
+
28
+ def ns
29
+ CanTango::Configuration::Engines
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,97 @@
1
+ module CanTango
2
+ class Configuration
3
+ class Engines < HashRegistry
4
+ autoload_modules :Permission, :Engine
5
+
6
+ include Singleton
7
+ include Enumerable
8
+
9
+ # engine registry is a simple hash
10
+ def register hash
11
+ hash.each_pair do |name, engine_class|
12
+ raise "Class must implement the CanTango Engine API. You can start by sublclassing CanTango::Engine" if !engine? engine_class
13
+ raise "Name of engine must be a String or Symbol" if !name.kind_of_label?
14
+ registered[name.to_s] = engine_class
15
+ end
16
+ end
17
+
18
+ # defines the order of execution of engine in ability
19
+ def set_execution_order *names
20
+ @execution_order = names.flatten.uniq.map(&:to_s).select {|name| available? name }
21
+ end
22
+
23
+ def dont_execute name
24
+ execution_order.delete(name.to_s)
25
+ end
26
+
27
+ def execute_first name
28
+ dont_execute name
29
+ execution_order.insert(0, name.to_s)
30
+ end
31
+
32
+ def execute_last name
33
+ dont_execute name
34
+ execution_order.insert(-1, name.to_s)
35
+ end
36
+
37
+ def execute_before existing, name
38
+ dont_execute name
39
+ index = execution_order.index(existing.to_s) || 0
40
+ execution_order.insert(index, name.to_s)
41
+ execution_order.compact!
42
+ end
43
+
44
+ def execute_after existing, name
45
+ dont_execute name
46
+ index = execution_order.index(existing.to_s)
47
+ index ? execution_order.insert(index +1, name.to_s) : execute_last(name)
48
+ execution_order.compact!
49
+ end
50
+
51
+ def execution_order
52
+ @execution_order ||= (available - [:cache])
53
+ end
54
+
55
+ def available
56
+ registered_names
57
+ end
58
+
59
+ def available? name
60
+ available.include? name.to_s
61
+ end
62
+
63
+ def all state
64
+ available.each {|engine| send(engine).set state }
65
+ end
66
+
67
+ def any? state
68
+ available.any? {|engine| send(engine).send(:"#{state}?") if respond_to?(engine) }
69
+ end
70
+
71
+ def clear!
72
+ each {|engine| engine.reset! }
73
+ @registered = nil
74
+ @execution_order = nil
75
+ end
76
+
77
+ def each
78
+ available.each {|engine| yield send(engine) if respond_to?(engine) }
79
+ end
80
+
81
+ def active? name
82
+ active.include? name.to_sym
83
+ end
84
+
85
+ def active
86
+ available.select {|engine| send(engine).on? if respond_to?(engine) }
87
+ end
88
+
89
+ protected
90
+
91
+ # does it implement the basic Engine API?
92
+ def engine? engine_class
93
+ [:execute!, :ability].all? {|meth| engine_class.instance_methods.include? meth }
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,59 @@
1
+ module CanTango
2
+ class Configuration
3
+ module Factory
4
+ def clear!
5
+ @factory = nil
6
+ end
7
+
8
+ def factory factory = nil
9
+ raise ArgumentError, "Factory must be a callable (lambda or Proc), was: #{proc}" if !callable? factory
10
+ @factory = factory
11
+ end
12
+
13
+ alias_method :factory=, :factory
14
+
15
+ def factory_build obj = nil, opts = {}
16
+ factory_method = @factory ? :call_factory : :default_factory
17
+ send(factory_method, obj, opts)
18
+ end
19
+
20
+ def call_factory obj = nil, opts = {}
21
+ @factory.respond_to?(:call) ? @factory.call(obj, opts) : @factory
22
+ end
23
+
24
+ def default_factory obj = nil, opts = {}
25
+ raise "Default factory must be defined" if !default_class
26
+ default_class.new obj, options.merge(opts)
27
+ end
28
+
29
+ attr_reader :default_class
30
+
31
+ # must be a Class of type Cache (Base?)
32
+ def default_class= clazz
33
+ raise ArgumentError, "default must be a Class" if !is_class? clazz
34
+ @default_class = clazz
35
+ end
36
+
37
+ def options= options = {}
38
+ raise ArgumentError, "Must be a Hash, was #{options}" if !options.kind_of? Hash
39
+ @options = options
40
+ end
41
+
42
+ def options
43
+ @options ? type_options : type_options.merge(@options || {})
44
+ end
45
+
46
+ def type_options
47
+ {}
48
+ end
49
+
50
+ protected
51
+
52
+ def callable? obj
53
+ obj && obj.respond_to?(:call)
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+
@@ -0,0 +1,57 @@
1
+ module CanTango
2
+ class Configuration
3
+ class Guest
4
+ include Singleton
5
+
6
+ def clear!
7
+ @user = nil
8
+ @account = nil
9
+ end
10
+
11
+ def user user = nil, &block
12
+ return (@user || guest_user) if !user && !block
13
+ @user = user || yield
14
+ end
15
+
16
+ alias_method :user=, :user
17
+
18
+ def account account = nil, &block
19
+ return (@account || guest_account) if !account && !block
20
+ @account = account || yield
21
+ end
22
+ alias_method :user_account, :account
23
+ alias_method :account=, :account
24
+
25
+ def default_user?
26
+ has_guest? base_user_class
27
+ end
28
+
29
+ def default_account?
30
+ has_guest? base_account_class
31
+ end
32
+
33
+ protected
34
+
35
+ def guest_user
36
+ base_user_class.guest if default_user?
37
+ end
38
+
39
+ def guest_account
40
+ base_account_class.guest if default_account?
41
+ end
42
+
43
+ def has_guest? clazz
44
+ clazz && defined?(clazz) && clazz.respond_to?(:guest)
45
+ end
46
+
47
+ def base_user_class
48
+ CanTango.config.user.base_class
49
+ end
50
+
51
+ def base_account_class
52
+ CanTango.config.user_account.base_class
53
+ end
54
+ end
55
+ end
56
+ end
57
+
@@ -0,0 +1,91 @@
1
+ require 'singleton'
2
+ require 'sugar-high/kind_of'
3
+
4
+ module CanTango
5
+ class Configuration
6
+ class HashRegistry < Registry
7
+
8
+ def types= *types
9
+ raise "This is a Hash registry!"
10
+ end
11
+
12
+ def types
13
+ [Hash]
14
+ end
15
+
16
+ def value_methods
17
+ []
18
+ end
19
+
20
+ def value_types
21
+ []
22
+ end
23
+
24
+ def clean!
25
+ registered = Hashie::Mash.new
26
+ end
27
+ alias_method :clear!, :clean!
28
+
29
+ def default!
30
+ @registered = default
31
+ end
32
+
33
+ def << hash
34
+ raise "Must be a hash" if !hash.is_a? Hash
35
+ registered.merge!(hash) and return if value_methods.empty? && value_types.empty?
36
+ hash.each_pair do |key, value|
37
+ registered[key] = value if value_api.all?{|m| value.respond_to(m)} && value.any_kind_of?(value_types)
38
+ end
39
+ end
40
+
41
+ def [] label
42
+ raise "Must be a label" if !label.kind_of_label?
43
+ registered[label.to_s]
44
+ end
45
+
46
+ def []= label, value
47
+ raise "Must be a label" if !label.kind_of_label?
48
+ registered[label.to_s] = value
49
+ end
50
+
51
+ def register hash
52
+ raise "Must be a hash" if !hash.is_a? Hash
53
+ registered.merge! hash
54
+ end
55
+
56
+ def unregister name
57
+ @registered = {} if name == :all
58
+ @registered.delete(name)
59
+ end
60
+
61
+ def registered
62
+ @registered ||= default
63
+ end
64
+
65
+ def registered_names
66
+ registered.keys
67
+ end
68
+
69
+ def registered_values
70
+ registered.values
71
+ end
72
+
73
+ def registered? label
74
+ registered_names.map(&:to_s).include? label.to_s
75
+ end
76
+ alias_method :registered_name, :registered?
77
+
78
+ def registered_value? value
79
+ registered_values.include? value
80
+ end
81
+
82
+ def default
83
+ @default ||= Hashie::Mash.new
84
+ end
85
+
86
+ def default= hash
87
+ @default = Hashie::Mash.new hash
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,12 @@
1
+ module CanTango
2
+ class Configuration
3
+ class Hooks < HashRegistry
4
+ include Singleton
5
+
6
+ def value_methods
7
+ [:call]
8
+ end
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,12 @@
1
+ module CanTango
2
+ class Configuration
3
+ class Localhosts < Registry
4
+ include Singleton
5
+
6
+ def default
7
+ @default ||= ['localhost', '0.0.0.0', '127.0.0.1']
8
+ end
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,26 @@
1
+ module CanTango
2
+ class Configuration
3
+ class Models
4
+ class Actions
5
+ attr_reader :collection, :member
6
+
7
+ def initialize
8
+ @collection = []
9
+ @member = []
10
+ end
11
+
12
+ def actions_for type
13
+ send(type.to_sym) || []
14
+ end
15
+
16
+ def add_member action
17
+ @member << action.to_sym
18
+ end
19
+
20
+ def add_collection action
21
+ @collection << action.to_sym
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,22 @@
1
+ module CanTango
2
+ class Configuration
3
+ class Models
4
+ class ActiveRecord < Generic
5
+ def models
6
+ ::ActiveRecord::Base.descendants
7
+ rescue
8
+ table_models
9
+ end
10
+
11
+ protected
12
+
13
+ def table_models
14
+ ActiveRecord::Base.connection.tables do |t|
15
+ t.classify.constantize
16
+ nil
17
+ end.compact
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,12 @@
1
+ module CanTango
2
+ class Configuration
3
+ class Models
4
+ class DataMapper < Generic
5
+ def models
6
+ DataMapper::Resource.descendants
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,12 @@
1
+ module CanTango
2
+ class Configuration
3
+ class Models
4
+ class Generic
5
+ def available_models
6
+ models.map(&:name)
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,12 @@
1
+ module CanTango
2
+ class Configuration
3
+ class Models
4
+ class Mongo
5
+ def available_models
6
+ models.map {|m| m.to_s.camelize }
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,11 @@
1
+ module CanTango
2
+ class Configuration
3
+ class Models
4
+ module MongoMapper < Mongo
5
+ def models
6
+ MongoMapper.database.collections
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module CanTango
2
+ class Configuration
3
+ class Models
4
+ class Mongoid < Mongo
5
+ def models
6
+ ::Mongoid.database.collections
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+