termtter 1.7.2 → 1.8.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.
Files changed (81) hide show
  1. data/.gitignore +1 -1
  2. data/README.rdoc +1 -0
  3. data/Rakefile +2 -1
  4. data/VERSION +1 -1
  5. data/bin/termtter +1 -0
  6. data/bin/termtter_frame +134 -0
  7. data/lib/plugins/aa.rb +44 -0
  8. data/lib/plugins/another_prompt.rb +42 -41
  9. data/lib/plugins/appendtitle.rb +82 -0
  10. data/lib/plugins/ar.rb +11 -8
  11. data/lib/plugins/async.rb +3 -2
  12. data/lib/plugins/capital_update.rb +12 -0
  13. data/lib/plugins/channel.rb +149 -0
  14. data/lib/plugins/clock.rb +10 -0
  15. data/lib/plugins/defaults/command_line.rb +8 -0
  16. data/lib/plugins/defaults/confirm.rb +1 -1
  17. data/lib/plugins/defaults/hashtag.rb +1 -1
  18. data/lib/plugins/defaults/keyword.rb +11 -0
  19. data/lib/plugins/defaults/list.rb +32 -6
  20. data/lib/plugins/defaults/standard_commands.rb +135 -52
  21. data/lib/plugins/defaults/standard_completion.rb +14 -0
  22. data/lib/plugins/defaults/stdout.rb +59 -27
  23. data/lib/plugins/defaults/user.rb +32 -0
  24. data/lib/plugins/draft.rb +9 -12
  25. data/lib/plugins/easy_post.rb +5 -0
  26. data/lib/plugins/event_invoked_at.rb +23 -0
  27. data/lib/plugins/expand-tinyurl.rb +13 -20
  28. data/lib/plugins/favotter.rb +9 -9
  29. data/lib/plugins/footer.rb +9 -12
  30. data/lib/plugins/friends.rb +0 -26
  31. data/lib/plugins/grass.rb +2 -4
  32. data/lib/plugins/growl.rb +47 -0
  33. data/lib/plugins/gyazo.rb +16 -18
  34. data/lib/plugins/hi.rb +31 -10
  35. data/lib/plugins/http_server.rb +3 -2
  36. data/lib/plugins/irc_gw.rb +71 -17
  37. data/lib/plugins/line.rb +10 -0
  38. data/lib/plugins/linefeed.rb +6 -1
  39. data/lib/plugins/list_switch.rb +76 -0
  40. data/lib/plugins/nop.rb +9 -0
  41. data/lib/plugins/notify-send.rb +1 -1
  42. data/lib/plugins/notify-send2.rb +25 -16
  43. data/lib/plugins/notify-send3.rb +16 -13
  44. data/lib/plugins/nuance.rb +29 -0
  45. data/lib/plugins/open_url.rb +1 -5
  46. data/lib/plugins/random.rb +2 -6
  47. data/lib/plugins/reply_sound.rb +33 -0
  48. data/lib/plugins/say.rb +2 -2
  49. data/lib/plugins/storage/sqlite3.rb +1 -1
  50. data/lib/plugins/story.rb +44 -0
  51. data/lib/plugins/tinyurl.rb +50 -29
  52. data/lib/plugins/translate_tweet.rb +38 -0
  53. data/lib/plugins/web.rb +27 -0
  54. data/lib/termtter.rb +8 -4
  55. data/lib/termtter/client.rb +17 -21
  56. data/lib/termtter/command.rb +35 -13
  57. data/lib/termtter/config.rb +13 -0
  58. data/lib/termtter/config_template.erb +3 -2
  59. data/lib/termtter/default_config.rb +2 -2
  60. data/lib/termtter/event.rb +69 -0
  61. data/lib/termtter/hook.rb +6 -1
  62. data/lib/termtter/hookable.rb +9 -1
  63. data/lib/termtter/httppool.rb +17 -9
  64. data/lib/termtter/optparse.rb +11 -1
  65. data/lib/termtter/rubytter_proxy.rb +21 -5
  66. data/spec/plugins/capital_update_spec.rb +9 -0
  67. data/spec/plugins/fib_spec.rb +2 -4
  68. data/spec/plugins/hi_spec.rb +9 -0
  69. data/spec/plugins/tinyurl_spec.rb +78 -0
  70. data/spec/termtter/client_spec.rb +5 -12
  71. data/spec/termtter/command_spec.rb +22 -10
  72. data/spec/termtter/config_spec.rb +23 -0
  73. data/spec/termtter/event_spec.rb +129 -0
  74. data/spec/termtter/optparse_spec.rb +2 -2
  75. data/spec/termtter/rubytter_proxy_spec.rb +1 -1
  76. metadata +39 -8
  77. data/bin/kill_termtter +0 -22
  78. data/lib/plugins/defaults/users.rb +0 -63
  79. data/lib/plugins/pause.rb +0 -3
  80. data/test/friends_timeline.json +0 -5
  81. data/test/search.json +0 -8
