require 'amqp/spec' require 'amqp/buffer' require 'amqp/protocol' module AMQP class Frame def initialize payload = nil, channel = 0 @channel, @payload = channel, payload end attr_accessor :channel, :payload def id self.class::ID end def to_binary buf = Buffer.new buf.write :octet, id buf.write :short, channel buf.write :longstr, payload buf.write :octet, FOOTER buf.rewind buf end def to_s to_binary.to_s end def == frame [ :id, :channel, :payload ].inject(true) do |eql, field| eql and __send__(field) == frame.__send__(field) end end class Invalid < StandardError; end class Method def initialize payload = nil, channel = 0 super unless @payload.is_a? Protocol::Class::Method or @payload.nil? @payload = Protocol.parse(@payload) end end end class Header def initialize payload = nil, channel = 0 super unless @payload.is_a? Protocol::Header or @payload.nil? @payload = Protocol::Header.new(@payload) end end end class Body; end def self.parse buf buf = Buffer.new(buf) unless buf.is_a? Buffer buf.extract do id, channel, payload, footer = buf.read(:octet, :short, :longstr, :octet) Frame.types[id].new(payload, channel) if footer == FOOTER end end end end if $0 =~ /bacon/ or $0 == __FILE__ require 'bacon' include AMQP describe Frame do should 'handle basic frame types' do Frame::Method.new.id.should == 1 Frame::Header.new.id.should == 2 Frame::Body.new.id.should == 3 end should 'convert method frames to binary' do meth = Protocol::Connection::Secure.new :challenge => 'secret' frame = Frame::Method.new(meth) frame.to_binary.should.be.kind_of? Buffer frame.to_s.should == [ 1, 0, meth.to_s.length, meth.to_s, 206 ].pack('CnNa*C') end should 'convert binary to method frames' do orig = Frame::Method.new Protocol::Connection::Secure.new(:challenge => 'secret') copy = Frame.parse(orig.to_binary) copy.should == orig end should 'ignore partial frames until ready' do frame = Frame::Method.new Protocol::Connection::Secure.new(:challenge => 'secret') data = frame.to_s buf = Buffer.new Frame.parse(buf).should == nil buf << data[0..5] Frame.parse(buf).should == nil buf << data[6..-1] Frame.parse(buf).should == frame Frame.parse(buf).should == nil end should 'convert header frames to binary' do head = Protocol::Header.new(Protocol::Basic, :priority => 1) frame = Frame::Header.new(head) frame.to_s.should == [ 2, 0, head.to_s.length, head.to_s, 206 ].pack('CnNa*C') end should 'convert binary to header frame' do orig = Frame::Header.new Protocol::Header.new(Protocol::Basic, :priority => 1) copy = Frame.parse(orig.to_binary) copy.should == orig end end end