feature-rich 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +36 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/feature-rich.gemspec +105 -0
- data/init.rb +5 -0
- data/lib/feature-rich.rb +9 -0
- data/lib/feature-rich/config.rb +17 -0
- data/lib/feature-rich/engine.rb +76 -0
- data/lib/feature-rich/feature.rb +42 -0
- data/lib/feature-rich/feature_handler.rb +18 -0
- data/lib/feature-rich/group_feature.rb +29 -0
- data/lib/feature-rich/model_behaviour.rb +56 -0
- data/lib/feature-rich/railtie.rb +15 -0
- data/spec/config.rb +4 -0
- data/spec/config_spec.rb +17 -0
- data/spec/db.yml +11 -0
- data/spec/db/migrate/001_create_super_heros.rb +12 -0
- data/spec/db/migrate/002_create_features.rb +13 -0
- data/spec/db_helper.rb +85 -0
- data/spec/engine_spec.rb +113 -0
- data/spec/feature_handler.rb +37 -0
- data/spec/group_spec.rb +34 -0
- data/spec/helper.rb +24 -0
- data/spec/model_spec.rb +114 -0
- data/spec/spec_helper.rb +13 -0
- metadata +231 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color --format=progress
|
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use --create @feature-rich
|
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
gem "activerecord", "~> 2.3.2"
|
9
|
+
group :development do
|
10
|
+
gem "rspec", "~> 2.3.0"
|
11
|
+
gem "sqlite3-ruby", :require => 'sqlite3'
|
12
|
+
gem "bundler", "~> 1.0.0"
|
13
|
+
gem "jeweler", "~> 1.5.2"
|
14
|
+
gem "rcov", ">= 0"
|
15
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activerecord (2.3.11)
|
5
|
+
activesupport (= 2.3.11)
|
6
|
+
activesupport (2.3.11)
|
7
|
+
diff-lcs (1.1.2)
|
8
|
+
git (1.2.5)
|
9
|
+
jeweler (1.5.2)
|
10
|
+
bundler (~> 1.0.0)
|
11
|
+
git (>= 1.2.5)
|
12
|
+
rake
|
13
|
+
rake (0.8.7)
|
14
|
+
rcov (0.9.9)
|
15
|
+
rspec (2.3.0)
|
16
|
+
rspec-core (~> 2.3.0)
|
17
|
+
rspec-expectations (~> 2.3.0)
|
18
|
+
rspec-mocks (~> 2.3.0)
|
19
|
+
rspec-core (2.3.1)
|
20
|
+
rspec-expectations (2.3.0)
|
21
|
+
diff-lcs (~> 1.1.2)
|
22
|
+
rspec-mocks (2.3.0)
|
23
|
+
sqlite3 (1.3.3)
|
24
|
+
sqlite3-ruby (1.3.3)
|
25
|
+
sqlite3 (>= 1.3.3)
|
26
|
+
|
27
|
+
PLATFORMS
|
28
|
+
ruby
|
29
|
+
|
30
|
+
DEPENDENCIES
|
31
|
+
activerecord (~> 2.3.2)
|
32
|
+
bundler (~> 1.0.0)
|
33
|
+
jeweler (~> 1.5.2)
|
34
|
+
rcov
|
35
|
+
rspec (~> 2.3.0)
|
36
|
+
sqlite3-ruby
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 hallelujah
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
= feature-rich
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Contributing to feature-rich
|
6
|
+
|
7
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
8
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
9
|
+
* Fork the project
|
10
|
+
* Start a feature/bugfix branch
|
11
|
+
* Commit and push until you are happy with your contribution
|
12
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2011 hallelujah. See LICENSE.txt for
|
18
|
+
further details.
|
19
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "feature-rich"
|
16
|
+
gem.homepage = "http://github.com/hallelujah/feature-rich"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{A activerecord based selectionable feature}
|
19
|
+
gem.description = %Q{Conditional statement to chose feature in your application }
|
20
|
+
gem.email = "hery@rails-royce.org"
|
21
|
+
gem.authors = ["hallelujah"]
|
22
|
+
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
23
|
+
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
24
|
+
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
25
|
+
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
26
|
+
gem.add_development_dependency 'bundler', '>= 1.0.10'
|
27
|
+
gem.add_runtime_dependency 'activerecord', '~> 2.3.2'
|
28
|
+
end
|
29
|
+
Jeweler::RubygemsDotOrgTasks.new
|
30
|
+
|
31
|
+
require 'rspec/core'
|
32
|
+
require 'rspec/core/rake_task'
|
33
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
34
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
35
|
+
end
|
36
|
+
|
37
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
38
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
39
|
+
spec.rcov = true
|
40
|
+
spec.rcov_opts = [ '--exclude', 'gems', '--exclude', 'spec']
|
41
|
+
end
|
42
|
+
|
43
|
+
task :default => :spec
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
48
|
+
|
49
|
+
rdoc.rdoc_dir = 'rdoc'
|
50
|
+
rdoc.title = "feature-rich #{version}"
|
51
|
+
rdoc.rdoc_files.include('README*')
|
52
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.2.0
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{feature-rich}
|
8
|
+
s.version = "0.2.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["hallelujah"]
|
12
|
+
s.date = %q{2011-04-06}
|
13
|
+
s.description = %q{Conditional statement to chose feature in your application }
|
14
|
+
s.email = %q{hery@rails-royce.org}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".rspec",
|
22
|
+
".rvmrc",
|
23
|
+
"Gemfile",
|
24
|
+
"Gemfile.lock",
|
25
|
+
"LICENSE.txt",
|
26
|
+
"README.rdoc",
|
27
|
+
"Rakefile",
|
28
|
+
"VERSION",
|
29
|
+
"feature-rich.gemspec",
|
30
|
+
"init.rb",
|
31
|
+
"lib/feature-rich.rb",
|
32
|
+
"lib/feature-rich/config.rb",
|
33
|
+
"lib/feature-rich/engine.rb",
|
34
|
+
"lib/feature-rich/feature.rb",
|
35
|
+
"lib/feature-rich/feature_handler.rb",
|
36
|
+
"lib/feature-rich/group_feature.rb",
|
37
|
+
"lib/feature-rich/model_behaviour.rb",
|
38
|
+
"lib/feature-rich/railtie.rb",
|
39
|
+
"spec/config.rb",
|
40
|
+
"spec/config_spec.rb",
|
41
|
+
"spec/db.yml",
|
42
|
+
"spec/db/migrate/001_create_super_heros.rb",
|
43
|
+
"spec/db/migrate/002_create_features.rb",
|
44
|
+
"spec/db_helper.rb",
|
45
|
+
"spec/engine_spec.rb",
|
46
|
+
"spec/feature_handler.rb",
|
47
|
+
"spec/group_spec.rb",
|
48
|
+
"spec/helper.rb",
|
49
|
+
"spec/model_spec.rb",
|
50
|
+
"spec/spec_helper.rb"
|
51
|
+
]
|
52
|
+
s.homepage = %q{http://github.com/hallelujah/feature-rich}
|
53
|
+
s.licenses = ["MIT"]
|
54
|
+
s.require_paths = ["lib"]
|
55
|
+
s.rubygems_version = %q{1.3.7}
|
56
|
+
s.summary = %q{A activerecord based selectionable feature}
|
57
|
+
s.test_files = [
|
58
|
+
"spec/config.rb",
|
59
|
+
"spec/config_spec.rb",
|
60
|
+
"spec/db/migrate/001_create_super_heros.rb",
|
61
|
+
"spec/db/migrate/002_create_features.rb",
|
62
|
+
"spec/db_helper.rb",
|
63
|
+
"spec/engine_spec.rb",
|
64
|
+
"spec/feature_handler.rb",
|
65
|
+
"spec/group_spec.rb",
|
66
|
+
"spec/helper.rb",
|
67
|
+
"spec/model_spec.rb",
|
68
|
+
"spec/spec_helper.rb"
|
69
|
+
]
|
70
|
+
|
71
|
+
if s.respond_to? :specification_version then
|
72
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
73
|
+
s.specification_version = 3
|
74
|
+
|
75
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
76
|
+
s.add_runtime_dependency(%q<activerecord>, ["~> 2.3.2"])
|
77
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
|
78
|
+
s.add_development_dependency(%q<sqlite3-ruby>, [">= 0"])
|
79
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
80
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
81
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
82
|
+
s.add_development_dependency(%q<bundler>, [">= 1.0.10"])
|
83
|
+
s.add_runtime_dependency(%q<activerecord>, ["~> 2.3.2"])
|
84
|
+
else
|
85
|
+
s.add_dependency(%q<activerecord>, ["~> 2.3.2"])
|
86
|
+
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
87
|
+
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
88
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
89
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
90
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
91
|
+
s.add_dependency(%q<bundler>, [">= 1.0.10"])
|
92
|
+
s.add_dependency(%q<activerecord>, ["~> 2.3.2"])
|
93
|
+
end
|
94
|
+
else
|
95
|
+
s.add_dependency(%q<activerecord>, ["~> 2.3.2"])
|
96
|
+
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
97
|
+
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
98
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
99
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
100
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
101
|
+
s.add_dependency(%q<bundler>, [">= 1.0.10"])
|
102
|
+
s.add_dependency(%q<activerecord>, ["~> 2.3.2"])
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
data/init.rb
ADDED
data/lib/feature-rich.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'activerecord', '~> 2.3.2'
|
3
|
+
require 'activerecord'
|
4
|
+
require 'feature-rich/feature_handler'
|
5
|
+
require 'feature-rich/engine'
|
6
|
+
require 'feature-rich/config'
|
7
|
+
require 'feature-rich/model_behaviour'
|
8
|
+
require 'feature-rich/group_feature'
|
9
|
+
require 'feature-rich/feature'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module FeatureRich
|
2
|
+
class Config < ActiveSupport::OrderedOptions
|
3
|
+
def initialize(*args)
|
4
|
+
super(*args)
|
5
|
+
self.feature_model ||= "Feature"
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
def method_missing(name, *args)
|
10
|
+
if args.size == 1 && name.to_s !~ /=$/
|
11
|
+
super("#{name}=",*args)
|
12
|
+
else
|
13
|
+
super(name, *args)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'activerecord', '~> 2.3.2'
|
3
|
+
require 'activerecord'
|
4
|
+
require 'feature-rich/config'
|
5
|
+
require 'feature-rich/model_behaviour'
|
6
|
+
require 'feature-rich/group_feature'
|
7
|
+
|
8
|
+
module FeatureRich
|
9
|
+
module Engine
|
10
|
+
VALID_KEYS = [:feature_model, :feature_table, :config_file]
|
11
|
+
|
12
|
+
mattr_accessor :config, :feature_table_name, :feature_handler_table_name, :features, :groups
|
13
|
+
|
14
|
+
self.config = Config.new
|
15
|
+
|
16
|
+
self.groups = HashWithIndifferentAccess.new
|
17
|
+
self.features = Set.new
|
18
|
+
|
19
|
+
|
20
|
+
class << self # Class Proxy
|
21
|
+
def configure(conf = Config.new, &block)
|
22
|
+
conf.instance_exec(&block)
|
23
|
+
self.config.merge!(conf)
|
24
|
+
self.config.assert_valid_keys(*VALID_KEYS)
|
25
|
+
self.config
|
26
|
+
end
|
27
|
+
|
28
|
+
def run(&block)
|
29
|
+
instance_exec(&block)
|
30
|
+
bootstrap!
|
31
|
+
end
|
32
|
+
|
33
|
+
def load!
|
34
|
+
if Object.const_defined?(:Rails) && Rails.root
|
35
|
+
self.config.config_file ||= Rails.root.join('config/feature-rich.rb').to_s
|
36
|
+
end
|
37
|
+
run do
|
38
|
+
eval(File.read(self.config.config_file))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def feature(name, options = {})
|
43
|
+
group(:_none_) do
|
44
|
+
feature name, options
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def group(name, opts = {}, &block)
|
49
|
+
group = (self.groups[name.to_sym] || FeatureRich::GroupFeature.new(name, opts)).configure(&block)
|
50
|
+
self.features += group.sets
|
51
|
+
self.groups[name.to_sym] = group
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def bootstrap!
|
57
|
+
set_feature_table_name
|
58
|
+
set_feature_handler_table_name
|
59
|
+
ActiveRecord::Base.__send__ :include, FeatureRich::ModelBehaviour
|
60
|
+
end
|
61
|
+
|
62
|
+
def set_feature_handler_table_name
|
63
|
+
feature_table_name = config.feature_table || table_name(config.feature_model)
|
64
|
+
end
|
65
|
+
|
66
|
+
def set_feature_table_name
|
67
|
+
feature_table_name = config.feature_table || table_name(config.feature_model)
|
68
|
+
end
|
69
|
+
|
70
|
+
def table_name(name)
|
71
|
+
ActiveRecord::Base.__send__ :undecorated_table_name, name
|
72
|
+
end
|
73
|
+
end # Class Proxy
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module FeatureRich
|
2
|
+
FeatureStruct = Struct.new(:features, :group_features)
|
3
|
+
FeatureStruct.class_eval do
|
4
|
+
def initialize(f,g)
|
5
|
+
self.features = []
|
6
|
+
self.group_features = []
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
def modify(ary)
|
11
|
+
self.features = ary.grep(Symbol)
|
12
|
+
self.group_features = ary.grep(GroupFeature){|g| g.name.to_sym }
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.default
|
16
|
+
new([],[])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Feature < ActiveRecord::Base
|
21
|
+
belongs_to :featured, :polymorphic => true
|
22
|
+
serialize :content, FeatureStruct
|
23
|
+
|
24
|
+
before_save :symbolize_feature_name
|
25
|
+
|
26
|
+
def after_initialize
|
27
|
+
self.content ||= FeatureStruct.default
|
28
|
+
end
|
29
|
+
|
30
|
+
def modify(ary)
|
31
|
+
content_will_change!
|
32
|
+
content.modify(ary)
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
|
37
|
+
def symbolize_feature_name
|
38
|
+
content.features.map!(&:to_sym)
|
39
|
+
content.group_features.map!(&:to_sym)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module FeatureRich
|
2
|
+
class FeatureHandler
|
3
|
+
|
4
|
+
attr_reader :name
|
5
|
+
attr_accessor :label, :disabled
|
6
|
+
|
7
|
+
def initialize(name, options = {})
|
8
|
+
@name = name.to_sym
|
9
|
+
@label = options[:label]
|
10
|
+
@disabled = !! options[:disabled]
|
11
|
+
end
|
12
|
+
|
13
|
+
def disabled?
|
14
|
+
!! @disabled
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module FeatureRich
|
2
|
+
class GroupFeature < FeatureRich::FeatureHandler
|
3
|
+
|
4
|
+
attr_accessor :sets
|
5
|
+
|
6
|
+
def initialize(group_name, options = {})
|
7
|
+
super
|
8
|
+
@sets = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def subset?(ary)
|
12
|
+
(names & ary) == names
|
13
|
+
end
|
14
|
+
|
15
|
+
def names
|
16
|
+
sets.map(&:name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def feature(name, options = {})
|
20
|
+
sets << FeatureRich::FeatureHandler.new(name.to_sym, options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def configure(&block)
|
24
|
+
instance_exec(&block)
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module FeatureRich
|
2
|
+
module ModelBehaviour
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend ClassMethods
|
6
|
+
end # self.included
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def has_feature
|
10
|
+
has_one :feature, :as => :featured, :class_name => "FeatureRich::Feature", :autosave => true
|
11
|
+
include InstanceMethods
|
12
|
+
end
|
13
|
+
end # ClassMethods
|
14
|
+
|
15
|
+
module InstanceMethods
|
16
|
+
|
17
|
+
def features
|
18
|
+
_feature.content
|
19
|
+
end
|
20
|
+
|
21
|
+
def features=(ary)
|
22
|
+
_feature.modify(ary)
|
23
|
+
end
|
24
|
+
|
25
|
+
def has_feature?(feature, options = {})
|
26
|
+
with_group(feature, options[:group]) do |f|
|
27
|
+
case f
|
28
|
+
when Symbol, String
|
29
|
+
features.features.include?(f.to_sym)
|
30
|
+
when GroupFeature
|
31
|
+
f.disabled? || f.subset?(features.features) || features.group_features.include?(f.name)
|
32
|
+
when FeatureHandler
|
33
|
+
f.disabled? || features.features.include?(f.name)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
def _feature
|
41
|
+
(feature || build_feature(:content => FeatureStruct.default))
|
42
|
+
end
|
43
|
+
|
44
|
+
def with_group(fname, with)
|
45
|
+
if with
|
46
|
+
feature = FeatureRich::Engine.groups[fname]
|
47
|
+
else
|
48
|
+
feature = FeatureRich::Engine.features.find{|f| f.name == fname} || fname
|
49
|
+
end
|
50
|
+
yield(feature) || false
|
51
|
+
end
|
52
|
+
|
53
|
+
end # InstanceMethods
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require 'feature-rich'
|
3
|
+
module FeatureRich
|
4
|
+
class Railtie < Rails::Railtie
|
5
|
+
|
6
|
+
config.feature_rich = FeatureRich::Engine.config
|
7
|
+
config.feature_rich.config_file = Rails.root.join('config/feature-rich.rb').to_s
|
8
|
+
|
9
|
+
initializer "feature-rich.after_initialize" do |app|
|
10
|
+
FeatureRich::Engine.run do
|
11
|
+
eval(File.read(app.config.feature_rich.config_file))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/spec/config.rb
ADDED
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "FeatureRich::Config instance" do
|
4
|
+
before do
|
5
|
+
@config = FeatureRich::Config.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should return \"Feature\" as default feature_model" do
|
9
|
+
@config.feature_model.should == "Feature"
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should pass arguments like standard method" do
|
13
|
+
@config.feature_model "OtherModel"
|
14
|
+
@config.feature_model.should == "OtherModel"
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
data/spec/db.yml
ADDED
data/spec/db_helper.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# Extracted from rails-2.3.5/railties/lib/tasks/databases.rake
|
2
|
+
require 'erb'
|
3
|
+
def create_database(config)
|
4
|
+
begin
|
5
|
+
if config['adapter'] =~ /sqlite/
|
6
|
+
if File.exist?(config['database'])
|
7
|
+
$stderr.puts "#{config['database']} already exists"
|
8
|
+
else
|
9
|
+
begin
|
10
|
+
# Create the SQLite database
|
11
|
+
ActiveRecord::Base.establish_connection(config)
|
12
|
+
ActiveRecord::Base.connection
|
13
|
+
rescue
|
14
|
+
$stderr.puts $!, *($!.backtrace)
|
15
|
+
$stderr.puts "Couldn't create database for #{config.inspect}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
return # Skip the else clause of begin/rescue
|
19
|
+
else
|
20
|
+
ActiveRecord::Base.establish_connection(config)
|
21
|
+
ActiveRecord::Base.connection
|
22
|
+
end
|
23
|
+
rescue
|
24
|
+
case config['adapter']
|
25
|
+
when 'mysql'
|
26
|
+
@charset = ENV['CHARSET'] || 'utf8'
|
27
|
+
@collation = ENV['COLLATION'] || 'utf8_unicode_ci'
|
28
|
+
begin
|
29
|
+
ActiveRecord::Base.establish_connection(config.merge('database' => nil))
|
30
|
+
ActiveRecord::Base.connection.create_database(config['database'], :charset => (config['charset'] || @charset), :collation => (config['collation'] || @collation))
|
31
|
+
ActiveRecord::Base.establish_connection(config)
|
32
|
+
rescue
|
33
|
+
$stderr.puts "Couldn't create database for #{config.inspect}, charset: #{config['charset'] || @charset}, collation: #{config['collation'] || @collation} (if you set the charset manually, make sure you have a matching collation)"
|
34
|
+
end
|
35
|
+
when 'postgresql'
|
36
|
+
@encoding = config[:encoding] || ENV['CHARSET'] || 'utf8'
|
37
|
+
begin
|
38
|
+
ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
|
39
|
+
ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => @encoding))
|
40
|
+
ActiveRecord::Base.establish_connection(config)
|
41
|
+
rescue
|
42
|
+
$stderr.puts $!, *($!.backtrace)
|
43
|
+
$stderr.puts "Couldn't create database for #{config.inspect}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
else
|
47
|
+
$stderr.puts "#{config['database']} already exists"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def drop_database(config)
|
52
|
+
case config['adapter']
|
53
|
+
when 'mysql'
|
54
|
+
ActiveRecord::Base.establish_connection(config)
|
55
|
+
ActiveRecord::Base.connection.drop_database config['database']
|
56
|
+
when /^sqlite/
|
57
|
+
FileUtils.rm(File.join(MyROOT, config['database']))
|
58
|
+
when 'postgresql'
|
59
|
+
ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
|
60
|
+
ActiveRecord::Base.connection.drop_database config['database']
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
config = YAML.load(ERB.new(IO.read(File.expand_path( '../db.yml',__FILE__ ))).result(binding))
|
65
|
+
ActiveRecord::Base.configurations = config.with_indifferent_access
|
66
|
+
ActiveRecord::Base.establish_connection :development
|
67
|
+
|
68
|
+
logfile = File.open(File.expand_path('../log/database.log',__FILE__), 'a')
|
69
|
+
logfile.sync = true
|
70
|
+
ActiveRecord::Base.logger = Logger.new(logfile)
|
71
|
+
|
72
|
+
def migrate!(config)
|
73
|
+
migrator = ActiveRecord::Migrator.new(:up,File.expand_path('../db/migrate',__FILE__),nil)
|
74
|
+
#if ! migrator.pending_migrations.blank? || ENV['REMIGRATE']
|
75
|
+
# Drop database
|
76
|
+
drop_database(config)
|
77
|
+
# Create database
|
78
|
+
create_database(config)
|
79
|
+
# Migrate up
|
80
|
+
puts "Migrate up"
|
81
|
+
ActiveRecord::Migrator.migrate(File.expand_path('../db/migrate',__FILE__),nil)
|
82
|
+
# end
|
83
|
+
end
|
84
|
+
|
85
|
+
migrate!(config['development'])
|
data/spec/engine_spec.rb
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe FeatureRich::Engine do
|
4
|
+
before do
|
5
|
+
FeatureRich::Engine.config.clear
|
6
|
+
FeatureRich::Engine.groups.clear
|
7
|
+
FeatureRich::Engine.features.clear
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should require activerecord" do
|
11
|
+
lambda{ActiveRecord::Base}.should_not raise_exception
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should declare FeatureRich::Config" do
|
15
|
+
lambda{FeatureRich::Config}.should_not raise_exception
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should respond to #configure" do
|
19
|
+
should respond_to(:configure).with(1)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "shoud respond to #config" do
|
23
|
+
should respond_to(:config)
|
24
|
+
FeatureRich::Engine.config.should be_an_instance_of(FeatureRich::Config)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should return a FeatureRich::Config instance when invoking #configure" do
|
28
|
+
FeatureRich::Engine.configure{}.should be_an_instance_of FeatureRich::Config
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should invoke #instance_exec on FeatureRich::Config when invoking #configure" do
|
32
|
+
lambda do
|
33
|
+
@config = FeatureRich::Config.new
|
34
|
+
@config.should_receive(:instance_exec).once
|
35
|
+
@config.stub!(:feature_model).and_return("Feature")
|
36
|
+
FeatureRich::Engine.config.should_receive(:merge!).once
|
37
|
+
FeatureRich::Engine.configure(@config) do
|
38
|
+
feature_model = "Feature"
|
39
|
+
end
|
40
|
+
end.should_not raise_exception
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should respond to #run" do
|
44
|
+
should respond_to(:run)
|
45
|
+
FeatureRich::Engine.should_receive(:bootstrap!).once
|
46
|
+
FeatureRich::Engine.run do
|
47
|
+
configure do
|
48
|
+
feature_model "OtherModel"
|
49
|
+
config_file File.expand_path('../config.yml',__FILE__)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should define VALID_KEYS constant" do
|
55
|
+
FeatureRich::Engine.const_defined?(:VALID_KEYS).should be_true
|
56
|
+
FeatureRich::Engine::VALID_KEYS.should =~ [:feature_table, :feature_model, :config_file]
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should raise ArgumentError on bad options " do
|
60
|
+
lambda do
|
61
|
+
FeatureRich::Engine.run do
|
62
|
+
configure do
|
63
|
+
bad_option "Hello"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end.should raise_exception(ArgumentError)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should respond to #features" do
|
70
|
+
FeatureRich::Engine.should respond_to(:features)
|
71
|
+
FeatureRich::Engine.features.should == Set.new
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should respond to #groups" do
|
75
|
+
FeatureRich::Engine.should respond_to(:groups)
|
76
|
+
FeatureRich::Engine.groups.should == HashWithIndifferentAccess.new
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should respond to #feature" do
|
80
|
+
FeatureRich::Engine.should respond_to(:feature).with(1)
|
81
|
+
FeatureRich::Engine.feature(:fly)
|
82
|
+
FeatureRich::Engine.features.map(&:name).should include(:fly)
|
83
|
+
FeatureRich::Engine.groups.should include(:_none_)
|
84
|
+
FeatureRich::Engine.groups[:_none_].sets.map(&:name).should =~ [:fly]
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should respond to #group" do
|
88
|
+
FeatureRich::Engine.should respond_to(:feature).with(1)
|
89
|
+
group_feature = mock('FeatureRich::GroupFeature')
|
90
|
+
FeatureRich::Engine.groups.should_receive(:[]=).once.with(:masked,anything)
|
91
|
+
FeatureRich::Engine.groups.should_receive(:[]).once
|
92
|
+
FeatureRich::Engine.should_receive(:features=).once
|
93
|
+
FeatureRich::Engine.should_receive(:features).once.and_return(Set.new)
|
94
|
+
FeatureRich::Engine.group(:masked) do
|
95
|
+
feature :black_color
|
96
|
+
feature :full_face
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should respond to load!" do
|
101
|
+
FeatureRich::Engine.should respond_to(:load!)
|
102
|
+
Rails = mock('hello')
|
103
|
+
root = mock('root')
|
104
|
+
root.stub!(:join).and_return(File.expand_path('../config.rb',__FILE__))
|
105
|
+
Rails.stub!(:root).and_return(root)
|
106
|
+
FeatureRich::Engine.load!
|
107
|
+
FeatureRich::Engine.groups.should have_key(:color)
|
108
|
+
FeatureRich::Engine.features.should_not be_empty
|
109
|
+
FeatureRich::Engine.features.should satisfy{|set| set.all?{ |n| FeatureRich::FeatureHandler === n} }
|
110
|
+
FeatureRich::Engine.features.map(&:name).to_a.should =~ [ :red,:blue ]
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
describe FeatureRich::FeatureHandler do
|
3
|
+
it "should define a instance attribute reader :name" do
|
4
|
+
@group.should respond_to(:name)
|
5
|
+
@group.name.should be_an_instance_of(Symbol)
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
it "should respond to #new with a name" do
|
10
|
+
FeatureRich::GroupFeature.should respond_to(:new).with(1)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should be labeled" do
|
14
|
+
lambda do
|
15
|
+
@handler = FeatureRich::FeatureHandler.new(:a_handler, :label => "This handler")
|
16
|
+
end.should_not raise_exception
|
17
|
+
@handler.should respond_to(:label)
|
18
|
+
|
19
|
+
@handler.label.should == 'This handler'
|
20
|
+
@handler.should respond_to(:label=)
|
21
|
+
|
22
|
+
@handler.label = 'Other handler'
|
23
|
+
@handler.label.should == 'Other handler'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should be disabled" do
|
27
|
+
handler = FeatureRich::GroupFeature.new(:a_handler, :disabled => true)
|
28
|
+
handler.disabled?.should be_true
|
29
|
+
|
30
|
+
handler = FeatureRich::GroupFeature.new(:a_handler, :disabled => false)
|
31
|
+
handler.disabled?.should be_false
|
32
|
+
|
33
|
+
handler.disabled = true
|
34
|
+
handler.disabled?.should be_true
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
data/spec/group_spec.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
describe FeatureRich::GroupFeature do
|
3
|
+
|
4
|
+
before do
|
5
|
+
@group = FeatureRich::GroupFeature.new(:a_group)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should define instance attribute accessor :sets" do
|
9
|
+
@group.should respond_to(:sets)
|
10
|
+
@group.should respond_to(:sets=)
|
11
|
+
@group.sets.should == Array.new
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should respond to #configure" do
|
15
|
+
@group.should respond_to(:configure).with(0)
|
16
|
+
lambda do
|
17
|
+
@group.configure do
|
18
|
+
feature :black_color
|
19
|
+
feature :full_face
|
20
|
+
end
|
21
|
+
end.should_not raise_exception
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should respond to #subset?" do
|
25
|
+
@group.should respond_to(:subset?)
|
26
|
+
@group.configure do
|
27
|
+
feature :red
|
28
|
+
feature :blue
|
29
|
+
feature :green
|
30
|
+
end
|
31
|
+
@group.subset?([:red, :green, :blue, :orange]).should be_true
|
32
|
+
@group.subset?([:red, :black]).should be_false
|
33
|
+
end
|
34
|
+
end
|
data/spec/helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
logfile = File.open(File.expand_path('../log/database.log',__FILE__), 'a')
|
3
|
+
logfile.sync = true
|
4
|
+
require 'active_record/fixtures'
|
5
|
+
ActiveRecord::Base.logger = Logger.new(logfile)
|
6
|
+
migrator = ActiveRecord::Migrator.new(:up,File.expand_path('../db/migrate',__FILE__),nil)
|
7
|
+
|
8
|
+
if ! migrator.pending_migrations.blank? || ENV['REMIGRATE']
|
9
|
+
ActiveRecord::Base.connection.execute("DROP DATABASE gettext_column_mapping")
|
10
|
+
ActiveRecord::Base.connection.execute("CREATE DATABASE gettext_column_mapping")
|
11
|
+
ActiveRecord::Base.establish_connection(:test)
|
12
|
+
|
13
|
+
class ActiveRecord::Migration
|
14
|
+
def self.load_data(filename, dir = File.expand_path('../db/fixtures',__FILE__))
|
15
|
+
Fixtures.create_fixtures(dir, filename)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Migrate up
|
20
|
+
puts "Migrate up"
|
21
|
+
ActiveRecord::Migrator.migrate(File.expand_path('../db/migrate',__FILE__),nil)
|
22
|
+
end
|
23
|
+
$gettext_column_mapping_root = File.dirname(__FILE__)
|
24
|
+
FileUtils.mkdir_p(File.join($gettext_column_mapping_root,'locale'))
|
data/spec/model_spec.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/db_helper')
|
3
|
+
|
4
|
+
describe FeatureRich::ModelBehaviour do
|
5
|
+
# Called once
|
6
|
+
before(:all) do
|
7
|
+
FeatureRich::Engine.run do
|
8
|
+
configure do
|
9
|
+
feature_model "Feature"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
SuperHero = Class.new(ActiveRecord::Base)
|
13
|
+
SuperHero.has_feature
|
14
|
+
end
|
15
|
+
|
16
|
+
# Called before each test
|
17
|
+
before do
|
18
|
+
FeatureRich::Engine.config.clear
|
19
|
+
FeatureRich::Engine.features.clear
|
20
|
+
FeatureRich::Engine.groups.clear
|
21
|
+
@superman = SuperHero.new
|
22
|
+
@superman.should be_an_instance_of SuperHero
|
23
|
+
@superman.new_record?.should be_true
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should create a has_many polymorphic relation" do
|
27
|
+
SuperHero.reflections[:feature].should_not be_nil
|
28
|
+
SuperHero.reflections[:feature].macro.should == :has_one
|
29
|
+
SuperHero.reflections[:feature].options[:as].should == :featured
|
30
|
+
SuperHero.reflections[:feature].options[:autosave].should be_true
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should respond to #features" do
|
34
|
+
g = FeatureRich::GroupFeature.new(:flying)
|
35
|
+
FeatureRich::Engine.run do
|
36
|
+
group :flying do
|
37
|
+
feature :wings
|
38
|
+
end
|
39
|
+
end
|
40
|
+
@superman.should respond_to(:features)
|
41
|
+
@superman.features.should == FeatureRich::FeatureStruct.default
|
42
|
+
@superman.features = [:fly]
|
43
|
+
@superman.features.features.should == [:fly]
|
44
|
+
@superman.feature.should be_an_instance_of FeatureRich::Feature
|
45
|
+
@superman.feature.new_record?.should be_true
|
46
|
+
@superman.name = "Clark Kent"
|
47
|
+
@superman.save!
|
48
|
+
@superman.reload
|
49
|
+
@superman.feature.should be_an_instance_of FeatureRich::Feature
|
50
|
+
@superman.features.features.should == [:fly]
|
51
|
+
@superman.features.group_features.should be_empty
|
52
|
+
@superman.features = [:strong, g]
|
53
|
+
@superman.changed?.should be_false
|
54
|
+
@superman.save!
|
55
|
+
@superman.reload
|
56
|
+
@superman.features.features.should == [:strong]
|
57
|
+
@superman.features.group_features.should == [:flying]
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should respond to #has_feature?" do
|
61
|
+
@superman.should respond_to(:has_feature?)
|
62
|
+
@superman.has_feature?(:fly).should be_false
|
63
|
+
@superman.features = [:fly]
|
64
|
+
@superman.has_feature?(:fly).should be_true
|
65
|
+
|
66
|
+
group = FeatureRich::GroupFeature.new(:flying)
|
67
|
+
# Mocking is more convenient
|
68
|
+
group.should_receive(:subset?).twice.and_return(false,true)
|
69
|
+
@superman.has_feature?(group).should be_false
|
70
|
+
@superman.has_feature?(group).should be_true
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should respond to #has_feature? with option group" do
|
74
|
+
g = FeatureRich::GroupFeature.new(:flying)
|
75
|
+
FeatureRich::Engine.run do
|
76
|
+
group :flying do
|
77
|
+
feature :wings
|
78
|
+
end
|
79
|
+
group :singing do
|
80
|
+
feature :voice
|
81
|
+
end
|
82
|
+
end
|
83
|
+
@superman.features = [:fly, g ]
|
84
|
+
@superman.features.group_features.should == [:flying]
|
85
|
+
@superman.has_feature?(:flying, :group => true).should be_true
|
86
|
+
@superman.has_feature?(:singing, :group => true).should be_false
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should have feature if group is disabled" do
|
90
|
+
g = FeatureRich::GroupFeature.new(:flying, :disabled => true)
|
91
|
+
FeatureRich::Engine.run do
|
92
|
+
group :flying do
|
93
|
+
feature :wings
|
94
|
+
end
|
95
|
+
group :singing do
|
96
|
+
feature :voice
|
97
|
+
end
|
98
|
+
end
|
99
|
+
@superman.features = [:fly, g ]
|
100
|
+
@superman.features.group_features.should == [:flying]
|
101
|
+
@superman.has_feature?(:flying, :group => true).should be_true
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should have feature if Feature is disabled" do
|
105
|
+
FeatureRich::Engine.run do
|
106
|
+
feature :wings
|
107
|
+
feature :voice, :disabled => true
|
108
|
+
end
|
109
|
+
@superman.features = [:fly ]
|
110
|
+
@superman.features.features.should == [:fly]
|
111
|
+
@superman.has_feature?(:voice).should be_true
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
MyROOT = File.expand_path('../../',__FILE__)
|
4
|
+
require 'rspec'
|
5
|
+
require 'feature-rich'
|
6
|
+
|
7
|
+
# Requires supporting files with custom matchers and macros, etc,
|
8
|
+
# in ./support/ and its subdirectories.
|
9
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,231 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: feature-rich
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- hallelujah
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-04-06 00:00:00 +02:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
hash: 7
|
28
|
+
segments:
|
29
|
+
- 2
|
30
|
+
- 3
|
31
|
+
- 2
|
32
|
+
version: 2.3.2
|
33
|
+
requirement: *id001
|
34
|
+
prerelease: false
|
35
|
+
type: :runtime
|
36
|
+
name: activerecord
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 2
|
46
|
+
- 3
|
47
|
+
- 0
|
48
|
+
version: 2.3.0
|
49
|
+
requirement: *id002
|
50
|
+
prerelease: false
|
51
|
+
type: :development
|
52
|
+
name: rspec
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 3
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
version: "0"
|
63
|
+
requirement: *id003
|
64
|
+
prerelease: false
|
65
|
+
type: :development
|
66
|
+
name: sqlite3-ruby
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ~>
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
hash: 23
|
74
|
+
segments:
|
75
|
+
- 1
|
76
|
+
- 0
|
77
|
+
- 0
|
78
|
+
version: 1.0.0
|
79
|
+
requirement: *id004
|
80
|
+
prerelease: false
|
81
|
+
type: :development
|
82
|
+
name: bundler
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
hash: 7
|
90
|
+
segments:
|
91
|
+
- 1
|
92
|
+
- 5
|
93
|
+
- 2
|
94
|
+
version: 1.5.2
|
95
|
+
requirement: *id005
|
96
|
+
prerelease: false
|
97
|
+
type: :development
|
98
|
+
name: jeweler
|
99
|
+
- !ruby/object:Gem::Dependency
|
100
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
101
|
+
none: false
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
hash: 3
|
106
|
+
segments:
|
107
|
+
- 0
|
108
|
+
version: "0"
|
109
|
+
requirement: *id006
|
110
|
+
prerelease: false
|
111
|
+
type: :development
|
112
|
+
name: rcov
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
version_requirements: &id007 !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
hash: 3
|
120
|
+
segments:
|
121
|
+
- 1
|
122
|
+
- 0
|
123
|
+
- 10
|
124
|
+
version: 1.0.10
|
125
|
+
requirement: *id007
|
126
|
+
prerelease: false
|
127
|
+
type: :development
|
128
|
+
name: bundler
|
129
|
+
- !ruby/object:Gem::Dependency
|
130
|
+
version_requirements: &id008 !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
132
|
+
requirements:
|
133
|
+
- - ~>
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
hash: 7
|
136
|
+
segments:
|
137
|
+
- 2
|
138
|
+
- 3
|
139
|
+
- 2
|
140
|
+
version: 2.3.2
|
141
|
+
requirement: *id008
|
142
|
+
prerelease: false
|
143
|
+
type: :runtime
|
144
|
+
name: activerecord
|
145
|
+
description: "Conditional statement to chose feature in your application "
|
146
|
+
email: hery@rails-royce.org
|
147
|
+
executables: []
|
148
|
+
|
149
|
+
extensions: []
|
150
|
+
|
151
|
+
extra_rdoc_files:
|
152
|
+
- LICENSE.txt
|
153
|
+
- README.rdoc
|
154
|
+
files:
|
155
|
+
- .document
|
156
|
+
- .rspec
|
157
|
+
- .rvmrc
|
158
|
+
- Gemfile
|
159
|
+
- Gemfile.lock
|
160
|
+
- LICENSE.txt
|
161
|
+
- README.rdoc
|
162
|
+
- Rakefile
|
163
|
+
- VERSION
|
164
|
+
- feature-rich.gemspec
|
165
|
+
- init.rb
|
166
|
+
- lib/feature-rich.rb
|
167
|
+
- lib/feature-rich/config.rb
|
168
|
+
- lib/feature-rich/engine.rb
|
169
|
+
- lib/feature-rich/feature.rb
|
170
|
+
- lib/feature-rich/feature_handler.rb
|
171
|
+
- lib/feature-rich/group_feature.rb
|
172
|
+
- lib/feature-rich/model_behaviour.rb
|
173
|
+
- lib/feature-rich/railtie.rb
|
174
|
+
- spec/config.rb
|
175
|
+
- spec/config_spec.rb
|
176
|
+
- spec/db.yml
|
177
|
+
- spec/db/migrate/001_create_super_heros.rb
|
178
|
+
- spec/db/migrate/002_create_features.rb
|
179
|
+
- spec/db_helper.rb
|
180
|
+
- spec/engine_spec.rb
|
181
|
+
- spec/feature_handler.rb
|
182
|
+
- spec/group_spec.rb
|
183
|
+
- spec/helper.rb
|
184
|
+
- spec/model_spec.rb
|
185
|
+
- spec/spec_helper.rb
|
186
|
+
has_rdoc: true
|
187
|
+
homepage: http://github.com/hallelujah/feature-rich
|
188
|
+
licenses:
|
189
|
+
- MIT
|
190
|
+
post_install_message:
|
191
|
+
rdoc_options: []
|
192
|
+
|
193
|
+
require_paths:
|
194
|
+
- lib
|
195
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
196
|
+
none: false
|
197
|
+
requirements:
|
198
|
+
- - ">="
|
199
|
+
- !ruby/object:Gem::Version
|
200
|
+
hash: 3
|
201
|
+
segments:
|
202
|
+
- 0
|
203
|
+
version: "0"
|
204
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
205
|
+
none: false
|
206
|
+
requirements:
|
207
|
+
- - ">="
|
208
|
+
- !ruby/object:Gem::Version
|
209
|
+
hash: 3
|
210
|
+
segments:
|
211
|
+
- 0
|
212
|
+
version: "0"
|
213
|
+
requirements: []
|
214
|
+
|
215
|
+
rubyforge_project:
|
216
|
+
rubygems_version: 1.3.7
|
217
|
+
signing_key:
|
218
|
+
specification_version: 3
|
219
|
+
summary: A activerecord based selectionable feature
|
220
|
+
test_files:
|
221
|
+
- spec/config.rb
|
222
|
+
- spec/config_spec.rb
|
223
|
+
- spec/db/migrate/001_create_super_heros.rb
|
224
|
+
- spec/db/migrate/002_create_features.rb
|
225
|
+
- spec/db_helper.rb
|
226
|
+
- spec/engine_spec.rb
|
227
|
+
- spec/feature_handler.rb
|
228
|
+
- spec/group_spec.rb
|
229
|
+
- spec/helper.rb
|
230
|
+
- spec/model_spec.rb
|
231
|
+
- spec/spec_helper.rb
|