@@ -4,13 +4,19 @@ require 'net/http'
4
4
  module Termtter
5
5
  module HTTPpool
6
6
  @@connections = {}
7
+ @@http_class = nil
7
8
 
8
9
  def self.start(host, port = 80)
10
+ count = config.retry || 3
9
11
  begin
10
12
  yield(connection(host, port))
11
13
  rescue EOFError
12
14
  finish(host, port)
13
- retry
15
+ if count > 0
16
+ count -= 1
17
+ retry
18
+ end
19
+ raise
14
20
  end
15
21
  end
16
22
 
@@ -30,14 +36,16 @@ module Termtter
30
36
  end
31
37
 
32
38
  def self.http_class
33
- if config.proxy.host.nil? or config.proxy.host.empty?
34
- Net::HTTP
35
- else
36
- Net::HTTP::Proxy(config.proxy.host,
37
- config.proxy.port,
38
- config.proxy.user_name,
39
- config.proxy.password)
40
- end
39
+ @@http_class ||=
40
+ if config.proxy.host.nil? or config.proxy.host.empty?
41
+ Net::HTTP
42
+ else
43
+ Net::HTTP::Proxy(
44
+ config.proxy.host,
45
+ config.proxy.port,
46
+ config.proxy.user_name,
47
+ config.proxy.password)
48
+ end
41
49
  end
42
50
 
43
51
  end
