opal-eventable 0.0.1

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.
@@ -0,0 +1,2 @@
1
+ .DS_Store
2
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
@@ -0,0 +1,76 @@
1
+ # opal-eventable
2
+
3
+ An eventable module for opal (and ruby) applications.
4
+
5
+ ## Installation
6
+
7
+ Add to your Gemfile:
8
+
9
+ ```ruby
10
+ gem "opal-eventable"
11
+ ```
12
+
13
+ Then, inside your opal code:
14
+
15
+ ```ruby
16
+ require "opal-eventable"
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ```ruby
22
+ require "opal-eventable"
23
+
24
+ class Person
25
+ include Eventable
26
+
27
+ def name=(name)
28
+ @name = name
29
+ trigger(:change_name, name)
30
+ end
31
+
32
+ def sign_in
33
+ @signed_in = true
34
+ trigger(:sign_in)
35
+ end
36
+
37
+ end
38
+
39
+ p = Person.new
40
+
41
+ p.on(:change_name) { |old, new| puts "changed name from #{old.inspect} to #{new.inspect}" }
42
+ p.on(:sign_in) { puts "signed in!" }
43
+
44
+ p.name = "Adam"
45
+ p.sign_in
46
+ p.name = "Ben"
47
+
48
+ # prints:
49
+ # changed name from nil to "Adam"
50
+ # signed in!
51
+ # changed name from "Adam" to "Ben"
52
+ ```
53
+
54
+ ## License
55
+
56
+ (The MIT License)
57
+
58
+ Copyright (C) 2013 by Adam Beynon
59
+
60
+ Permission is hereby granted, free of charge, to any person obtaining a copy
61
+ of this software and associated documentation files (the "Software"), to deal
62
+ in the Software without restriction, including without limitation the rights
63
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
64
+ copies of the Software, and to permit persons to whom the Software is
65
+ furnished to do so, subject to the following conditions:
66
+
67
+ The above copyright notice and this permission notice shall be included in
68
+ all copies or substantial portions of the Software.
69
+
70
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
71
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
72
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
73
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
74
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
75
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
76
+ THE SOFTWARE.
@@ -0,0 +1,5 @@
1
+ require 'bundler'
2
+ Bundler.require
3
+
4
+ require 'opal/spec/rake_task'
5
+ Opal::Spec::RakeTask.new(:default)
@@ -0,0 +1,5 @@
1
+ require 'opal'
2
+ require 'opal-eventable/version'
3
+
4
+ # Just register our opal code path with opal build tools
5
+ Opal.append_path File.expand_path('../../opal', __FILE__)
@@ -0,0 +1,3 @@
1
+ module OpalEventable
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1 @@
1
+ require 'opal-eventable'
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $LOAD_PATH << File.expand_path('../lib', __FILE__)
3
+ require 'opal-eventable/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'opal-eventable'
7
+ s.version = OpalEventable::VERSION
8
+ s.author = 'Adam Beynon'
9
+ s.email = 'adam.beynon@gmail.com'
10
+ s.homepage = 'http://opalrb.org'
11
+ s.summary = 'Eventable module for Opal.'
12
+ s.description = 'Eventable module for Opal'
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.require_paths = ['lib']
18
+
19
+ s.add_dependency 'rake'
20
+ s.add_dependency 'opal', '~> 0.3.44'
21
+
22
+ s.add_development_dependency 'opal-spec'
23
+ end
@@ -0,0 +1,34 @@
1
+ # A simple event registering/triggering module to mix into classes.
2
+ # Events are stored in the `@events` ivar.
3
+ module Eventable
4
+
5
+ # Register a handler for the given event name.
6
+ #
7
+ # obj.on(:foo) { puts "foo was called" }
8
+ #
9
+ # @param [String, Symbol] name event name
10
+ # @return handler
11
+ def on(name, &handler)
12
+ @eventable ||= Hash.new { |hash, key| hash[key] = [] }
13
+ @eventable[name] << handler
14
+ handler
15
+ end
16
+
17
+ def off(name, handler)
18
+ if @eventable and evts = @eventable[name]
19
+ evts.delete handler
20
+ end
21
+ end
22
+
23
+ # Trigger the given event name and passes all args to each handler
24
+ # for this event.
25
+ #
26
+ # obj.trigger(:foo)
27
+ # obj.trigger(:foo, 1, 2, 3)
28
+ #
29
+ # @param [String, Symbol] name event name to trigger
30
+ def trigger(name, *args)
31
+ @eventable ||= Hash.new { |hash, key| hash[key] = [] }
32
+ @eventable[name].each { |handler| handler.call(*args) }
33
+ end
34
+ end
@@ -0,0 +1,94 @@
1
+ require 'opal-eventable'
2
+
3
+ class EventableSpec
4
+ include Eventable
5
+
6
+ def events
7
+ @eventable
8
+ end
9
+ end
10
+
11
+ describe Eventable do
12
+
13
+ let(:obj) { EventableSpec.new }
14
+
15
+ describe "#on" do
16
+ it "should register event handlers for given name" do
17
+ handler = Proc.new {}
18
+ obj.on(:foo, &handler)
19
+ obj.events[:foo].should == [handler]
20
+ end
21
+
22
+ it "returns the given handler" do
23
+ handler = Proc.new {}
24
+ obj.on(:foo, &handler).should eq(handler)
25
+ end
26
+ end
27
+
28
+ describe "#off" do
29
+ it "has no affect if no handlers defined at all" do
30
+ obj.off(:bar, proc {})
31
+ obj.on(:foo) { raise "err" }
32
+ obj.off(:bar, proc {})
33
+ end
34
+
35
+ it "removes the handler for the event" do
36
+ called = false
37
+ handler = obj.on(:foo) { called = true }
38
+
39
+ obj.off(:foo, handler)
40
+ obj.trigger(:foo)
41
+ called.should be_false
42
+ end
43
+ end
44
+
45
+ describe "#trigger" do
46
+ it "should call handler" do
47
+ called = false
48
+
49
+ obj.on(:foo) { called = true }
50
+ called.should == false
51
+
52
+ obj.trigger(:foo)
53
+ called.should == true
54
+ end
55
+
56
+ it "should pass all arguments to handler" do
57
+ args = nil
58
+ obj.on(:foo) { |*a| args = a }
59
+
60
+ obj.trigger(:foo)
61
+ args.should == []
62
+
63
+ obj.trigger(:foo, 1)
64
+ args.should == [1]
65
+
66
+ obj.trigger(:foo, 1, 2, 3)
67
+ args.should == [1, 2, 3]
68
+ end
69
+
70
+ it "should allow multiple different events to be registered" do
71
+ result = []
72
+ obj.on(:foo) { result << :foo }
73
+ obj.on(:bar) { result << :bar }
74
+
75
+ obj.trigger(:foo)
76
+ result.should == [:foo]
77
+
78
+ obj.trigger(:bar)
79
+ result.should == [:foo, :bar]
80
+ end
81
+
82
+ it "should allow multiple handlers for an event" do
83
+ count = 0
84
+
85
+ obj.on(:foo) { count += 1 }
86
+ obj.on(:foo) { count += 1 }
87
+ obj.on(:foo) { count += 1 }
88
+ obj.on(:foo) { count += 1 }
89
+ obj.trigger(:foo)
90
+
91
+ count.should == 4
92
+ end
93
+ end
94
+ end
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: opal-eventable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Adam Beynon
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-06-12 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: opal
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 0.3.44
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.3.44
46
+ - !ruby/object:Gem::Dependency
47
+ name: opal-spec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Eventable module for Opal
63
+ email: adam.beynon@gmail.com
64
+ executables: []
65
+ extensions: []
66
+ extra_rdoc_files: []
67
+ files:
68
+ - .gitignore
69
+ - Gemfile
70
+ - README.md
71
+ - Rakefile
72
+ - lib/opal-eventable.rb
73
+ - lib/opal-eventable/version.rb
74
+ - lib/opal/eventable.rb
75
+ - opal-eventable.gemspec
76
+ - opal/opal-eventable.rb
77
+ - spec/eventable_spec.rb
78
+ homepage: http://opalrb.org
79
+ licenses: []
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ requirements: []
97
+ rubyforge_project:
98
+ rubygems_version: 1.8.23
99
+ signing_key:
100
+ specification_version: 3
101
+ summary: Eventable module for Opal.
102
+ test_files:
103
+ - spec/eventable_spec.rb