ruby-dbus 0.16.0 → 0.18.1
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.
- checksums.yaml +4 -4
 - data/NEWS.md +160 -0
 - data/README.md +3 -5
 - data/Rakefile +18 -8
 - data/VERSION +1 -1
 - data/doc/Reference.md +106 -7
 - data/examples/doc/_extract_examples +7 -0
 - data/examples/gdbus/gdbus +31 -24
 - data/examples/no-introspect/nm-test.rb +2 -0
 - data/examples/no-introspect/tracker-test.rb +3 -1
 - data/examples/rhythmbox/playpause.rb +2 -1
 - data/examples/service/call_service.rb +2 -1
 - data/examples/service/complex-property.rb +21 -0
 - data/examples/service/service_newapi.rb +1 -1
 - data/examples/simple/call_introspect.rb +1 -0
 - data/examples/simple/get_id.rb +2 -1
 - data/examples/simple/properties.rb +2 -0
 - data/examples/utils/listnames.rb +1 -0
 - data/examples/utils/notify.rb +1 -0
 - data/lib/dbus/api_options.rb +9 -0
 - data/lib/dbus/auth.rb +20 -15
 - data/lib/dbus/bus.rb +123 -75
 - data/lib/dbus/bus_name.rb +12 -8
 - data/lib/dbus/core_ext/class/attribute.rb +1 -1
 - data/lib/dbus/data.rb +821 -0
 - data/lib/dbus/emits_changed_signal.rb +83 -0
 - data/lib/dbus/error.rb +4 -2
 - data/lib/dbus/introspect.rb +132 -31
 - data/lib/dbus/logger.rb +3 -1
 - data/lib/dbus/marshall.rb +247 -296
 - data/lib/dbus/matchrule.rb +16 -16
 - data/lib/dbus/message.rb +44 -37
 - data/lib/dbus/message_queue.rb +16 -10
 - data/lib/dbus/object.rb +358 -24
 - data/lib/dbus/object_path.rb +11 -6
 - data/lib/dbus/proxy_object.rb +22 -1
 - data/lib/dbus/proxy_object_factory.rb +13 -7
 - data/lib/dbus/proxy_object_interface.rb +63 -30
 - data/lib/dbus/raw_message.rb +91 -0
 - data/lib/dbus/type.rb +318 -86
 - data/lib/dbus/xml.rb +32 -17
 - data/lib/dbus.rb +14 -7
 - data/ruby-dbus.gemspec +7 -3
 - data/spec/async_spec.rb +2 -0
 - data/spec/binding_spec.rb +2 -0
 - data/spec/bus_and_xml_backend_spec.rb +2 -0
 - data/spec/bus_driver_spec.rb +2 -0
 - data/spec/bus_name_spec.rb +3 -1
 - data/spec/bus_spec.rb +2 -0
 - data/spec/byte_array_spec.rb +2 -0
 - data/spec/client_robustness_spec.rb +4 -2
 - data/spec/data/marshall.yaml +1667 -0
 - data/spec/data_spec.rb +673 -0
 - data/spec/emits_changed_signal_spec.rb +58 -0
 - data/spec/err_msg_spec.rb +2 -0
 - data/spec/introspect_xml_parser_spec.rb +2 -0
 - data/spec/introspection_spec.rb +2 -0
 - data/spec/main_loop_spec.rb +3 -1
 - data/spec/node_spec.rb +23 -0
 - data/spec/object_path_spec.rb +3 -0
 - data/spec/object_spec.rb +138 -0
 - data/spec/packet_marshaller_spec.rb +41 -0
 - data/spec/packet_unmarshaller_spec.rb +248 -0
 - data/spec/property_spec.rb +192 -5
 - data/spec/proxy_object_spec.rb +2 -0
 - data/spec/server_robustness_spec.rb +2 -0
 - data/spec/server_spec.rb +2 -0
 - data/spec/service_newapi.rb +70 -70
 - data/spec/session_bus_spec.rb +3 -1
 - data/spec/session_bus_spec_manual.rb +2 -0
 - data/spec/signal_spec.rb +5 -3
 - data/spec/spec_helper.rb +37 -9
 - data/spec/thread_safety_spec.rb +2 -0
 - data/spec/tools/dbus-limited-session.conf +4 -0
 - data/spec/type_spec.rb +214 -6
 - data/spec/value_spec.rb +16 -1
 - data/spec/variant_spec.rb +4 -2
 - data/spec/zzz_quit_spec.rb +16 -0
 - metadata +34 -8
 
| 
         @@ -0,0 +1,58 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env rspec
         
     | 
| 
      
 2 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative "spec_helper"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "dbus"
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            describe DBus::EmitsChangedSignal do
         
     | 
| 
      
 8 
     | 
    
         
            +
              describe "#initialize" do
         
     | 
| 
      
 9 
     | 
    
         
            +
                it "accepts a simple value" do
         
     | 
| 
      
 10 
     | 
    
         
            +
                  expect(described_class.new(:const).value).to eq :const
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                it "avoids nil by asking the interface" do
         
     | 
| 
      
 14 
     | 
    
         
            +
                  ifc = DBus::Interface.new("org.example.Foo")
         
     | 
