shuber-interface 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Sean Huber - shuber@huberry.com
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,56 @@
1
+ = interface
2
+
3
+ Implementable interfaces in ruby
4
+
5
+
6
+ == Installation
7
+
8
+ gem install shuber-interface
9
+
10
+ require 'interface'
11
+
12
+
13
+ == Usage
14
+
15
+ Simply create a module with any methods that you'd like its implementing objects to define
16
+
17
+ module RemoteControl
18
+ # turns the device on
19
+ def on
20
+ end
21
+
22
+ # turns the device off
23
+ def off
24
+ end
25
+ end
26
+
27
+ Then use the <tt>implements</tt> method in your classes (also aliased as <tt>implement</tt> to conform with <tt>include</tt> and <tt>extend</tt> naming conventions)
28
+
29
+ class BrokenDevice
30
+ implements RemoteControl
31
+ end
32
+
33
+ BrokenDevice.new.on # NotImplementedError: BrokenDevice needs to implement 'on' for interface RemoteControl
34
+
35
+ class WorkingDevice < BrokenDevice
36
+ def on
37
+ @power = true
38
+ end
39
+
40
+ def off
41
+ @power = false
42
+ end
43
+ end
44
+
45
+ WorkingDevice.new.on # true
46
+
47
+ WorkingDevice.interfaces # [RemoteControl]
48
+
49
+
50
+ == Note on Patches/Pull Requests
51
+
52
+ * Fork the project.
53
+ * Make your feature addition or bug fix.
54
+ * Add tests for it. This is important so I don't break it in a future version unintentionally.
55
+ * Commit, do not mess with Rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
56
+ * Send me a pull request. Bonus points for topic branches.
data/Rakefile ADDED
@@ -0,0 +1,22 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the interface gem.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs += ['lib', 'test']
11
+ t.pattern = 'test/**/*_test.rb'
12
+ t.verbose = true
13
+ end
14
+
15
+ desc 'Generate documentation for the interface gem.'
16
+ Rake::RDocTask.new(:rdoc) do |rdoc|
17
+ rdoc.rdoc_dir = 'rdoc'
18
+ rdoc.title = 'interface'
19
+ rdoc.options << '--line-numbers' << '--inline-source'
20
+ rdoc.rdoc_files.include('README*')
21
+ rdoc.rdoc_files.include('lib/**/*.rb')
22
+ end
@@ -0,0 +1,12 @@
1
+ module Interface
2
+ # When extended, this abstract interface will re-define an object's methods to raise <tt>NotImplementedError</tt> when called
3
+ module Abstract
4
+ def self.extended(base) # :nodoc:
5
+ base.class_eval do
6
+ instance_methods(false).each do |method|
7
+ define_method(method) { |*args| raise NotImplementedError.new("#{self.class} needs to implement '#{method}' for interface #{base}") }
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ module Interface
2
+ # Contains information about this gem's version
3
+ module Version
4
+ MAJOR = 0
5
+ MINOR = 0
6
+ PATCH = 0
7
+
8
+ # Returns a version string by joining <tt>MAJOR</tt>, <tt>MINOR</tt>, and <tt>PATCH</tt> with <tt>'.'</tt>
9
+ #
10
+ # Example
11
+ #
12
+ # Interface::Version.string # '1.0.2'
13
+ def self.string
14
+ [MAJOR, MINOR, PATCH].join('.')
15
+ end
16
+ end
17
+ end
data/lib/interface.rb ADDED
@@ -0,0 +1,36 @@
1
+ # Implementable interfaces in ruby
2
+ module Interface
3
+ autoload :Abstract, 'interface/abstract'
4
+ autoload :Version, 'interface/version'
5
+
6
+ # Takes a module (or multiple in reverse order), extends it with <tt>Interface::Abstract</tt>, then includes it into the current object
7
+ #
8
+ # Example
9
+ #
10
+ # module Remote
11
+ # # turns the device on
12
+ # def on
13
+ # end
14
+ # end
15
+ #
16
+ # class Device
17
+ # implements Remote
18
+ #
19
+ # def on
20
+ # @power = true
21
+ # end
22
+ # end
23
+ def implements(*modules)
24
+ modules.flatten.reverse!.each { |mod| include mod.extend(Abstract) }
25
+ end
26
+
27
+ # Conforms with naming conventions for include and extend
28
+ alias_method :implement, :implements
29
+
30
+ # Returns an array of interfaces implemented by the current object
31
+ def interfaces
32
+ included_modules.select { |mod| mod.is_a?(Abstract) }
33
+ end
34
+ end
35
+
36
+ Object.send(:include, Interface)
@@ -0,0 +1 @@
1
+ require 'interface'
@@ -0,0 +1,45 @@
1
+ require 'test_helper'
2
+
3
+ module MockModule end
4
+ module MockInterface end
5
+
6
+ module Remote
7
+ def on
8
+ end
9
+ end
10
+
11
+ class BrokenDevice
12
+ implements Remote, MockInterface
13
+ end
14
+
15
+ class Device < BrokenDevice
16
+ include MockModule
17
+
18
+ def on
19
+ @power = true
20
+ end
21
+ end
22
+
23
+ class InterfaceTest < Test::Unit::TestCase
24
+
25
+ def test_should_include_interface
26
+ assert BrokenDevice.included_modules.include?(Remote)
27
+ end
28
+
29
+ def test_interface_should_include_abstract
30
+ assert Remote.is_a?(Interface::Abstract)
31
+ end
32
+
33
+ def test_should_raise_not_implemented_error
34
+ assert_raises(NotImplementedError) { BrokenDevice.new.on }
35
+ end
36
+
37
+ def test_should_not_raise_not_implemented_error
38
+ assert Device.new.on
39
+ end
40
+
41
+ def test_should_return_interfaces
42
+ assert_equal [Remote, MockInterface], Device.interfaces
43
+ end
44
+
45
+ end
@@ -0,0 +1,5 @@
1
+ require 'test/unit'
2
+
3
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
+ $:.unshift(File.dirname(__FILE__))
5
+ require 'interface'
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: shuber-interface
3
+ version: !ruby/object:Gem::Version
4
+ hash: 31
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 0
10
+ version: 0.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Sean Huber
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-02-08 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Implementable interfaces in ruby
23
+ email: shuber@huberry.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - lib/interface.rb
32
+ - lib/interface/abstract.rb
33
+ - lib/interface/version.rb
34
+ - lib/shuber-interface.rb
35
+ - MIT-LICENSE
36
+ - Rakefile
37
+ - README.rdoc
38
+ - test/interface_test.rb
39
+ - test/test_helper.rb
40
+ has_rdoc: true
41
+ homepage: http://github.com/shuber/interface
42
+ licenses: []
43
+
44
+ post_install_message:
45
+ rdoc_options:
46
+ - --line-numbers
47
+ - --inline-source
48
+ - --main
49
+ - README.rdoc
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ hash: 3
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ requirements: []
71
+
72
+ rubyforge_project:
73
+ rubygems_version: 1.5.0
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: Implementable interfaces in ruby
77
+ test_files:
78
+ - test/interface_test.rb
79
+ - test/test_helper.rb