ghaki-app 2011.11.29.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010 Gerald Kalafut
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,23 @@
1
+ = Ghaki App - Ghaki App singleton helpers
2
+
3
+ Ghaki App is a collection of application singleton libraries.
4
+
5
+ == Download
6
+
7
+ The latest version of Ghaki App can be found at
8
+
9
+ * git@github.com:ghaki/ghaki-account.git
10
+
11
+ == Installation
12
+
13
+ The preferred method of installing Ghaki App is through its GEM file.
14
+
15
+ % [sudo] gem install ghaki-app-0.0.1.gem
16
+
17
+ == License
18
+
19
+ Ghaki App is released under the MIT license.
20
+
21
+ == Support
22
+
23
+ Contact mailto:gerald@kalafut.org
@@ -0,0 +1,19 @@
1
+ require 'singleton'
2
+
3
+ module Ghaki #:nodoc:
4
+ module App #:nodoc:
5
+
6
+ # Singleton application engine.
7
+ #
8
+ # This is a unified loading place for application level singletons.
9
+ #
10
+ # ==== Examples
11
+ #
12
+ # require 'ghaki/app/engine'
13
+ # app = Ghaki::App::Engine.instance
14
+
15
+ class Engine
16
+ include Singleton
17
+ end
18
+
19
+ end end
@@ -0,0 +1,78 @@
1
+ module Ghaki #:nodoc:
2
+ module App #:nodoc:
3
+
4
+ module Mixable #:nodoc:
5
+ # ==== Examples
6
+ #
7
+ # require 'ghaki/app/plugin'
8
+ # require 'ghaki/app/mixer'
9
+ #
10
+ # class Duck
11
+ # attr_accessor :quack
12
+ # end
13
+ #
14
+ # class DuckApp < Ghaki::App::Plugin
15
+ # app_plugin_accessor Duck, :duck
16
+ # end
17
+ #
18
+ # class DuckMixin
19
+ # include Ghaki::App::Mixable
20
+ # app_mixin_accessor DuckApp, :duck
21
+ # end
22
+ #
23
+ # class UsingDuck
24
+ # include DuckMixin
25
+ # def quacker
26
+ # duck.quack = true
27
+ # end
28
+ # end
29
+
30
+ module ClassMethods
31
+
32
+ # Generate mixin attribute reader.
33
+ # Uses the singleton copy unless overwritten by the writer.
34
+
35
+ def app_mixin_reader klass, source, target=source
36
+ if klass.respond_to?(:instance)
37
+ class_eval <<-"END"
38
+ def #{target}
39
+ @#{target} ||= #{klass}.instance.#{source}
40
+ end
41
+ END
42
+ func = :instance
43
+ elsif klass.respond_to?(:new)
44
+ class_eval <<-"END"
45
+ def #{target}
46
+ @#{target} ||= #{klass}.new
47
+ end
48
+ END
49
+ else
50
+ raise ArgumentError, "Unknown Constructor: #{klass}"
51
+ end
52
+ end
53
+
54
+ # Generate mixin attribute writer.
55
+ # Allows the local copy of the singleton value to be overriden.
56
+
57
+ def app_mixin_writer target
58
+ class_exec do
59
+ attr_writer target
60
+ end
61
+ end
62
+
63
+ # Generate attribute reader and writer.
64
+
65
+ def app_mixin_accessor klass, source, target=source
66
+ app_mixin_reader klass, source, target
67
+ app_mixin_writer target
68
+ end
69
+
70
+ end
71
+
72
+ def self.included klass #:nodoc:
73
+ klass.extend ClassMethods
74
+ end
75
+
76
+ end
77
+
78
+ end end
@@ -0,0 +1,62 @@
1
+ require 'ghaki/app/engine'
2
+
3
+ module Ghaki #:nodoc:
4
+ module App #:nodoc:
5
+
6
+ module Mixer #:nodoc:
7
+
8
+ # Allows customizable engine mixin name.
9
+ #
10
+ # ==== Example
11
+ #
12
+ # require 'ghaki/app/mixer'
13
+ #
14
+ # class MyWidget
15
+ #
16
+ # include Ghaki::App::Mixer
17
+ # app_engine_mixin :sys_app
18
+ #
19
+ # def do_something
20
+ # sys_app.logger.info 'doing something'
21
+ # end
22
+ #
23
+ # end
24
+
25
+ module ClassMethods
26
+
27
+ # Generate engine mixin reader in eigen class.
28
+
29
+ def app_engine_eigen_mixin name
30
+ class_eval <<-"END"
31
+ def self.#{name}
32
+ Ghaki::App::Engine.instance
33
+ end
34
+ END
35
+ end
36
+
37
+ # Generate engine mixin reader in class.
38
+
39
+ def app_engine_class_mixin name
40
+ class_eval <<-"END"
41
+ def #{name}
42
+ Ghaki::App::Engine.instance
43
+ end
44
+ END
45
+ end
46
+
47
+ # Generate engine mixins in both the class and eigen class.
48
+
49
+ def app_engine_mixin name
50
+ app_engine_eigen_mixin name
51
+ app_engine_class_mixin name
52
+ end
53
+
54
+ end
55
+
56
+ def self.included klass #:nodoc:
57
+ klass.extend ClassMethods
58
+ end
59
+
60
+ end
61
+
62
+ end end
@@ -0,0 +1,46 @@
1
+ require 'ghaki/app/mixer'
2
+
3
+ module Ghaki #:nodoc:
4
+ module App #:nodoc:
5
+
6
+ # Default engine mixin name.
7
+ #
8
+ # ==== Example
9
+ #
10
+ # require 'ghaki/app/mixin'
11
+ #
12
+ # class MyWidget
13
+ # include Ghaki::App::Mixin
14
+ #
15
+ # def do_something
16
+ # app.logger.info 'did something'
17
+ # end
18
+ # end
19
+ #
20
+ # class OtherWidget
21
+ # extend Ghaki::App::Mixin
22
+ #
23
+ # def self.do_something
24
+ # app.logger.info 'did something else'
25
+ # end
26
+ # end
27
+
28
+ module Mixin
29
+
30
+ def self.included klass #:nodoc:
31
+ klass.class_exec do
32
+ include Ghaki::App::Mixer
33
+ app_engine_class_mixin :app
34
+ end
35
+ end
36
+
37
+ def self.extended klass #:nodoc:
38
+ klass.class_exec do
39
+ include Ghaki::App::Mixer
40
+ app_engine_eigen_mixin :app
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ end end
@@ -0,0 +1,77 @@
1
+ require 'singleton'
2
+ require 'ghaki/app/engine'
3
+
4
+ module Ghaki #:nodoc:
5
+ module App #:nodoc:
6
+
7
+ # Singleton application plugin.
8
+ #
9
+ # ==== Examples
10
+ #
11
+ # require 'ghaki/app/plugin'
12
+ #
13
+ # class Widget
14
+ # attr_accessor :size
15
+ # def initialize opts={}
16
+ # @size = opts[:size]
17
+ # end
18
+ # end
19
+ #
20
+ # class WidgetApp < Ghaki::App::Plugin
21
+ # app_plugin_make Widget, :widget
22
+ # end
23
+ #
24
+ # # Default plugin constructor options.
25
+ # WidgetApp.instance.widget_defs = {
26
+ # :size => 20,
27
+ # }
28
+ #
29
+ # # Actual plugin constructor options.
30
+ # WidgetApp.instance.widget_opts = {
31
+ # :size => 10,
32
+ # }
33
+ #
34
+ # # Generated plugin has set value.
35
+ # WidgetApp.instance.widget.size #=> 10
36
+
37
+ class Plugin
38
+ include Singleton
39
+
40
+ protected
41
+
42
+ # Generates attribute functions for the plugin class,
43
+ # constructor options, and default constructor options.
44
+
45
+ def self.app_plugin_make klass, name
46
+ opts = "#{name}_opts".to_sym
47
+ defs = "#{name}_defs".to_sym
48
+ class_eval <<-"END"
49
+ attr_writer :#{defs}, :#{opts}, :#{name}
50
+ def #{defs}
51
+ @#{defs} ||= {}
52
+ end
53
+ def #{opts}
54
+ @#{opts} ||= self.#{defs}
55
+ end
56
+ def #{name}
57
+ @#{name} ||= #{klass}.new( self.#{opts} )
58
+ end
59
+ END
60
+ end
61
+
62
+ # Links the plugin singleton with the engine singleton.
63
+
64
+ def self.app_plugin_link source, target=source
65
+ inst = "#{self}.instance"
66
+ Ghaki::App::Engine.class_eval <<-"END"
67
+ def #{target}_defs ; #{inst}.#{source}_defs end
68
+ def #{target}_defs= val ; #{inst}.#{source}_defs= val end
69
+ def #{target}_opts ; #{inst}.#{source}_opts end
70
+ def #{target}_opts= val ; #{inst}.#{source}_opts= val end
71
+ def #{target} ; #{inst}.#{source} end
72
+ def #{target}= val ; #{inst}.#{source}= val end
73
+ END
74
+ end
75
+
76
+ end
77
+ end end
@@ -0,0 +1,6 @@
1
+ require 'ghaki/app/engine'
2
+
3
+ describe Ghaki::App::Engine do
4
+ subject { Ghaki::App::Engine }
5
+ it { should respond_to :instance }
6
+ end
@@ -0,0 +1,83 @@
1
+ require 'ghaki/app/plugin'
2
+ require 'ghaki/app/mixable'
3
+
4
+ describe Ghaki::App::Mixable do
5
+
6
+ class UsingMixable
7
+ include Ghaki::App::Mixable
8
+ end
9
+
10
+ describe 'class using include' do
11
+ subject { UsingMixable }
12
+ it { should respond_to :app_mixin_reader }
13
+ it { should respond_to :app_mixin_writer }
14
+ it { should respond_to :app_mixin_accessor }
15
+ end
16
+
17
+ class Cow
18
+ def initialize opts={} ; end
19
+ end
20
+
21
+ class TheCow < Ghaki::App::Plugin
22
+ app_plugin_make Cow, :cow
23
+ app_plugin_link :cow
24
+ end
25
+
26
+ describe '#app_mixin_reader' do
27
+
28
+ context 'using source only' do
29
+ class UsingReaderSourceOnly
30
+ include Ghaki::App::Mixable
31
+ app_mixin_reader TheCow, :cow
32
+ end
33
+ subject { UsingReaderSourceOnly.new }
34
+ it { should respond_to :cow }
35
+ it { subject.cow.should be_an_instance_of(Cow) }
36
+ end
37
+
38
+ context 'using source and target' do
39
+ class UsingReaderSourceAndTarget
40
+ include Ghaki::App::Mixable
41
+ app_mixin_reader TheCow, :cow, :bull
42
+ end
43
+ subject { UsingReaderSourceAndTarget.new }
44
+ it { should respond_to :bull }
45
+ it { subject.bull.should be_an_instance_of(Cow) }
46
+ end
47
+
48
+ end
49
+
50
+ describe '#app_mixin_writer' do
51
+ class UsingWriter
52
+ include Ghaki::App::Mixable
53
+ app_mixin_writer :cow
54
+ end
55
+ subject { UsingWriter.new }
56
+ it { should respond_to :cow= }
57
+ end
58
+
59
+ describe '#app_mixin_accessor' do
60
+
61
+ context 'using source only' do
62
+ class UsingAccessorSourceOnly
63
+ include Ghaki::App::Mixable
64
+ app_mixin_accessor Cow, :cow
65
+ end
66
+ subject { UsingAccessorSourceOnly.new }
67
+ it { should respond_to :cow }
68
+ it { should respond_to :cow= }
69
+ end
70
+
71
+ context 'using source and target' do
72
+ class UsingAccessorSourceAndTarget
73
+ include Ghaki::App::Mixable
74
+ app_mixin_accessor Cow, :cow, :bull
75
+ end
76
+ subject { UsingAccessorSourceAndTarget.new }
77
+ it { should respond_to :bull }
78
+ it { should respond_to :bull= }
79
+ end
80
+
81
+ end
82
+
83
+ end
@@ -0,0 +1,53 @@
1
+ require 'ghaki/app/mixer'
2
+
3
+ describe Ghaki::App::Mixer do
4
+
5
+ class TestUsing
6
+ include Ghaki::App::Mixer
7
+ end
8
+
9
+ context 'class using include' do
10
+ subject { TestUsing }
11
+ it { should respond_to :app_engine_eigen_mixin }
12
+ it { should respond_to :app_engine_class_mixin }
13
+ it { should respond_to :app_engine_mixin }
14
+ end
15
+
16
+ context 'using eigen mixin' do
17
+ class TestEigen
18
+ include Ghaki::App::Mixer
19
+ app_engine_eigen_mixin :app_eigen
20
+ end
21
+ subject { TestEigen }
22
+ it { should respond_to :app_eigen }
23
+ end
24
+
25
+ context 'using class mixin' do
26
+ class TestKlass
27
+ include Ghaki::App::Mixer
28
+ app_engine_class_mixin :app_klass
29
+ end
30
+ subject { TestKlass.new }
31
+ it { should respond_to :app_klass }
32
+ end
33
+
34
+ context 'using mixed mixin' do
35
+
36
+ class TestMixed
37
+ include Ghaki::App::Mixer
38
+ app_engine_mixin :app_mixed
39
+ end
40
+
41
+ context 'with eigen access' do
42
+ subject { TestMixed }
43
+ it { should respond_to :app_mixed }
44
+ end
45
+
46
+ context 'with class access' do
47
+ subject { TestMixed.new }
48
+ it { should respond_to :app_mixed }
49
+ end
50
+
51
+ end
52
+
53
+ end
@@ -0,0 +1,21 @@
1
+ require 'ghaki/app/mixin'
2
+
3
+ describe Ghaki::App::Mixin do
4
+
5
+ describe 'using include' do
6
+ class TestInclude
7
+ include Ghaki::App::Mixin
8
+ end
9
+ subject { TestInclude.new }
10
+ it { should respond_to :app }
11
+ end
12
+
13
+ describe 'using extend' do
14
+ class TestExtend
15
+ extend Ghaki::App::Mixin
16
+ end
17
+ subject { TestExtend }
18
+ it { should respond_to :app }
19
+ end
20
+
21
+ end
@@ -0,0 +1,76 @@
1
+ require 'ghaki/app/plugin'
2
+
3
+ describe Ghaki::App::Plugin do
4
+
5
+ describe 'class extended by' do
6
+ class UsingPlugin < Ghaki::App::Plugin ; end
7
+ subject { UsingPlugin }
8
+ it { should respond_to :app_plugin_make }
9
+ it { should respond_to :app_plugin_link }
10
+ end
11
+
12
+
13
+ describe '#app_plugin_make' do
14
+ class Chicken
15
+ def initialize opts={}; end
16
+ end
17
+ class ChickenApp < Ghaki::App::Plugin
18
+ app_plugin_make Chicken, :chicken
19
+ end
20
+ subject { ChickenApp.instance }
21
+ context 'using source <chicken>' do
22
+ context 'generates plugin' do
23
+ it { should respond_to :chicken }
24
+ it { should respond_to :chicken= }
25
+ it { should respond_to :chicken_opts }
26
+ it { should respond_to :chicken_opts= }
27
+ it { should respond_to :chicken_defs }
28
+ it { should respond_to :chicken_defs= }
29
+ it { subject.chicken.should be_an_instance_of(Chicken) }
30
+ end
31
+ end
32
+ end
33
+
34
+ class Cow
35
+ def initialize opts={}; end
36
+ end
37
+
38
+ describe '#app_plugin_link' do
39
+
40
+ context 'using source only <cow>' do
41
+ class CowSourceOnly < Ghaki::App::Plugin
42
+ app_plugin_make Cow, :cow
43
+ app_plugin_link :cow
44
+ end
45
+ context 'generates plugin' do
46
+ subject { CowSourceOnly.instance }
47
+ it { should respond_to :cow }
48
+ it { subject.cow.should be_an_instance_of(Cow) }
49
+ end
50
+ context 'updates engine' do
51
+ subject { Ghaki::App::Engine.instance }
52
+ it { should respond_to :cow }
53
+ it { subject.cow.should be_an_instance_of(Cow) }
54
+ end
55
+ end
56
+
57
+ context 'using source <cow> and target <bull>' do
58
+ class CowSourceAndTarget < Ghaki::App::Plugin
59
+ app_plugin_make Cow, :cow
60
+ app_plugin_link :cow, :bull
61
+ end
62
+ context 'generates plugin' do
63
+ subject { CowSourceAndTarget.instance }
64
+ it { should respond_to :cow }
65
+ it { subject.cow.should be_an_instance_of(Cow) }
66
+ end
67
+ context 'updates engine' do
68
+ subject { Ghaki::App::Engine.instance }
69
+ it { should respond_to :bull }
70
+ it { subject.bull.should be_an_instance_of(Cow) }
71
+ end
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,6 @@
1
+ require 'mocha'
2
+
3
+ RSpec.configure do |cfg|
4
+ cfg.mock_with :mocha
5
+ cfg.color_enabled = true
6
+ end
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ghaki-app
3
+ version: !ruby/object:Gem::Version
4
+ version: 2011.11.29.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Gerald Kalafut
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-11-30 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &73486440 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 2.4.0
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *73486440
25
+ - !ruby/object:Gem::Dependency
26
+ name: rdoc
27
+ requirement: &73486210 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 3.9.4
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *73486210
36
+ - !ruby/object:Gem::Dependency
37
+ name: mocha
38
+ requirement: &73485980 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 0.9.12
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *73485980
47
+ description: Collection of application singleton libraries.
48
+ email: gerald@kalafut.org
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files:
52
+ - README
53
+ files:
54
+ - lib/ghaki/app/engine.rb
55
+ - lib/ghaki/app/plugin.rb
56
+ - lib/ghaki/app/mixin.rb
57
+ - lib/ghaki/app/mixer.rb
58
+ - lib/ghaki/app/mixable.rb
59
+ - README
60
+ - LICENSE
61
+ - spec/ghaki/app/plugin_spec.rb
62
+ - spec/ghaki/app/mixer_spec.rb
63
+ - spec/ghaki/app/mixin_spec.rb
64
+ - spec/ghaki/app/mixable_spec.rb
65
+ - spec/ghaki/app/engine_spec.rb
66
+ - spec/spec_helper.rb
67
+ homepage: http://github.com/ghaki
68
+ licenses: []
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ! '>='
83
+ - !ruby/object:Gem::Version
84
+ version: 1.3.6
85
+ requirements: []
86
+ rubyforge_project: ghaki-app
87
+ rubygems_version: 1.8.10
88
+ signing_key:
89
+ specification_version: 3
90
+ summary: Application singleton helpers
91
+ test_files:
92
+ - spec/ghaki/app/plugin_spec.rb
93
+ - spec/ghaki/app/mixer_spec.rb
94
+ - spec/ghaki/app/mixin_spec.rb
95
+ - spec/ghaki/app/mixable_spec.rb
96
+ - spec/ghaki/app/engine_spec.rb
97
+ - spec/spec_helper.rb