| 
      
 15 
     | 
    
         
            +
                  ifc.emits_changed_signal = described_class.new(:invalidates)
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  expect(described_class.new(nil, interface: ifc).value).to eq :invalidates
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                it "fails for unknown value" do
         
     | 
| 
      
 21 
     | 
    
         
            +
                  expect { described_class.new(:huh) }.to raise_error(ArgumentError, /Seen :huh/)
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                it "fails for 2 nils" do
         
     | 
| 
      
 25 
     | 
    
         
            +
                  expect { described_class.new(nil, interface: nil) }.to raise_error(ArgumentError, /Both/)
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              describe "#==" do
         
     | 
| 
      
 30 
     | 
    
         
            +
                it "is true for two different objects with the same value" do
         
     | 
| 
      
 31 
     | 
    
         
            +
                  const_a = described_class.new(:const)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  const_b = described_class.new(:const)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  expect(const_a == const_b).to be true
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              describe "#to_xml" do
         
     | 
| 
      
 38 
     | 
    
         
            +
                it "uses a string value" do
         
     | 
| 
      
 39 
     | 
    
         
            +
                  expect(described_class.new(:const).to_xml)
         
     | 
| 
      
 40 
     | 
    
         
            +
                    .to eq "    <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"const\"/>\n"
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
              describe "#to_s" do
         
     | 
| 
      
 45 
     | 
    
         
            +
                it "uses a string value" do
         
     | 
| 
      
 46 
     | 
    
         
            +
                  expect(described_class.new(:const).to_s).to eq "const"
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
            end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            describe DBus::Interface do
         
     | 
| 
      
 52 
     | 
    
         
            +
              describe ".emits_changed_signal=" do
         
     | 
| 
      
 53 
     | 
    
         
            +
                it "only allows an EmitsChangedSignal as argument" do
         
     | 
| 
      
 54 
     | 
    
         
            +
                  ifc = described_class.new("org.ruby.Interface")
         
     | 
| 
      
 55 
     | 
    
         
            +
                  expect { ifc.emits_changed_signal = :const }.to raise_error(TypeError)
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
              end
         
     | 
| 
      
 58 
     | 
    
         
            +
            end
         
     | 
    
        data/spec/err_msg_spec.rb
    CHANGED
    
    
    
        data/spec/introspection_spec.rb
    CHANGED
    
    
    
        data/spec/main_loop_spec.rb
    CHANGED
    
    | 
         @@ -1,4 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            #!/usr/bin/env rspec
         
     | 
| 
      
 2 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
       2 
4 
     | 
    
         
             
            # Test the main loop
         
     | 
| 
       3 
5 
     | 
    
         
             
            require_relative "spec_helper"
         
     | 
| 
       4 
6 
     | 
    
         
             
            require "dbus"
         
     | 
| 
         @@ -70,7 +72,7 @@ describe "MainLoopTest" do 
     | 
|
| 
       70 
72 
     | 
    
         
             
                @obj.on_signal "LongTaskEnd"
         
     | 
| 
       71 
73 
     | 
    
         
             
              end
         
     | 
| 
       72 
74 
     | 
    
         | 
| 
       73 
     | 
    
         
            -
              it "tests loop quit" do
         
     | 
| 
      
 75 
     | 
    
         
            +
              it "tests loop quit", slow: true do
         
     | 
| 
       74 
76 
     | 
    
         
             
                test_loop_quit 1
         
     | 
| 
       75 
77 
     | 
    
         
             
              end
         
     | 
| 
       76 
78 
     | 
    
         | 
    
        data/spec/node_spec.rb
    ADDED
    
    | 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env rspec
         
     | 
| 
      
 2 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative "spec_helper"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "dbus"
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            describe DBus::Node do
         
     | 
| 
      
 8 
     | 
    
         
            +
              describe "#inspect" do
         
     | 
| 
      
 9 
     | 
    
         
            +
                # the behavior needs improvement
         
     | 
| 
      
 10 
     | 
    
         
            +
                it "shows the node, poorly" do
         
     | 
| 
      
 11 
     | 
    
         
            +
                  parent = described_class.new("parent")
         
     | 
| 
      
 12 
     | 
    
         
            +
                  parent.object = DBus::Object.new("/parent")
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  3.times do |i|
         
     | 
| 
      
 15 
     | 
    
         
            +
                    child_name = "child#{i}"
         
     | 
| 
      
 16 
     | 
    
         
            +
                    child = described_class.new(child_name)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    parent[child_name] = child
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  expect(parent.inspect).to match(/<DBus::Node [0-9a-f]+ {child0 => {},child1 => {},child2 => {}}>/)
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
    
        data/spec/object_path_spec.rb
    CHANGED
    
    | 
         @@ -1,4 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            #!/usr/bin/env rspec
         
     | 
| 
      
 2 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
       2 
4 
     | 
    
         
             
            require_relative "spec_helper"
         
     | 
| 
       3 
5 
     | 
    
         
             
            require "dbus"
         
     | 
| 
       4 
6 
     | 
    
         | 
| 
         @@ -18,6 +20,7 @@ describe DBus::ObjectPath do 
     | 
|
| 
       18 
20 
     | 
    
         
             
                  expect(described_class.valid?("/EmptyLastComponent/")).to be_falsey
         
     | 
