bridge-ruby 0.2.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 (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