shuber-interface 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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