| 
       19 
21 
     | 
    
         
             
                  expect(described_class.valid?("/Invalid Character")).to be_falsey
         
     | 
| 
       20 
22 
     | 
    
         
             
                  expect(described_class.valid?("/Invalid-Character")).to be_falsey
         
     | 
| 
      
 23 
     | 
    
         
            +
                  expect(described_class.valid?("/InválídCháráctér")).to be_falsey
         
     | 
| 
       21 
24 
     | 
    
         
             
                end
         
     | 
| 
       22 
25 
     | 
    
         
             
              end
         
     | 
| 
       23 
26 
     | 
    
         
             
            end
         
     | 
    
        data/spec/object_spec.rb
    ADDED
    
    | 
         @@ -0,0 +1,138 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env rspec
         
     | 
| 
      
 2 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative "spec_helper"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "dbus"
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            class ObjectTest < DBus::Object
         
     | 
| 
      
 8 
     | 
    
         
            +
              T = DBus::Type unless const_defined? "T"
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              dbus_interface "org.ruby.ServerTest" do
         
     | 
| 
      
 11 
     | 
    
         
            +
                dbus_attr_writer :write_me, T::Struct[String, String]
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                attr_accessor :read_only_for_dbus
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                dbus_reader :read_only_for_dbus, T::STRING, emits_changed_signal: :invalidates
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            describe DBus::Object do
         
     | 
| 
      
 20 
     | 
    
         
            +
              describe ".dbus_attr_writer" do
         
     | 
| 
      
 21 
     | 
    
         
            +
                describe "the declared assignment method" do
         
     | 
| 
      
 22 
     | 
    
         
            +
                  # Slightly advanced RSpec:
         
     | 
| 
      
 23 
     | 
    
         
            +
                  # https://rspec.info/documentation/3.9/rspec-expectations/RSpec/Matchers.html#satisfy-instance_method
         
     | 
| 
      
 24 
     | 
    
         
            +
                  let(:a_struct_in_a_variant) do
         
     | 
| 
      
 25 
     | 
    
         
            +
                    satisfying { |x| x.is_a?(DBus::Data::Variant) && x.member_type.to_s == "(ss)" }
         
     | 
| 
      
 26 
     | 
    
         
            +
                    # ^ This formatting keeps the matcher on a single line
         
     | 
| 
      
 27 
     | 
    
         
            +
                    # which enables RSpec to cite it if it fails, instead of saying "block".
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  it "emits PropertyChanged with correctly typed argument" do
         
     | 
| 
      
 31 
     | 
    
         
            +
                    obj = ObjectTest.new("/test")
         
     | 
| 
      
 32 
     | 
    
         
            +
                    expect(obj).to receive(:PropertiesChanged).with(
         
     | 
| 
      
 33 
     | 
    
         
            +
                      "org.ruby.ServerTest",
         
     | 
| 
      
 34 
     | 
    
         
            +
                      {
         
     | 
| 
      
 35 
     | 
    
         
            +
                        "WriteMe" => a_struct_in_a_variant
         
     | 
| 
      
 36 
     | 
    
         
            +
                      },
         
     | 
| 
      
 37 
     | 
    
         
            +
                      []
         
     | 
| 
      
 38 
     | 
    
         
            +
                    )
         
     | 
| 
      
 39 
     | 
    
         
            +
                    # bug: call PC with simply the assigned value,
         
     | 
| 
      
 40 
     | 
    
         
            +
                    # which will need type guessing
         
     | 
| 
      
 41 
     | 
    
         
            +
                    obj.write_me = ["two", "strings"]
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
              end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
              describe ".dbus_accessor" do
         
     | 
| 
      
 47 
     | 
    
         
            +
                it "can only be used within a dbus_interface" do
         
     | 
| 
      
 48 
     | 
    
         
            +
                  expect do
         
     | 
| 
      
 49 
     | 
    
         
            +
                    ObjectTest.instance_exec do
         
     | 
| 
      
 50 
     | 
    
         
            +
                      dbus_accessor :foo, DBus::Type::STRING
         
     | 
| 
      
 51 
     | 
    
         
            +
                    end
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end.to raise_error(DBus::Object::UndefinedInterface)
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
              end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
              describe ".dbus_reader" do
         
     | 
| 
      
 57 
     | 
    
         
            +
                it "can only be used within a dbus_interface" do
         
     | 
| 
      
 58 
     | 
    
         
            +
                  expect do
         
     | 
| 
      
 59 
     | 
    
         
            +
                    ObjectTest.instance_exec do
         
     | 
| 
      
 60 
     | 
    
         
            +
                      dbus_reader :foo, DBus::Type::STRING
         
     | 
| 
      
 61 
     | 
    
         
            +
                    end
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end.to raise_error(DBus::Object::UndefinedInterface)
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
              describe ".dbus_reader, when paired with attr_accessor" do
         
     | 
| 
      
 67 
     | 
    
         
            +
                describe "the declared assignment method" do
         
     | 
| 
      
 68 
     | 
    
         
            +
                  it "emits PropertyChanged" do
         
     | 
| 
      
 69 
     | 
    
         
            +
                    obj = ObjectTest.new("/test")
         
     | 