@@ -9,6 +9,14 @@ module Termtter
9
9
  @optionparser = OptionParser.new { |opt|
10
10
  opt.program_name = 'Termtter'
11
11
 
12
+ opt.on('-f', '--config-file file', 'Set path to configfile') do |val|
13
+ Termtter::CONF_FILE = val
14
+ end
15
+
16
+ opt.on('-t', '--termtter-directory directory', 'Set termtter directory') do |val|
17
+ Termtter::CONF_DIR = val
18
+ end
19
+
12
20
  opt.on('-d', '--devel', 'Start in developer mode') do |flg|
13
21
  config.__assign__(:devel, true) if flg
14
22
  end
@@ -39,7 +47,9 @@ module Termtter
39
47
  class << self
40
48
  alias parse_orig parse
41
49
  def parse(o)
42
- o.gsub(/<.+?>(.*?)<\/.+?>/, '\1')
50
+ o.gsub(/<\/?.+?>/, '').
51
+ gsub('&lt;', '<').
52
+ gsub('&gt;', '>')
43
53
  end
44
54
  end
45
55
  end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  config.set_default(:memory_cache_size, 10000)
2
3
 
3
4
  module Termtter
@@ -21,11 +22,24 @@ module Termtter
21
22
  end
22
23
 
23
24
  from = Time.now
25
+ Termtter::Client.logger.debug(
26
+ "rubytter_proxy: #{method}(#{modified_args.inspect[1...-1]})")
24
27
  result = call_rubytter_or_use_cache(method, *modified_args, &block)
25
- Termtter::Client.logger.debug "rubytter_proxy: #{method}(#{modified_args.inspect[1...-1]}), %.2fsec" % (Time.now - from)
28
+ Termtter::Client.logger.debug(
29
+ "rubytter_proxy: #{method}(#{modified_args.inspect[1...-1]}), " +
30
+ "%.2fsec" % (Time.now - from))
26
31
 
27
32
  self.class.call_hooks("post_#{method}", *args)
28
33
  rescue HookCanceled
34
+ rescue TimeoutError => e
35
+ Termtter::Client.logger.debug(
36
+ "rubytter_proxy: #{method}(#{modified_args.inspect[1...-1]}) " +
37
+ "#{e.message} #{'%.2fsec' % (Time.now - from)}")
38
+ raise e
39
+ rescue => e
40
+ Termtter::Client.logger.debug(
41
+ "rubytter_proxy: #{method}(#{modified_args.inspect[1...-1]}) #{e.message}")
42
+ raise e
29
43
  end
30
44
  result
31
45
  else
@@ -46,16 +60,18 @@ module Termtter
46
60
  users_cache_store[screen_name]
47
61
  end
48
62
 
63
+ def cached_status(id)
64
+ status_cache_store[id.to_i]
65
+ end
66
+
49
67
  def call_rubytter_or_use_cache(method, *args, &block)
50
68
  case method
51
69
  when :show
52
- if status_cache_store.key?(args[0].to_i)
53
- status_cache_store[args[0].to_i]
54
- else
70
+ unless status = cached_status(args[0])
55
71
  status = call_rubytter(method, *args, &block)
56
72
  store_status_cache(status)
57
- status
58
73
  end
74
+ status
59
75
  when :home_timeline, :user_timeline, :friends_timeline, :search
60
76
  statuses = call_rubytter(method, *args, &block)
61
77
  statuses.each do |status|
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Termtter::Client, 'when the plugin capital_update is loaded' do
4
+ it 'adds command capital_update' do
5
+ Termtter::Client.should_receive(:register_command).once
6
+ Termtter::Client.plug 'capital_update'
7
+ end
8
+ end
9
+
@@ -1,14 +1,12 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  require File.dirname(__FILE__) + '/../spec_helper'
4
2
 
5
3
  describe Termtter::Client, 'when the plugin fib is loaded' do
6
- it 'should add command fib' do
4
+ it 'adds command fib' do
7
5
  Termtter::Client.should_receive(:register_command).once
8
6
  Termtter::Client.plug 'defaults/fib'
9
7
  end
10
8
 
11
- it 'should define fib method' do
9
+ it 'defines fib method' do
12
10
  Termtter::Client.plug 'defaults/fib'
13
11
  (0..10).map {|i| fib i }.should == [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
14
12
  end
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Termtter::Client, 'when the plugin hi is loaded' do
4
+ it 'adds commands such as hi and hola' do
5
+ Termtter::Client.should_receive(:register_command).at_most(9).times
6
+ Termtter::Client.plug 'hi'
7
+ end
8
+ end
9
+
@@ -0,0 +1,78 @@
1
+ #-*- coding: utf-8 -*-
2
+
3
+ require File.dirname(__FILE__) + '/../spec_helper'
4
+ require 'open-uri'
5
+ require 'uri'
6
+ require 'net/http'
7
+
8
+ describe 'plugin tinyurl' do
9
+ before do
10
+ Termtter::Client.setup_task_manager
11
+ end
12
+
13
+ it 'adds hook :tinyurl' do
14
+ Termtter::Client.should_receive(:register_hook).once
15
+ Termtter::Client.plug 'tinyurl'
16
+ #Termtter::Client.get_hook(:tinyurl).should be_a_kind_of(Hook)
17
+ #Termtter::Client.get_hook(:tinyurl).name.should == :tinyurl
18
+ end
19
+
20
+ it 'truncates url' do
21
+ Termtter::Client.register_command(
22
+ :name => :update, :alias => :u,
23
+ :exec => lambda do |url|
24
+ url.should match(/(bit\.ly|tinyurl|is\.gd)/)
25
+ open(url) do |f|
26
+ f.base_uri.to_s.should match('www.google')
27
+ end
28
+ end
29
+ )
30
+ Termtter::Client.plug 'tinyurl'
31
+ Termtter::Client.execute('update http://www.google.com/')
32
+ end
33
+
34
+ it 'truncates url with not escaped Non-ASCII characters' do
35
+ Termtter::Client.register_command(
36
+ :name => :update, :alias => :u,
37
+ :exec => lambda do |url|
38
+ url.should match(/(bit\.ly|tinyurl|is\.gd)/)
39
+ uri = URI.parse(url)
40
+ Net::HTTP.new(uri.host,uri.port) do |h|
41
+ r = h.get(uri.path)
42
+ r['Location'].should match('http://ja.wikipedia.org/wiki/%E6%B7%B1%E7%94%B0%E6%81%AD%E5%AD%90')
43
+ end
44
+ end
45
+ )
46
+ Termtter::Client.plug 'tinyurl'
47
+ Termtter::Client.execute('update http://ja.wikipedia.org/wiki/深田恭子')
48
+ end
49
+
50
+ it 'truncates url with escaped Non-ASCII characters' do
51
+ Termtter::Client.register_command(
52
+ :name => :update, :alias => :u,
53
+ :exec => lambda do |url|
54
+ url.should match(/(bit\.ly|tinyurl|is\.gd)/)
55
+ open(url) do |f|
56
+ f.base_uri.to_s.should match('http://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%88%E3%83%AA%E3%83%BC%E3%83%88%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0')
57
+ end
58
+ end
59
+ )
60
+ Termtter::Client.plug 'tinyurl'
61
+ Termtter::Client.execute('update http://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%88%E3%83%AA%E3%83%BC%E3%83%88%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0')
62
+ end
63
+
64
+ it 'truncates url with many parameters' do
65
+ Termtter::Client.register_command(
66
+ :name => :update, :alias => :u,
67
+ :exec => lambda do |url|
68
+ url.should match(/(bit\.ly|tinyurl|is\.gd)/)
69
+ open(url) do |f|
70
+ f.base_uri.to_s.should match('hl=ja&source=hp&q=ujihisa&lr=&aq=f&aqi=g4g-r6&aql=&oq=&gs_rfai=')
71
+ end
72
+ end
73
+ )
74
+ Termtter::Client.plug 'tinyurl'
75
+ Termtter::Client.execute('update http://www.google.co.jp/search?hl=ja&source=hp&q=ujihisa&lr=&aq=f&aqi=g4g-r6&aql=&oq=&gs_rfai=')
76
+
77
+ end
78
+ end
@@ -15,7 +15,6 @@ module Termtter
15
15
  it 'can run' do
16
16
  Client.should_receive(:load_config) {}
17
17
  Termtter::API.should_receive(:setup) {}
18
- Client.should_receive(:setup_logger) {}
19
18
  Client.should_receive(:load_plugins) {}
20
19
  Client.should_receive(:eval_init_block) {}
21
20
 
@@ -27,7 +26,6 @@ module Termtter
27
26
  it 'can run (eval script cannot eval)' do
28
27
  Client.stub(:load_config) {}
29
28
  Termtter::API.stub(:setup) {}
30
- Client.stub(:setup_logger) {}
31
29
  Client.stub(:load_plugins) {}
32
30
  Client.stub(:eval_init_block) {}
33
31
 
@@ -41,7 +39,6 @@ module Termtter
41
39
  it 'can run (eval script cannot eval)' do
42
40
  Client.stub(:load_config) {}
43
41
  Termtter::API.stub(:setup) {}
44
- Client.stub(:setup_logger) {}
45
42
  Client.stub(:load_plugins) {}
46
43
  Client.stub(:eval_init_block) {}
47
44
 
@@ -391,7 +388,7 @@ module Termtter
391
388
  it 'can output status (good)' do
392
389
  statuses = mock('statuses', :null_object => true)
393
390
  statuses.stub(:empty? => false, :nil? => false)
394
- event = :event
391
+ event = Termtter::Event.new(:event)
395
392
  Client.should_receive(:call_hooks).with(:pre_filter, statuses, event)
396
393
  Client.should_receive(:apply_filters_for_hook).exactly(2).times.
397
394
  with(an_instance_of(Symbol), anything, event).
@@ -425,13 +422,9 @@ module Termtter
425
422
  Client.handle_error error
426
423
  end
427
424
 
428
- it 'handle_error raise error when logger is nothing' do
429
- Client.instance_variable_set(:@logger, nil)
430
- $stderr, old = StringIO.new, $stderr
425
+ it 'handle_error raise error' do
426
+ Client.logger.should_receive(:error).with('StandardError: error')
431
427
  Client.handle_error(StandardError.new('error'))
432
- $stderr.rewind
433
- $stderr.gets.should match(/\AError: error/)
434
- $stderr = old
435
428
  end
436
429
 
437
430
  it 'cancels command by hook' do
@@ -478,14 +471,14 @@ module Termtter
478
471
  it 'can confirm before update (yes default)' do
479
472
  message = 'hello'
480
473
  Readline.should_receive(:readline).
481
- with("\"#{message}".strip + "\" [Y/n] ", false)
474
+ with("[Y/n] ", false)
482
475
  Client.confirm(message)
483
476
  end
484
477
 
485
478
  it 'can confirm before update (no default)' do
486
479
  message = 'hello'
487
480
  Readline.should_receive(:readline).
488
- with("\"#{message}".strip + "\" [N/y] ", false)
481
+ with("[N/y] ", false)
489
482
  Client.confirm(message, false)
490
483
  end
491
484
 
@@ -1,5 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  require File.dirname(__FILE__) + '/../spec_helper'
4
2
 
5
3
  module Termtter
@@ -28,6 +26,7 @@ module Termtter
28
26
  params = {
29
27
  :name => 'update',
30
28
  :aliases => ['u', 'up'],
29
+ :author => 'ujihisa',
31
30
  :exec_proc => lambda {|arg| arg },
32
31
  :completion_proc => lambda {|command, arg| %w[complete1 complete2] },
33
32
  :help => ['update,u TEXT', 'test command']
@@ -38,7 +37,7 @@ module Termtter
38
37
  describe '#pattern' do
39
38
  it 'returns command regex' do
40
39
  @command.pattern.
41
- should == /^((update|u|up)|(update|u|up)\s+(.*?))\s*$/
40
+ should == /^\s*((update|u|up)|(update|u|up)\s+(.*?))\s*$/
42
41
  end
43
42
  end
44
43
 
@@ -55,6 +54,10 @@ module Termtter
55
54
  @command.aliases.should == [:u, :up]
56
55
  end
57
56
 
57
+ it 'returns author' do
58
+ @command.author.should == 'ujihisa'
59
+ end
60
+
58
61
  it 'returns commands' do
59
62
  @command.commands.should == [:update, :u, :up]
60
63
  end
@@ -86,10 +89,10 @@ module Termtter
86
89
  ['up', true],
87
90
  ['u', true],
88
91
  ['update ', true],
89
- [' update ', false],
92
+ [' update ', true],
90
93
  ['update foo', true],
91
- [' update foo', false],
92
- [' update foo ', false],
94
+ [' update foo', true],
95
+ [' update foo ', true],
93
96
  ['u foo', true],
94
97
  ['up foo', true],
95
98
  ['upd foo', false],
@@ -148,18 +151,27 @@ module Termtter
148
151
 
149
152
  describe 'spec for split_command_line with sub command' do
150
153
  before do
151
- @command = Command.new(:name => 'foo bar')
154
+ @command = Command.new(:name => 'foo bar', :alias => 'f')
155
+ end
156
+
157
+ describe '#pattern' do
158
+ it 'returns command regex' do
159
+ @command.pattern.
160
+ should == /^\s*((foo\s+bar|f)|(foo\s+bar|f)\s+(.*?))\s*$/
161
+ end
152
162
  end
153
163
 
154
164
  it 'splits from a command line string to the command name and the arg' do
155
165
  @command.split_command_line('foo bar args').
156
166
  should == ['foo bar', 'args']
157
167
  @command.split_command_line('foo bar args').
158
- should == ['foo bar', 'args']
168
+ should == ['foo bar', 'args']
159
169
  @command.split_command_line(' foo bar args ').
160
- should == ['foo bar', 'args']
170
+ should == ['foo bar', 'args']
161
171
  @command.split_command_line(' foo foo args ').
162
- should == ['foo foo', 'args']
172
+ should == []
173
+ @command.split_command_line('f args').
174
+ should == ['f', 'args']
163
175
  end
164
176
  end
165
177
  end
@@ -8,6 +8,29 @@ module Termtter
8
8
  @config = Config.new
9
9
  end
10
10
 
11
+ describe 'freeze' do
12
+ before do
13
+ @config.foo = 'foo'
14
+ @config.__freeze__(:foo)
15
+ end
16
+
17
+ it 'can not change value' do
18
+ @config.foo = 'bar'
19
+ @config.foo.should == 'foo'
20
+ end
21
+
22
+ it 'can not clear value' do
23
+ @config.__clear__(:foo)
24
+ @config.foo.should == 'foo'
25
+ end
26
+
27
+ it 'can unfreeze' do
28
+ @config.__unfreeze__(:foo)
29
+ @config.foo = 'bar'
30
+ @config.foo.should == 'bar'
31
+ end
32
+ end
33
+
11
34
  it 'can store value to new storage' do
12
35
  @config.new_storage = :value
13
36
  @config.new_storage.should == :value
@@ -0,0 +1,129 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require File.dirname(__FILE__) + '/../spec_helper'
4
+ require 'termtter/event'
5
+
6
+ module Termtter
7
+ describe Event do
8
+
9
+ it 'creates with name' do
10
+ event = Event.new(:foo)
11
+ event.should be_kind_of Event
12
+ end
13
+
14
+ it 'in not created with wrong arguments' do
15
+ lambda{ Event.new }.should raise_error
16
+ lambda{ Event.new(1) }.should raise_error
17
+ lambda{ Event.new('hello') }.should raise_error
18
+ lambda{ Event.new('hello', 'goodbye') }.should raise_error
19
+ lambda{ Event.new(:hello, :goodbye) }.should raise_error
20
+ end
21
+
22
+ it 'bes created with name and params' do
23
+ event = Event.new(:bar, :a => 'alpha', :b => 'bravo')
24
+ event.should be_kind_of Event
25
+ end
26
+
27
+ it 'has name' do
28
+ event = Event.new(:foo)
29
+ event.name.should == :foo
30
+ end
31
+
32
+ it 'compares with symbol' do
33
+ event = Event.new(:foo)
34
+ event.should == :foo
35
+ :foo.should == event
36
+ end
37
+
38
+ it 'compares with itself' do
39
+ event = Event.new(:foo)
40
+ event.should == event
41
+ end
42
+
43
+ it 'compares with other events' do
44
+ a = Event.new(:foo)
45
+ b1 = Event.new(:bar)
46
+ b2 = Event.new(:bar, :a => 'alpha', :b => 'bravo')
47
+ a.should_not == b1
48
+ a.should_not == b2
49
+ b1.should == b2
50
+ end
51
+
52
+ it 'compares with other objects' do
53
+ event = Event.new(:foo)
54
+ event.should_not == 'hello'
55
+ event.should_not == 33
56
+ end
57
+
58
+ it 'compares with symbol using case' do
59
+ event = Event.new(:foo)
60
+ matched =
61
+ case event
62
+ when :foo
63
+ :foo_matched
64
+ else
65
+ :not_matched
66
+ end
67
+ matched.should == :foo_matched
68
+
69
+ matched =
70
+ case :foo
71
+ when event
72
+ :foo_matched
73
+ else
74
+ :not_matched
75
+ end
76
+ matched.should == :foo_matched
77
+
78
+ matched =
79
+ case :bar
80
+ when event
81
+ :bar_matched
82
+ else
83
+ :not_matched
84
+ end
85
+ matched.should == :not_matched
86
+ end
87
+
88
+ it 'delegates to ActiveRubytter' do
89
+ event = Event.new(:bar, :a => 'alpha', :b => 'bravo')
90
+ event.a.should == 'alpha'
91
+ event.b.should == 'bravo'
92
+ lambda { event.c }.should raise_error(NoMethodError)
93
+ event[:a].should == 'alpha'
94
+ event[:b].should == 'bravo'
95
+ event[:c].should be_nil
96
+
97
+ event.to_hash.should == {:a => 'alpha', :b => 'bravo'}
98
+
99
+ lambda {
100
+ event.attributes = {:c => 'charlie', :d => 'delta'}
101
+ }.should_not raise_error
102
+
103
+ event.to_hash.should == {:c => 'charlie', :d => 'delta'}
104
+ end
105
+
106
+ it 'delegates to Symbol' do
107
+ a = Event.new(:foo, :a => 'alpha', :b => 'bravo')
108
+ a.to_sym.should == a.name.to_sym
109
+ a.id2name.should == a.name.id2name
110
+ a.to_s.should == a.name.to_s
111
+
112
+ # NOTE: Isn't this spec working?
113
+ #a.to_i.should == a.name.to_i
114
+ end
115
+
116
+ it 'provides has_key?' do
117
+ event = Event.new(:foo, :a => 'alpha', :b => 'bravo')
118
+ event.has_key?(:a).should be_true
119
+ event.has_key?(:b).should be_true
120
+ event.has_key?(:c).should be_false
121
+ end
122
+
123
+ it 'provides []= ' do
124
+ event = Event.new(:foo)
125
+ event[:a] = 'alpha'
126
+ event.a.should == 'alpha'
127
+ end
128
+ end
129
+ end