bridge-ruby 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/LICENSE +19 -0
  2. data/README.md +31 -0
  3. data/Rakefile +24 -0
  4. data/bridge-ruby.gemspec +24 -0
  5. data/doc/Bridge.html +276 -0
  6. data/doc/Bridge/Bridge.html +1874 -0
  7. data/doc/Bridge/Bridge/SystemService.html +396 -0
  8. data/doc/Bridge/Client.html +271 -0
  9. data/doc/Bridge/Connection.html +1180 -0
  10. data/doc/Bridge/Connection/SockBuffer.html +322 -0
  11. data/doc/Bridge/Reference.html +605 -0
  12. data/doc/Bridge/Serializer.html +405 -0
  13. data/doc/Bridge/Serializer/Callback.html +498 -0
  14. data/doc/Bridge/Tcp.html +657 -0
  15. data/doc/Bridge/Util.html +643 -0
  16. data/doc/Bridge/Util/CallbackReference.html +557 -0
  17. data/doc/OpenSSL/X509/Certificate.html +275 -0
  18. data/doc/SSLCertificateVerification.html +446 -0
  19. data/doc/_index.html +239 -0
  20. data/doc/class_list.html +53 -0
  21. data/doc/css/common.css +1 -0
  22. data/doc/css/full_list.css +57 -0
  23. data/doc/css/style.css +328 -0
  24. data/doc/file.README.html +106 -0
  25. data/doc/file_list.html +55 -0
  26. data/doc/frames.html +28 -0
  27. data/doc/index.html +106 -0
  28. data/doc/js/app.js +214 -0
  29. data/doc/js/full_list.js +173 -0
  30. data/doc/js/jquery.js +4 -0
  31. data/doc/method_list.html +772 -0
  32. data/doc/top-level-namespace.html +112 -0
  33. data/examples/channels/client-writeable.rb +24 -0
  34. data/examples/channels/client.rb +23 -0
  35. data/examples/channels/server.rb +24 -0
  36. data/examples/chat/chatclient.rb +21 -0
  37. data/examples/chat/chatserver.rb +24 -0
  38. data/examples/client-context/client.rb +21 -0
  39. data/examples/client-context/server.rb +25 -0
  40. data/examples/secure/example.rb +8 -0
  41. data/examples/simple/channels.rb +47 -0
  42. data/examples/simple/services.rb +41 -0
  43. data/include/ssl/cacert.pem +3331 -0
  44. data/lib/bridge-ruby.rb +441 -0
  45. data/lib/client.rb +14 -0
  46. data/lib/connection.rb +162 -0
  47. data/lib/reference.rb +49 -0
  48. data/lib/serializer.rb +104 -0
  49. data/lib/ssl_utils.rb +68 -0
  50. data/lib/tcp.rb +73 -0
  51. data/lib/util.rb +101 -0
  52. data/lib/version.rb +3 -0
  53. data/rakelib/package.rake +4 -0
  54. data/rakelib/test.rake +8 -0
  55. data/test/regression/reconnect.rb +48 -0
  56. data/test/regression/rpc.rb +39 -0
  57. data/test/regression/test.rb +58 -0
  58. data/test/unit/bridge_dummy.rb +26 -0
  59. data/test/unit/connection_dummy.rb +21 -0
  60. data/test/unit/reference_dummy.rb +11 -0
  61. data/test/unit/tcp_dummy.rb +12 -0
  62. data/test/unit/test.rb +20 -0
  63. data/test/unit/test_reference.rb +30 -0
  64. data/test/unit/test_serializer.rb +109 -0
  65. data/test/unit/test_tcp.rb +51 -0
  66. data/test/unit/test_util.rb +59 -0
  67. metadata +162 -0