| 
      
 70 
     | 
    
         
            +
                    expect(obj).to receive(:PropertiesChanged).with(
         
     | 
| 
      
 71 
     | 
    
         
            +
                      "org.ruby.ServerTest",
         
     | 
| 
      
 72 
     | 
    
         
            +
                      {},
         
     | 
| 
      
 73 
     | 
    
         
            +
                      ["ReadOnlyForDbus"]
         
     | 
| 
      
 74 
     | 
    
         
            +
                    )
         
     | 
| 
      
 75 
     | 
    
         
            +
                    obj.read_only_for_dbus = "myvalue"
         
     | 
| 
      
 76 
     | 
    
         
            +
                  end
         
     | 
| 
      
 77 
     | 
    
         
            +
                end
         
     | 
| 
      
 78 
     | 
    
         
            +
              end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
              describe ".dbus_writer" do
         
     | 
| 
      
 81 
     | 
    
         
            +
                it "can only be used within a dbus_interface" do
         
     | 
| 
      
 82 
     | 
    
         
            +
                  expect do
         
     | 
| 
      
 83 
     | 
    
         
            +
                    ObjectTest.instance_exec do
         
     | 
| 
      
 84 
     | 
    
         
            +
                      dbus_writer :foo, DBus::Type::STRING
         
     | 
| 
      
 85 
     | 
    
         
            +
                    end
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end.to raise_error(DBus::Object::UndefinedInterface)
         
     | 
| 
      
 87 
     | 
    
         
            +
                end
         
     | 
| 
      
 88 
     | 
    
         
            +
              end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
              describe ".dbus_watcher" do
         
     | 
| 
      
 91 
     | 
    
         
            +
                it "can only be used within a dbus_interface" do
         
     | 
| 
      
 92 
     | 
    
         
            +
                  expect do
         
     | 
| 
      
 93 
     | 
    
         
            +
                    ObjectTest.instance_exec do
         
     | 
| 
      
 94 
     | 
    
         
            +
                      dbus_watcher :foo
         
     | 
| 
      
 95 
     | 
    
         
            +
                    end
         
     | 
| 
      
 96 
     | 
    
         
            +
                  end.to raise_error(DBus::Object::UndefinedInterface)
         
     | 
| 
      
 97 
     | 
    
         
            +
                end
         
     | 
| 
      
 98 
     | 
    
         
            +
              end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
              describe ".dbus_method" do
         
     | 
| 
      
 101 
     | 
    
         
            +
                it "can only be used within a dbus_interface" do
         
     | 
| 
      
 102 
     | 
    
         
            +
                  expect do
         
     | 
| 
      
 103 
     | 
    
         
            +
                    ObjectTest.instance_exec do
         
     | 
| 
      
 104 
     | 
    
         
            +
                      dbus_method :foo do
         
     | 
| 
      
 105 
     | 
    
         
            +
                      end
         
     | 
| 
      
 106 
     | 
    
         
            +
                    end
         
     | 
| 
      
 107 
     | 
    
         
            +
                  end.to raise_error(DBus::Object::UndefinedInterface)
         
     | 
| 
      
 108 
     | 
    
         
            +
                end
         
     | 
| 
      
 109 
     | 
    
         
            +
              end
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
              describe ".emits_changed_signal" do
         
     | 
| 
      
 112 
     | 
    
         
            +
                it "raises UndefinedInterface when so" do
         
     | 
| 
      
 113 
     | 
    
         
            +
                  expect { ObjectTest.emits_changed_signal = false }
         
     | 
| 
      
 114 
     | 
    
         
            +
                    .to raise_error DBus::Object::UndefinedInterface
         
     | 
| 
      
 115 
     | 
    
         
            +
                end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                it "assigns to the current interface" do
         
     | 
| 
      
 118 
     | 
    
         
            +
                  ObjectTest.instance_exec do
         
     | 
| 
      
 119 
     | 
    
         
            +
                    dbus_interface "org.ruby.Interface" do
         
     | 
| 
      
 120 
     | 
    
         
            +
                      self.emits_changed_signal = false
         
     | 
| 
      
 121 
     | 
    
         
            +
                    end
         
     | 
| 
      
 122 
     | 
    
         
            +
                  end
         
     | 
| 
      
 123 
     | 
    
         
            +
                  ecs = ObjectTest.intfs["org.ruby.Interface"].emits_changed_signal
         
     | 
| 
      
 124 
     | 
    
         
            +
                  expect(ecs).to eq false
         
     | 
| 
      
 125 
     | 
    
         
            +
                end
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                it "only can be assigned once" do
         
     | 
| 
      
 128 
     | 
    
         
            +
                  expect do
         
     | 
| 
      
 129 
     | 
    
         
            +
                    Class.new(DBus::Object) do
         
     | 
| 
      
 130 
     | 
    
         
            +
                      dbus_interface "org.ruby.Interface" do
         
     | 
| 
      
 131 
     | 
    
         
            +
                        self.emits_changed_signal = false
         
     | 
| 
      
 132 
     | 
    
         
            +
                        self.emits_changed_signal = :invalidates
         
     | 
| 
      
 133 
     | 
    
         
            +
                      end
         
     | 
| 
      
 134 
     | 
    
         
            +
                    end
         
     | 
