File: integration_spec.rb

package info (click to toggle)
ruby-faye 1.4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 1,792 kB
  • sloc: javascript: 14,833; ruby: 5,068; makefile: 30
file content (126 lines) | stat: -rw-r--r-- 3,379 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# encoding=utf-8

require "spec_helper"

IntegrationSteps = RSpec::EM.async_steps do
  class Tagger
    def incoming(message, callback)
      message["data"]["tagged"] = true if message["data"]
      callback.call(message)
    end

    def outgoing(message, request, callback)
      message["data"]["url"] = request.path_info if message["data"]
      callback.call(message)
    end
  end

  def server(port, &callback)
    @faye = Faye::RackAdapter.new(:mount => "/bayeux", :timeout => 25)
    @faye.add_extension(Tagger.new)

    @server = ServerProxy::App.new(@faye)
    @port   = port

    @server.listen(@port)
    EM.next_tick(&callback)
  end

  def stop(&callback)
    @server.stop
    EM.next_tick(&callback)
  end

  def client(name, channels, &callback)
    @clients       ||= {}
    @inboxes       ||= {}
    @clients[name]   = Faye::Client.new("http://0.0.0.0:#{ @port }/bayeux")
    @inboxes[name]   = {}

    n = channels.size
    return @clients[name].connect(&callback) if n.zero?

    channels.each do |channel|
      subscription = @clients[name].subscribe(channel) do |message|
        @inboxes[name][channel] ||= []
        @inboxes[name][channel] << message
      end
      subscription.callback do
        n -= 1
        callback.call if n.zero?
      end
    end
  end

  def publish(name, channel, message, &callback)
    @clients[name].publish(channel, message)
    EM.add_timer(0.1, &callback)
  end

  def check_inbox(name, channel, messages, &callback)
    inbox = @inboxes[name][channel] || []
    inbox.should == messages
    callback.call
  end
end

describe "server integration" do
  next if RUBY_PLATFORM =~ /java/

  include IntegrationSteps
  include EncodingHelper

  before do
    server 4180
    client :alice, []
    client :bob,   ["/foo"]
  end

  after { stop }

  shared_examples_for "message bus" do
    it "delivers a message between clients" do
      publish :alice, "/foo", { "hello" => "world", "extra" => nil }
      check_inbox :bob, "/foo", [{ "hello" => "world", "extra" => nil, "tagged" => true, "url" => "/bayeux" }]
    end

    it "does not deliver messages for unsubscribed channels" do
      publish :alice, "/bar", { "hello" => "world" }
      check_inbox :bob, "/foo", []
    end

    it "delivers multiple messages" do
      publish :alice, "/foo", { "hello" => "world" }
      publish :alice, "/foo", { "hello" => "world" }
      check_inbox :bob, "/foo", [{ "hello" => "world", "tagged" => true, "url" => "/bayeux" }, { "hello" => "world", "tagged" => true, "url" => "/bayeux" }]
    end

    it "delivers multibyte strings" do
      publish :alice, "/foo", { "hello" => encode("Apple = "), "tagged" => true, "url" => "/bayeux" }
      check_inbox :bob, "/foo", [{ "hello" => encode("Apple = "), "tagged" => true, "url" => "/bayeux" }]
    end
  end

  shared_examples_for "network transports" do
    describe "with HTTP transport" do
      before do
        Faye::Transport::WebSocket.stub(:usable?).and_yield(false)
      end

      it_should_behave_like "message bus"
    end

    describe "with WebSocket transport" do
      before do
        Faye::Transport::WebSocket.stub(:usable?).and_yield(true)
      end

      it_should_behave_like "message bus"
    end
  end

  describe "with HTTP server" do
    let(:server_options) { { :ssl => false } }
    it_should_behave_like "network transports"
  end
end