@@ -0,0 +1,101 @@
1
+ require 'json'
2
+ require 'logger'
3
+
4
+
5
+
6
+ module Bridge
7
+ module Util #:nodoc: all
8
+
9
+ @log = Logger.new(STDOUT)
10
+
11
+ def self.generate_guid
12
+ chars = (('a'..'z').to_a + (0..9).to_a)
13
+ (0...12).map{ chars[rand(26)] }.join
14
+ end
15
+
16
+ def self.stringify obj
17
+ JSON::generate obj
18
+ end
19
+
20
+ def self.parse str
21
+ JSON::parse str
22
+ end
23
+
24
+ def self.info msg
25
+ @log.info msg
26
+ end
27
+
28
+ def self.warn msg
29
+ @log.warn msg
30
+ end
31
+
32
+ def self.error msg
33
+ @log.error msg
34
+ end
35
+
36
+ def self.set_log_level level
37
+ if level > 2
38
+ @log.level = Logger::INFO
39
+ elsif level == 2
40
+ @log.level = Logger::WARN
41
+ elsif level == 1
42
+ @log.level = Logger::ERROR
43
+ else
44
+ @log.level = Logger::FATAL
45
+ end
46
+ end
47
+
48
+ def self.ref_callback ref
49
+ CallbackReference.new ref do |*args, &blk|
50
+ args << blk if blk
51
+ self.call *args
52
+ end
53
+ end
54
+
55
+ def self.find_ops obj
56
+ if obj.is_a? Module
57
+ return obj.methods false
58
+ else
59
+ return obj.class.instance_methods false
60
+ end
61
+ end
62
+
63
+ class CallbackReference < Proc
64
+ def initialize ref
65
+ @ref = ref
66
+ end
67
+
68
+ def callback *args, &blk
69
+ args << blk if blk
70
+ @ref.callback *args
71
+ end
72
+
73
+ def call *args, &blk
74
+ args << blk if blk
75
+ @ref.callback *args
76
+ end
77
+
78
+ def method atom
79
+ if atom.to_s == 'callback'
80
+ self
81
+ else
82
+ Class.method atom
83
+ end
84
+ end
85
+
86
+ def methods bool
87
+ [:callback]
88
+ end
89
+
90
+ def to_dict op = nil
91
+ @ref.to_dict op
92
+ end
93
+
94
+ def respond_to? atom
95
+ atom == :callback || atom == :to_dict || Class.respond_to?(atom)
96
+ end
97
+
98
+ end
99
+
100
+ end
101
+ end
@@ -0,0 +1,3 @@
1
+ module Bridge
2
+ VERSION = "0.2.0"
3
+ end
@@ -0,0 +1,4 @@
1
+ require 'rubygems/package_task'
2
+
3
+ Gem::PackageTask.new(GEMSPEC) do |pkg|
4
+ end
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new(:test) do |t|
4
+ t.libs << "tests"
5
+ t.libs << "lib"
6
+ t.pattern = 'tests/**/test_*.rb'
7
+ t.warning = true
8
+ end
@@ -0,0 +1,48 @@
1
+ require_relative '../../lib/bridge'
2
+ require_relative './test'
3
+
4
+ description = 'Reconnects';
5
+ failureMessage = 'This implementation of the Bridge API does not support reconnects.';
6
+
7
+ =begin
8
+ Passing this test means the following:
9
+
10
+ We can connect, reconnects (seem to) work. buffering between reconnects
11
+ works, services are preserved between these reconnects (i.e. should happen
12
+ in < 5s), and client ID is preserved.
13
+ =end
14
+
15
+ EM::run do
16
+ test = Test.new(failureMessage, 1, 4)
17
+
18
+ class T
19
+ def initialize(test, id)
20
+ @id = id
21
+ @test = test
22
+ @test.advance 1
23
+ end
24
+
25
+ def cb(id)
26
+ if id != @id
27
+ @test.fail "ID not preserved."
28
+ end
29
+ @test.advance 3
30
+ @test.close
31
+ end
32
+ end
33
+
34
+ bridge = Bridge::Bridge.new({:api_key => 'abcdefgh'}).connect {
35
+ test.advance 0
36
+ }
37
+
38
+ bridge.ready {
39
+ svc = T.new(test, bridge.connection.client_id)
40
+ bridge.publish_service('test_reconn', svc) {
41
+ test.advance 2
42
+ bridge.connection.sock.close_connection
43
+ EM::Timer.new(0) {
44
+ bridge.get_service('test_reconn') {|service| service.cb(bridge.connection.client_id)}
45
+ }
46
+ }
47
+ }
48
+ end
@@ -0,0 +1,39 @@
1
+ require_relative '../../lib/bridge'
2
+ require_relative './test'
3
+
4
+ description = 'Basic RPC';
5
+ failureMessage = 'This implementation of the Bridge API is incapable of RPC.';
6
+
7
+ =begin
8
+ Passing this test means the following:
9
+
10
+ We can connect (it seems), we can publish a service, the callback to
11
+ publishService is called, and calling a method of getService works.
12
+
13
+ =end
14
+
15
+ EM::run do
16
+ test = Test.new(failureMessage, 2, 3)
17
+
18
+ bridge = Bridge::Bridge.new({:api_key => 'abcdefgh'}).connect {
19
+ test.advance 0
20
+ }
21
+
22
+ module ConsoleLogServer
23
+ def self.log(msg = "", test)
24
+ if msg == '123'
25
+ test.advance(2)
26
+ else
27
+ test.log('received ' + msg + ' but expected 123')
28
+ end
29
+ test.close
30
+ end
31
+ end
32
+
33
+ bridge.ready {
34
+ bridge.publish_service('test_consolelog', ConsoleLogServer) {
35
+ test.advance 1
36
+ bridge.get_service('test_consolelog') {|service| service.log('123', test)}
37
+ }
38
+ }
39
+ end
@@ -0,0 +1,58 @@
1
+ require 'eventmachine'
2
+
3
+ class Test
4
+ def initialize failureMessage, logLevel, stages
5
+ @messages = []
6
+ @stages = stages
7
+ @stage = 0
8
+ @failureMessage = failureMessage
9
+ @timer = EM::Timer.new(5) { self.fail "timeout" }
10
+ if !(logLevel == 0 || logLevel == 1 || logLevel == 2)
11
+ raise "Invalid log level #{logLevel}"
12
+ end
13
+ @logLevel = logLevel
14
+ end
15
+
16
+ def advance expected
17
+ if @stage != expected
18
+ self.fail "out of order: at stage #{@stage}, not #{expected}"
19
+ else
20
+ @stage += 1
21
+ @timer.cancel
22
+ @timer = EM::Timer.new(5) { self.fail "timeout" }
23
+ if @logLevel > 0
24
+ puts "Advancing to stage #{@stage}"
25
+ end
26
+ end
27
+ end
28
+
29
+ def close
30
+ if @stage != @stages
31
+ puts "Failure: reached stage #{@stage} of #{@stages}"
32
+ else
33
+ puts "Success; passed this test."
34
+ end
35
+
36
+ Process::exit
37
+ end
38
+
39
+ def fail(m = failureMessage)
40
+ puts "============================================"
41
+ puts " Description: ", m
42
+ if @logLevel != 0
43
+ puts " Message stack: "
44
+ @messages.each {|msg| puts msg}
45
+ end
46
+ self.close
47
+ end
48
+
49
+ def log msg
50
+ if @logLevel != 0
51
+ @messages += msg
52
+ if logLevel == 2
53
+ puts msg
54
+ end
55
+ end
56
+ end
57
+
58
+ end
@@ -0,0 +1,26 @@
1
+ require_relative "reference_dummy.rb"
2
+
3
+ class BridgeDummy
4
+
5
+ attr_accessor :last_args, :last_dest, :stored, :options
6
+
7
+ def initialize
8
+ @options = {
9
+ :redirector => 'http://redirector.getbridge.com',
10
+ :reconnect => true,
11
+ :log => 2, # 0 for no output
12
+ }
13
+ @stored = []
14
+ end
15
+
16
+ def store_object handler, ops
17
+ @stored << [handler, ops]
18
+ return ReferenceDummy.new
19
+ end
20
+
21
+ def send args, destination
22
+ @last_args = args
23
+ @last_dest = destination
24
+ end
25
+
26
+ end
@@ -0,0 +1,21 @@
1
+ class ConnectionDummy
2
+
3
+ attr_accessor :messages, :onopened
4
+
5
+ def initialize
6
+ @messages = []
7
+ @onopened = false
8
+ end
9
+
10
+ def onopen *args
11
+ @onopened = true
12
+ end
13
+
14
+ def onclose *args
15
+ end
16
+
17
+ def onmessage data, tcp
18
+ messages << data[:data]
19
+ end
20
+
21
+ end
@@ -0,0 +1,11 @@
1
+ class ReferenceDummy
2
+
3
+
4
+ def initialize *args
5
+
6
+ end
7
+
8
+ def to_dict *args
9
+ return "dummy"
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ class TcpDummy
2
+
3
+ attr_accessor :last_send
4
+
5
+ def initialize *args
6
+
7
+ end
8
+
9
+ def send *args
10
+ @last_send = args
11
+ end
12
+ end
@@ -0,0 +1,20 @@
1
+ require 'simplecov'
2
+ SimpleCov.start do
3
+ add_filter "/test/"
4
+ end
5
+
6
+ require 'test/unit'
7
+
8
+ require_relative '../../lib/bridge'
9
+ require_relative '../../lib/connection'
10
+ require_relative '../../lib/reference'
11
+ require_relative '../../lib/serializer'
12
+ require_relative '../../lib/tcp'
13
+ require_relative '../../lib/util'
14
+ require_relative '../../lib/version'
15
+
16
+ require_relative 'test_util.rb'
17
+ require_relative 'test_serializer.rb'
18
+ require_relative 'test_tcp.rb'
19
+ require_relative 'test_reference.rb'
20
+
@@ -0,0 +1,30 @@
1
+ require "bridge"
2
+ require_relative "bridge_dummy.rb"
3
+ require "test/unit"
4
+
5
+ class TestReference < Test::Unit::TestCase
6
+
7
+ def setup
8
+
9
+ end
10
+
11
+ def teardown
12
+ ## Nothing really
13
+ end
14
+
15
+
16
+ def test_reference
17
+ dummy = BridgeDummy.new
18
+ ref = Bridge::Reference.new dummy, ['x', 'y', 'z'], [:a, :b, :c]
19
+ assert_equal(['a', 'b', 'c'], ref.operations)
20
+ assert_equal({:ref => ['x', 'y', 'z'], :operations => ['a', 'b', 'c']}, ref.to_dict)
21
+
22
+ blk = lambda {}
23
+ ref.test 1, 2, &blk
24
+ assert_equal([1,2,blk], dummy.last_args)
25
+ assert_equal(['x', 'y', 'z', 'test'], dummy.last_dest[:ref])
26
+ assert(!dummy.last_dest.key?(:operations))
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,109 @@
1
+ require "bridge"
2
+ require_relative "bridge_dummy.rb"
3
+ require_relative "reference_dummy.rb"
4
+ require "test/unit"
5
+
6
+ class TestSerializer < Test::Unit::TestCase
7
+
8
+ def setup
9
+
10
+ end
11
+
12
+ def teardown
13
+ ## Nothing really
14
+ end
15
+
16
+
17
+ def test_serialize
18
+ dummy = BridgeDummy.new
19
+ test2 = Test2.new
20
+ test3 = Test3.new
21
+ test4 = lambda {}
22
+ obj = {
23
+ :a => {
24
+ :b => Test1
25
+ },
26
+ :c => 5,
27
+ :d => true,
28
+ :e => 'abc',
29
+ :f => [test2, test3],
30
+ :g => test2,
31
+ :h => test3,
32
+ :i => test4
33
+ }
34
+ ser = Bridge::Serializer.serialize dummy, obj
35
+
36
+ assert(dummy.stored.include?([Test1, [:a]]))
37
+ assert(dummy.stored.include?([test2, [:c]]))
38
+ assert(dummy.stored.include?([test3, [:d, :e]]))
39
+
40
+ found = false
41
+ dummy.stored.each do | x |
42
+ if x[1] == ['callback']
43
+ assert_instance_of(Bridge::Serializer::Callback, x[0])
44
+ found = true
45
+ end
46
+ end
47
+
48
+ assert found
49
+
50
+ expected_ser = {
51
+ :a => {
52
+ :b => "dummy"
53
+ },
54
+ :c => 5,
55
+ :d => true,
56
+ :e => 'abc',
57
+ :f => ["dummy", "dummy"],
58
+ :g => "dummy",
59
+ :h => "dummy",
60
+ :i => "dummy"
61
+ }
62
+
63
+ assert_equal(expected_ser, ser)
64
+ end
65
+
66
+ def test_unserialize
67
+ dummy = BridgeDummy.new
68
+ obj = {
69
+ :a => {'ref' => ['x','x','x'], 'operations' => ['a','b']},
70
+ :b => {
71
+ :i => {'ref' => ['z','z','z'], 'operations' => ['callback']}
72
+ },
73
+ :c => 5,
74
+ :d => true,
75
+ :e => 'abc',
76
+ :f => [1, {'ref' => ['y','y','y'], 'operations' => ['c','d']}],
77
+ :g => 2,
78
+ :h => 'foo'
79
+ }
80
+
81
+ unser = Bridge::Serializer.unserialize dummy, obj
82
+
83
+ assert_instance_of(Bridge::Reference, unser[:a])
84
+ assert_instance_of(Bridge::Reference, unser[:f][1])
85
+ assert_instance_of(Bridge::Util::CallbackReference, unser[:b][:i])
86
+
87
+
88
+ end
89
+
90
+ module Test1
91
+ def self.a
92
+ end
93
+ def b
94
+ end
95
+ end
96
+
97
+ class Test2
98
+ def c
99
+ end
100
+ end
101
+
102
+ class Test3 < Test2
103
+ def d
104
+ end
105
+ def e
106
+ end
107
+ end
108
+
109
+ end