| 
      
 135 
     | 
    
         
            +
                  end.to raise_error(RuntimeError, /assigned more than once/)
         
     | 
| 
      
 136 
     | 
    
         
            +
                end
         
     | 
| 
      
 137 
     | 
    
         
            +
              end
         
     | 
| 
      
 138 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,41 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env rspec
         
     | 
| 
      
 2 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative "spec_helper"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "dbus"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "ostruct"
         
     | 
| 
      
 7 
     | 
    
         
            +
            require "yaml"
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            data_dir = File.expand_path("data", __dir__)
         
     | 
| 
      
 10 
     | 
    
         
            +
            marshall_yaml_s = File.read("#{data_dir}/marshall.yaml")
         
     | 
| 
      
 11 
     | 
    
         
            +
            marshall_yaml = YAML.safe_load(marshall_yaml_s)
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            describe DBus::PacketMarshaller do
         
     | 
| 
      
 14 
     | 
    
         
            +
              context "marshall.yaml" do
         
     | 
| 
      
 15 
     | 
    
         
            +
                marshall_yaml.each do |test|
         
     | 
| 
      
 16 
     | 
    
         
            +
                  t = OpenStruct.new(test)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  next if t.marshall == false
         
     | 
| 
      
 18 
     | 
    
         
            +
                  # skip test cases for invalid unmarshalling
         
     | 
| 
      
 19 
     | 
    
         
            +
                  next if t.val.nil?
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  # while the marshaller can use only native endianness, skip the other
         
     | 
| 
      
 22 
     | 
    
         
            +
                  endianness = t.end.to_sym
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  signature = t.sig
         
     | 
| 
      
 25 
     | 
    
         
            +
                  expected = buffer_from_yaml(t.buf)
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  it "writes a '#{signature}' with value #{t.val.inspect} (#{endianness})" do
         
     | 
| 
      
 28 
     | 
    
         
            +
                    subject = described_class.new(endianness: endianness)
         
     | 
| 
      
 29 
     | 
    
         
            +
                    subject.append(signature, t.val)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    expect(subject.packet).to eq(expected)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  it "writes a '#{signature}' with typed value #{t.val.inspect} (#{endianness})" do
         
     | 
| 
      
 34 
     | 
    
         
            +
                    subject = described_class.new(endianness: endianness)
         
     | 
| 
      
 35 
     | 
    
         
            +
                    typed_val = DBus::Data.make_typed(signature, t.val)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    subject.append(signature, typed_val)
         
     | 
| 
      
 37 
     | 
    
         
            +
                    expect(subject.packet).to eq(expected)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,248 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env rspec
         
     | 
| 
      
 2 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative "spec_helper"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "dbus"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "ostruct"
         
     | 
| 
      
 7 
     | 
    
         
            +
            require "yaml"
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            data_dir = File.expand_path("data", __dir__)
         
     | 
| 
      
 10 
     | 
    
         
            +
            marshall_yaml_s = File.read("#{data_dir}/marshall.yaml")
         
     | 
| 
      
 11 
     | 
    
         
            +
            marshall_yaml = YAML.safe_load(marshall_yaml_s)
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            # Helper to access PacketUnmarshaller internals.
         
     | 
| 
      
 14 
     | 
    
         
            +
            # Add it to its public API?
         
     | 
| 
      
 15 
     | 
    
         
            +
            # @param p_u [PacketUnmarshaller]
         
     | 
| 
      
 16 
     | 
    
         
            +
            # @return [String] the binary string with unconsumed data
         
     | 
| 
      
 17 
     | 
    
         
            +
            def remaining_buffer(p_u)
         
     | 
| 
      
 18 
     | 
    
         
            +
              raw_msg = p_u.instance_variable_get(:@raw_msg)
         
     | 
| 
      
 19 
     | 
    
         
            +
              raw_msg.remaining_bytes
         
     | 
| 
      
 20 
     | 
    
         
            +
            end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            RSpec.shared_examples "parses good data" do |cases|
         
     | 
| 
      
 23 
     | 
    
         
            +
              describe "parses all the instances of good test data" do
         
     | 
| 
      
 24 
     | 
    
         
            +
                cases.each_with_index do |(buffer, endianness, expected), i|
         
     | 
| 
      
 25 
     | 
    
         
            +
                  it "parses plain data ##{i}" do
         
     | 
| 
      
 26 
     | 
    
         
            +
                    buffer = String.new(buffer, encoding: Encoding::BINARY)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    subject = described_class.new(buffer, endianness)
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                    results = subject.unmarshall(signature, mode: :plain)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    # unmarshall works on multiple signatures but we use one
         
     | 
| 
      
 31 
     | 
    
         
            +
                    expect(results).to be_an(Array)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    expect(results.size).to eq(1)
         
     | 
| 
      
 33 
     | 
    
         
            +
                    result = results.first
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                    expect(result).to eq(expected)
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                    expect(remaining_buffer(subject)).to be_empty
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  it "parses exact data ##{i}" do
         
     | 
| 
      
 41 
     | 
    
         
            +
                    buffer = String.new(buffer, encoding: Encoding::BINARY)
         
     | 
| 
      
 42 
     | 
    
         
            +
                    subject = described_class.new(buffer, endianness)
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                    results = subject.unmarshall(signature, mode: :exact)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    # unmarshall works on multiple signatures but we use one
         
     | 
| 
      
 46 
     | 
    
         
            +
                    expect(results).to be_an(Array)
         
     | 
| 
      
 47 
     | 
    
         
            +
                    expect(results.size).to eq(1)
         
     | 
| 
      
 48 
     | 
    
         
            +
                    result = results.first
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                    expect(result).to be_a(DBus::Data::Base)
         
     | 
| 
      
 51 
     | 
    
         
            +
                    expect(result.value).to eq(expected)
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                    expect(remaining_buffer(subject)).to be_empty
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
      
 56 
     | 
    
         
            +
              end
         
     | 
| 
      
 57 
     | 
    
         
            +
            end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            # this is necessary because we do an early switch on the signature
         
     | 
| 
      
 60 
     | 
    
         
            +
            RSpec.shared_examples "reports empty data" do
         
     | 
| 
      
 61 
     | 
    
         
            +
              it "reports empty data" do
         
     | 
| 
      
 62 
     | 
    
         
            +
                [:big, :little].each do |endianness|
         
     | 
| 
      
 63 
     | 
    
         
            +
                  subject = described_class.new("", endianness)
         
     | 
| 
      
 64 
     | 
    
         
            +
                  expect { subject.unmarshall(signature) }.to raise_error(DBus::IncompleteBufferException)
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
              end
         
     | 
| 
      
 67 
     | 
    
         
            +
            end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
            describe DBus::PacketUnmarshaller do
         
     | 
| 
      
 70 
     | 
    
         
            +
              context "marshall.yaml" do
         
     | 
| 
      
 71 
     | 
    
         
            +
                marshall_yaml.each do |test|
         
     | 
| 
      
 72 
     | 
    
         
            +
                  t = OpenStruct.new(test)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  signature = t.sig
         
     | 
| 
      
 74 
     | 
    
         
            +
                  buffer = buffer_from_yaml(t.buf)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  endianness = t.end.to_sym
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                  # successful parse
         
     | 
| 
      
 78 
     | 
    
         
            +
                  if !t.val.nil?
         
     | 
| 
      
 79 
     | 
    
         
            +
                    expected = t.val
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                    it "parses a '#{signature}' to get #{t.val.inspect} (plain)" do
         
     | 
| 
      
 82 
     | 
    
         
            +
                      subject = described_class.new(buffer, endianness)
         
     | 
| 
      
 83 
     | 
    
         
            +
                      results = subject.unmarshall(signature, mode: :plain)
         
     | 
| 
      
 84 
     | 
    
         
            +
                      # unmarshall works on multiple signatures but we use one
         
     | 
| 
      
 85 
     | 
    
         
            +
                      expect(results).to be_an(Array)
         
     | 
| 
      
 86 
     | 
    
         
            +
                      expect(results.size).to eq(1)
         
     | 
| 
      
 87 
     | 
    
         
            +
                      result = results.first
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                      expect(result).to eq(expected)
         
     | 
| 
      
 90 
     | 
    
         
            +
                      expect(remaining_buffer(subject)).to be_empty
         
     | 
| 
      
 91 
     | 
    
         
            +
                    end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                    it "parses a '#{t.sig}' to get #{t.val.inspect} (exact)" do
         
     | 
| 
      
 94 
     | 
    
         
            +
                      subject = described_class.new(buffer, endianness)
         
     | 
| 
      
 95 
     | 
    
         
            +
                      results = subject.unmarshall(signature, mode: :exact)
         
     | 
| 
      
 96 
     | 
    
         
            +
                      # unmarshall works on multiple signatures but we use one
         
     | 
| 
      
 97 
     | 
    
         
            +
                      expect(results).to be_an(Array)
         
     | 
| 
      
 98 
     | 
    
         
            +
                      expect(results.size).to eq(1)
         
     | 
| 
      
 99 
     | 
    
         
            +
                      result = results.first
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                      expect(result).to be_a(DBus::Data::Base)
         
     | 
| 
      
 102 
     | 
    
         
            +
                      expect(result.value).to eq(expected)
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                      expect(remaining_buffer(subject)).to be_empty
         
     | 
| 
      
 105 
     | 
    
         
            +
                    end
         
     | 
| 
      
 106 
     | 
    
         
            +
                  elsif t.exc
         
     | 
| 
      
 107 
     | 
    
         
            +
                    next if t.unmarshall == false
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                    exc_class = DBus.const_get(t.exc)
         
     | 
| 
      
 110 
     | 
    
         
            +
                    msg_re = Regexp.new(Regexp.escape(t.msg))
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                    # TODO: InvalidPacketException is never rescued.
         
     | 
| 
      
 113 
     | 
    
         
            +
                    # The other end is sending invalid data. Can we do better than crashing?
         
     | 
| 
      
 114 
     | 
    
         
            +
                    # When we can test with peer connections, try it out.
         
     | 
| 
      
 115 
     | 
    
         
            +
                    it "parses a '#{signature}' to report a #{t.exc}" do
         
     | 
| 
      
 116 
     | 
    
         
            +
                      subject = described_class.new(buffer, endianness)
         
     | 
| 
      
 117 
     | 
    
         
            +
                      expect { subject.unmarshall(signature, mode: :plain) }.to raise_error(exc_class, msg_re)
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                      subject = described_class.new(buffer, endianness)
         
     | 
| 
      
 120 
     | 
    
         
            +
                      expect { subject.unmarshall(signature, mode: :exact) }.to raise_error(exc_class, msg_re)
         
     | 
| 
      
 121 
     | 
    
         
            +
                    end
         
     | 
| 
      
 122 
     | 
    
         
            +
                  end
         
     | 
| 
      
 123 
     | 
    
         
            +
                end
         
     | 
| 
      
 124 
     | 
    
         
            +
              end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
              context "BYTEs" do
         
     | 
| 
      
 127 
     | 
    
         
            +
                let(:signature) { "y" }
         
     | 
| 
      
 128 
     | 
    
         
            +
                include_examples "reports empty data"
         
     | 
| 
      
 129 
     | 
    
         
            +
              end
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
              context "BOOLEANs" do
         
     | 
| 
      
 132 
     | 
    
         
            +
                let(:signature) { "b" }
         
     | 
| 
      
 133 
     | 
    
         
            +
                include_examples "reports empty data"
         
     | 
| 
      
 134 
     | 
    
         
            +
              end
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
              context "INT16s" do
         
     | 
| 
      
 137 
     | 
    
         
            +
                let(:signature) { "n" }
         
     | 
| 
      
 138 
     | 
    
         
            +
                include_examples "reports empty data"
         
     | 
| 
      
 139 
     | 
    
         
            +
              end
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
              context "UINT16s" do
         
     | 
| 
      
 142 
     | 
    
         
            +
                let(:signature) { "q" }
         
     | 
| 
      
 143 
     | 
    
         
            +
                include_examples "reports empty data"
         
     | 
| 
      
 144 
     | 
    
         
            +
              end
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
              context "INT32s" do
         
     | 
| 
      
 147 
     | 
    
         
            +
                let(:signature) { "i" }
         
     | 
| 
      
 148 
     | 
    
         
            +
                include_examples "reports empty data"
         
     | 
| 
      
 149 
     | 
    
         
            +
              end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
              context "UINT32s" do
         
     | 
| 
      
 152 
     | 
    
         
            +
                let(:signature) { "u" }
         
     | 
| 
      
 153 
     | 
    
         
            +
                include_examples "reports empty data"
         
     | 
| 
      
 154 
     | 
    
         
            +
              end
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
              context "UNIX_FDs" do
         
     | 
| 
      
 157 
     | 
    
         
            +
                let(:signature) { "h" }
         
     | 
| 
      
 158 
     | 
    
         
            +
                include_examples "reports empty data"
         
     | 
| 
      
 159 
     | 
    
         
            +
              end
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
              context "INT64s" do
         
     | 
| 
      
 162 
     | 
    
         
            +
                let(:signature) { "x" }
         
     | 
| 
      
 163 
     | 
    
         
            +
                include_examples "reports empty data"
         
     | 
| 
      
 164 
     | 
    
         
            +
              end
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
              context "UINT64s" do
         
     | 
| 
      
 167 
     | 
    
         
            +
                let(:signature) { "t" }
         
     | 
| 
      
 168 
     | 
    
         
            +
                include_examples "reports empty data"
         
     | 
| 
      
 169 
     | 
    
         
            +
              end
         
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
      
 171 
     | 
    
         
            +
              context "DOUBLEs" do
         
     | 
| 
      
 172 
     | 
    
         
            +
                let(:signature) { "d" }
         
     | 
| 
      
 173 
     | 
    
         
            +
                # See https://en.wikipedia.org/wiki/Double-precision_floating-point_format
         
     | 
| 
      
 174 
     | 
    
         
            +
                # for binary representations
         
     | 
| 
      
 175 
     | 
    
         
            +
                # TODO: figure out IEEE754 comparisons
         
     | 
| 
      
 176 
     | 
    
         
            +
                good = [
         
     | 
| 
      
 177 
     | 
    
         
            +
                  # But == cant distinguish -0.0
         
     | 
| 
      
 178 
     | 
    
         
            +
                  ["\x00\x00\x00\x00\x00\x00\x00\x80", :little, -0.0],
         
     | 
| 
      
 179 
     | 
    
         
            +
                  # But NaN == NaN is false!
         
     | 
| 
      
 180 
     | 
    
         
            +
                  # ["\xff\xff\xff\xff\xff\xff\xff\xff", :little, Float::NAN],
         
     | 
| 
      
 181 
     | 
    
         
            +
                  ["\x80\x00\x00\x00\x00\x00\x00\x00", :big, -0.0]
         
     | 
| 
      
 182 
     | 
    
         
            +
                  # ["\xff\xff\xff\xff\xff\xff\xff\xff", :big, Float::NAN]
         
     | 
| 
      
 183 
     | 
    
         
            +
                ]
         
     | 
| 
      
 184 
     | 
    
         
            +
                include_examples "parses good data", good
         
     | 
| 
      
 185 
     | 
    
         
            +
                include_examples "reports empty data"
         
     | 
| 
      
 186 
     | 
    
         
            +
              end
         
     | 
| 
      
 187 
     | 
    
         
            +
             
     | 
| 
      
 188 
     | 
    
         
            +
              context "STRINGs" do
         
     | 
| 
      
 189 
     | 
    
         
            +
                let(:signature) { "s" }
         
     | 
| 
      
 190 
     | 
    
         
            +
                include_examples "reports empty data"
         
     | 
| 
      
 191 
     | 
    
         
            +
              end
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
              context "OBJECT_PATHs" do
         
     | 
| 
      
 194 
     | 
    
         
            +
                let(:signature) { "o" }
         
     | 
| 
      
 195 
     | 
    
         
            +
                include_examples "reports empty data"
         
     | 
| 
      
 196 
     | 
    
         
            +
              end
         
     | 
| 
      
 197 
     | 
    
         
            +
             
     | 
| 
      
 198 
     | 
    
         
            +
              context "SIGNATUREs" do
         
     | 
| 
      
 199 
     | 
    
         
            +
                let(:signature) { "g" }
         
     | 
| 
      
 200 
     | 
    
         
            +
                include_examples "reports empty data"
         
     | 
| 
      
 201 
     | 
    
         
            +
              end
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
      
 203 
     | 
    
         
            +
              context "ARRAYs" do
         
     | 
| 
      
 204 
     | 
    
         
            +
                context "of BYTEs" do
         
     | 
| 
      
 205 
     | 
    
         
            +
                  let(:signature) { "ay" }
         
     | 
| 
      
 206 
     | 
    
         
            +
                  include_examples "reports empty data"
         
     | 
| 
      
 207 
     | 
    
         
            +
                end
         
     | 
| 
      
 208 
     | 
    
         
            +
             
     | 
| 
      
 209 
     | 
    
         
            +
                context "of UINT64s" do
         
     | 
| 
      
 210 
     | 
    
         
            +
                  let(:signature) { "at" }
         
     | 
| 
      
 211 
     | 
    
         
            +
                  include_examples "reports empty data"
         
     | 
| 
      
 212 
     | 
    
         
            +
                end
         
     | 
| 
      
 213 
     | 
    
         
            +
             
     | 
| 
      
 214 
     | 
    
         
            +
                context "of STRUCT of 2 UINT16s" do
         
     | 
| 
      
 215 
     | 
    
         
            +
                  let(:signature) { "a(qq)" }
         
     | 
| 
      
 216 
     | 
    
         
            +
                  include_examples "reports empty data"
         
     | 
| 
      
 217 
     | 
    
         
            +
                end
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
      
 219 
     | 
    
         
            +
                context "of DICT_ENTRIES" do
         
     | 
| 
      
 220 
     | 
    
         
            +
                  let(:signature) { "a{yq}" }
         
     | 
| 
      
 221 
     | 
    
         
            +
                  include_examples "reports empty data"
         
     | 
| 
      
 222 
     | 
    
         
            +
                end
         
     | 
| 
      
 223 
     | 
    
         
            +
              end
         
     | 
| 
      
 224 
     | 
    
         
            +
             
     | 
| 
      
 225 
     | 
    
         
            +
              context "STRUCTs" do
         
     | 
| 
      
 226 
     | 
    
         
            +
                # TODO: this is invalid but does not raise
         
     | 
| 
      
 227 
     | 
    
         
            +
                context "(generic 'r' struct)" do
         
     | 
| 
      
 228 
     | 
    
         
            +
                  let(:signature) { "r" }
         
     | 
| 
      
 229 
     | 
    
         
            +
                end
         
     | 
| 
      
 230 
     | 
    
         
            +
             
     | 
| 
      
 231 
     | 
    
         
            +
                context "of two shorts" do
         
     | 
| 
      
 232 
     | 
    
         
            +
                  let(:signature) { "(qq)" }
         
     | 
| 
      
 233 
     | 
    
         
            +
                  include_examples "reports empty data"
         
     | 
| 
      
 234 
     | 
    
         
            +
                end
         
     | 
| 
      
 235 
     | 
    
         
            +
              end
         
     | 
| 
      
 236 
     | 
    
         
            +
             
     | 
| 
      
 237 
     | 
    
         
            +
              # makes sense here? or in array? remember invalid sigs are rejected elsewhere
         
     | 
| 
      
 238 
     | 
    
         
            +
              context "DICT_ENTRYs" do
         
     | 
| 
      
 239 
     | 
    
         
            +
                context "(generic 'e' dict_entry)" do
         
     | 
| 
      
 240 
     | 
    
         
            +
                  let(:signature) { "e" }
         
     | 
| 
      
 241 
     | 
    
         
            +
                end
         
     | 
| 
      
 242 
     | 
    
         
            +
              end
         
     | 
| 
      
 243 
     | 
    
         
            +
             
     | 
| 
      
 244 
     | 
    
         
            +
              context "VARIANTs" do
         
     | 
| 
      
 245 
     | 
    
         
            +
                let(:signature) { "v" }
         
     | 
| 
      
 246 
     | 
    
         
            +
                include_examples "reports empty data"
         
     | 
| 
      
 247 
     | 
    
         
            +
              end
         
     | 
| 
      
 248 
     | 
    
         
            +
            end
         
     |