Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package rubygem-ruby-dbus for 
openSUSE:Factory checked in at 2022-06-23 10:22:13
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-ruby-dbus (Old)
 and      /work/SRC/openSUSE:Factory/.rubygem-ruby-dbus.new.1548 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rubygem-ruby-dbus"

Thu Jun 23 10:22:13 2022 rev:30 rq:984133 version:0.18.0.beta8

Changes:
--------
--- /work/SRC/openSUSE:Factory/rubygem-ruby-dbus/rubygem-ruby-dbus.changes      
2022-05-30 12:42:14.760254430 +0200
+++ 
/work/SRC/openSUSE:Factory/.rubygem-ruby-dbus.new.1548/rubygem-ruby-dbus.changes
    2022-06-23 10:22:16.607610013 +0200
@@ -1,0 +2,16 @@
+Tue Jun 21 09:54:22 UTC 2022 - Martin Vidner <mvid...@suse.com>
+
+- 0.18.0.beta8
+ Bug fixes:
+ * Introduced Object#dbus_properties_changed to send correctly typed property
+   values (gh#mvidner/ruby-dbus#115). Avoid calling PropertiesChanged directly
+   as it will guess the types.
+ * Fix Object.dbus_reader to work with attr_accessor and automatically produce
+   dbus_properties_changed for properties that are read-write at
+   implementation side and read-only at D-Bus side (gh#mvidner/ruby-dbus#96)
+ API:
+ * Service side `emits_changed_signal` to control emission of
+   PropertiesChanged: can be assigned within `dbus_interface` or as an option
+   when declaring properties (gh#mvidner/ruby-dbus#117).
+
+-------------------------------------------------------------------

Old:
----
  ruby-dbus-0.18.0.beta7.gem

New:
----
  ruby-dbus-0.18.0.beta8.gem

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ rubygem-ruby-dbus.spec ++++++
--- /var/tmp/diff_new_pack.TxXGBJ/_old  2022-06-23 10:22:17.023610465 +0200
+++ /var/tmp/diff_new_pack.TxXGBJ/_new  2022-06-23 10:22:17.027610470 +0200
@@ -24,7 +24,7 @@
 #
 
 Name:           rubygem-ruby-dbus
-Version:        0.18.0.beta7
+Version:        0.18.0.beta8
 Release:        0
 %define mod_name ruby-dbus
 %define mod_full_name %{mod_name}-%{version}

++++++ ruby-dbus-0.18.0.beta7.gem -> ruby-dbus-0.18.0.beta8.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/NEWS.md new/NEWS.md
--- old/NEWS.md 2022-05-29 10:48:54.000000000 +0200
+++ new/NEWS.md 2022-06-21 12:04:46.000000000 +0200
@@ -2,6 +2,26 @@
 
 ## Unreleased
 
+## Ruby D-Bus 0.18.0.beta8 - 2022-06-21
+
+Bug fixes:
+ * Introduced Object#dbus_properties_changed to send correctly typed property
+   values ([#115][]). Avoid calling PropertiesChanged directly as it will
+   guess the types.
+ * Fix Object.dbus_reader to work with attr_accessor and automatically produce
+   dbus_properties_changed for properties that are read-write at
+   implementation side and read-only at D-Bus side ([#96][])
+
+[#96]: https://github.com/mvidner/ruby-dbus/issues/96
+
+API:
+ * Service side `emits_changed_signal` to control emission of
+   PropertiesChanged: can be assigned within `dbus_interface` or as an option
+   when declaring properties ([#117][]).
+
+[#115]: https://github.com/mvidner/ruby-dbus/issues/115
+[#117]: https://github.com/mvidner/ruby-dbus/pulls/117
+
 ## Ruby D-Bus 0.18.0.beta7 - 2022-05-29
 
 API:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/VERSION new/VERSION
--- old/VERSION 2022-05-29 10:48:54.000000000 +0200
+++ new/VERSION 2022-06-21 12:04:46.000000000 +0200
@@ -1 +1 @@
-0.18.0.beta7
+0.18.0.beta8
Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dbus/bus.rb new/lib/dbus/bus.rb
--- old/lib/dbus/bus.rb 2022-05-29 10:48:54.000000000 +0200
+++ new/lib/dbus/bus.rb 2022-06-21 12:04:46.000000000 +0200
@@ -171,15 +171,11 @@
 "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd";>
 '
       xml += "<node name=\"#{node_opath}\">\n"
-      each_pair do |k, _v|
+      each_key do |k|
         xml += "  <node name=\"#{k}\" />\n"
       end
-      @object&.intfs&.each_pair do |_k, v|
-        xml += "  <interface name=\"#{v.name}\">\n"
-        v.methods.each_value { |m| xml += m.to_xml }
-        v.signals.each_value { |m| xml += m.to_xml }
-        v.properties.each_value { |m| xml += m.to_xml }
-        xml += "  </interface>\n"
+      @object&.intfs&.each_value do |v|
+        xml += v.to_xml
       end
       xml += "</node>"
       xml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dbus/emits_changed_signal.rb 
new/lib/dbus/emits_changed_signal.rb
--- old/lib/dbus/emits_changed_signal.rb        1970-01-01 01:00:00.000000000 
+0100
+++ new/lib/dbus/emits_changed_signal.rb        2022-06-21 12:04:46.000000000 
+0200
@@ -0,0 +1,83 @@
+# frozen_string_literal: true
+
+# This file is part of the ruby-dbus project
+# Copyright (C) 2022 Martin Vidner
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License, version 2.1 as published by the Free Software Foundation.
+# See the file "COPYING" for the exact licensing terms.
+
+module DBus
+  # Describes the behavior of PropertiesChanged signal, for a single property
+  # or for an entire interface.
+  #
+  # The possible values are:
+  #
+  # - *true*: the signal is emitted with the value included.
+  # - *:invalidates*: the signal is emitted but the value is not included
+  #   in the signal.
+  # - *:const*: the property never changes value during the lifetime
+  #   of the object it belongs to, and hence the signal
+  #   is never emitted for it (but clients can cache the value)
+  # - *false*: the signal won't be emitted (clients should re-Get the property 
value)
+  #
+  # The default is:
+  # - for an interface: *true*
+  # - for a property: what the parent interface specifies
+  #
+  # @see DBus::Object.emits_changed_signal
+  # @see DBus::Object.dbus_attr_accessor
+  # @see 
https://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format
+  #
+  # Immutable once constructed.
+  class EmitsChangedSignal
+    # @return [true,false,:const,:invalidates]
+    attr_reader :value
+
+    # @param value [true,false,:const,:invalidates,nil]
+    #   See class-level description above, {EmitsChangedSignal}.
+    # @param interface [Interface,nil]
+    #   If the (property-level) *value* is unspecified (nil), this is the
+    #   containing {Interface} to get the value from.
+    def initialize(value, interface: nil)
+      if value.nil?
+        raise ArgumentError, "Both arguments are nil" if interface.nil?
+
+        @value = interface.emits_changed_signal.value
+      else
+        expecting = [true, false, :const, :invalidates]
+        unless expecting.include?(value)
+          raise ArgumentError, "Expecting one of #{expecting.inspect}. Seen 
#{value.inspect}"
+        end
+
+        @value = value
+      end
+
+      freeze
+    end
+
+    # Return introspection XML string representation
+    # @return [String]
+    def to_xml
+      return "" if @value == true
+
+      "    <annotation 
name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" 
value=\"#{@value}\"/>\n"
+    end
+
+    def to_s
+      @value.to_s
+    end
+
+    def ==(other)
+      if other.is_a?(self.class)
+        other.value == @value
+      else
+        other == value
+      end
+    end
+    alias eql? ==
+
+    DEFAULT_ECS = EmitsChangedSignal.new(true)
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dbus/introspect.rb new/lib/dbus/introspect.rb
--- old/lib/dbus/introspect.rb  2022-05-29 10:48:54.000000000 +0200
+++ new/lib/dbus/introspect.rb  2022-06-21 12:04:46.000000000 +0200
@@ -26,7 +26,7 @@
   # method call instantiates and configures this class for us.
   #
   # It also is the local definition of interface exported by the program.
-  # At the client side, see ProxyObjectInterface
+  # At the client side, see {ProxyObjectInterface}.
   class Interface
     # @return [String] The name of the interface.
     attr_reader :name
@@ -38,6 +38,9 @@
     # @return [Hash{Symbol => Property}]
     attr_reader :properties
 
+    # @return [EmitsChangedSignal]
+    attr_reader :emits_changed_signal
+
     # Creates a new interface with a given _name_.
     def initialize(name)
       validate_name(name)
@@ -45,6 +48,20 @@
       @methods = {}
       @signals = {}
       @properties = {}
+      @emits_changed_signal = EmitsChangedSignal::DEFAULT_ECS
+    end
+
+    # Helper for {Object.emits_changed_signal=}.
+    # @api private
+    def emits_changed_signal=(ecs)
+      raise TypeError unless ecs.is_a? EmitsChangedSignal
+      # equal?: object identity
+      unless @emits_changed_signal.equal?(EmitsChangedSignal::DEFAULT_ECS) ||
+             @emits_changed_signal.value == ecs.value
+        raise "emits_change_signal was assigned more than once"
+      end
+
+      @emits_changed_signal = ecs
     end
 
     # Validates a service _name_.
@@ -85,6 +102,18 @@
       define(m)
     end
     alias declare_method define_method
+
+    # Return introspection XML string representation of the property.
+    # @return [String]
+    def to_xml
+      xml = "  <interface name=\"#{name}\">\n"
+      xml += emits_changed_signal.to_xml
+      methods.each_value { |m| xml += m.to_xml }
+      signals.each_value { |m| xml += m.to_xml }
+      properties.each_value { |m| xml += m.to_xml }
+      xml += "  </interface>\n"
+      xml
+    end
   end
 
   # = A formal parameter has a name and a type
@@ -190,6 +219,7 @@
     end
 
     # Return an XML string representation of the method interface elment.
+    # @return [String]
     def to_xml
       xml = "    <method name=\"#{@name}\">\n"
       @params.each do |param|
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dbus/object.rb new/lib/dbus/object.rb
--- old/lib/dbus/object.rb      2022-05-29 10:48:54.000000000 +0200
+++ new/lib/dbus/object.rb      2022-06-21 12:04:46.000000000 +0200
@@ -102,6 +102,18 @@
       end
     end
 
+    # Declare the behavior of PropertiesChanged signal,
+    # common for all properties in this interface
+    # (individual properties may override it)
+    # @example
+    #   self.emits_changed_signal = :invalidates
+    # @param [true,false,:const,:invalidates] value
+    def self.emits_changed_signal=(value)
+      raise UndefinedInterface, :emits_changed_signal if @@cur_intf.nil?
+
+      @@cur_intf.emits_changed_signal = EmitsChangedSignal.new(value)
+    end
+
     # A read-write property accessing an instance variable.
     # A combination of `attr_accessor` and {.dbus_accessor}.
     #
@@ -114,11 +126,13 @@
     # @param dbus_name [String] if not given it is made
     #   by CamelCasing the ruby_name. foo_bar becomes FooBar
     #   to convert the Ruby convention to the DBus convention.
+    # @param emits_changed_signal [true,false,:const,:invalidates]
+    #   see {EmitsChangedSignal}; if unspecified, ask the interface.
     # @return [void]
-    def self.dbus_attr_accessor(ruby_name, type, dbus_name: nil)
+    def self.dbus_attr_accessor(ruby_name, type, dbus_name: nil, 
emits_changed_signal: nil)
       attr_accessor(ruby_name)
 
-      dbus_accessor(ruby_name, type, dbus_name: dbus_name)
+      dbus_accessor(ruby_name, type, dbus_name: dbus_name, 
emits_changed_signal: emits_changed_signal)
     end
 
     # A read-only property accessing an instance variable.
@@ -126,19 +140,20 @@
     #
     # Whenever the property value gets changed from "inside" the object,
     # you should emit the `PropertiesChanged` signal by calling
+    # {#dbus_properties_changed}.
     #
-    #   object[DBus::PROPERTY_INTERFACE].PropertiesChanged(interface_name, 
{dbus_name.to_s => value}, [])
+    #   dbus_properties_changed(interface_name, {dbus_name.to_s => value}, [])
     #
     # or, omitting the value in the signal,
     #
-    #   object[DBus::PROPERTY_INTERFACE].PropertiesChanged(interface_name, {}, 
[dbus_name.to_s])
+    #   dbus_properties_changed(interface_name, {}, [dbus_name.to_s])
     #
     # @param  (see .dbus_attr_accessor)
     # @return (see .dbus_attr_accessor)
-    def self.dbus_attr_reader(ruby_name, type, dbus_name: nil)
+    def self.dbus_attr_reader(ruby_name, type, dbus_name: nil, 
emits_changed_signal: nil)
       attr_reader(ruby_name)
 
-      dbus_reader(ruby_name, type, dbus_name: dbus_name)
+      dbus_reader(ruby_name, type, dbus_name: dbus_name, emits_changed_signal: 
emits_changed_signal)
     end
 
     # A write-only property accessing an instance variable.
@@ -146,10 +161,10 @@
     #
     # @param  (see .dbus_attr_accessor)
     # @return (see .dbus_attr_accessor)
-    def self.dbus_attr_writer(ruby_name, type, dbus_name: nil)
+    def self.dbus_attr_writer(ruby_name, type, dbus_name: nil, 
emits_changed_signal: nil)
       attr_writer(ruby_name)
 
-      dbus_writer(ruby_name, type, dbus_name: dbus_name)
+      dbus_writer(ruby_name, type, dbus_name: dbus_name, emits_changed_signal: 
emits_changed_signal)
     end
 
     # A read-write property using a pair of reader/writer methods
@@ -160,36 +175,49 @@
     #
     # @param  (see .dbus_attr_accessor)
     # @return (see .dbus_attr_accessor)
-    def self.dbus_accessor(ruby_name, type, dbus_name: nil)
+    def self.dbus_accessor(ruby_name, type, dbus_name: nil, 
emits_changed_signal: nil)
       raise UndefinedInterface, ruby_name if @@cur_intf.nil?
 
       dbus_name = make_dbus_name(ruby_name, dbus_name: dbus_name)
       property = Property.new(dbus_name, type, :readwrite, ruby_name: 
ruby_name)
       @@cur_intf.define(property)
 
-      dbus_watcher(ruby_name, dbus_name: dbus_name)
+      dbus_watcher(ruby_name, dbus_name: dbus_name, emits_changed_signal: 
emits_changed_signal)
     end
 
     # A read-only property accessing a reader method (which must already 
exist).
     # (To directly access an instance variable, use {.dbus_attr_reader} 
instead)
     #
-    # Whenever the property value gets changed from "inside" the object,
+    # At the D-Bus side the property is read only but it makes perfect sense to
+    # implement it with a read-write attr_accessor. In that case this method
+    # uses {.dbus_watcher} to set up the PropertiesChanged signal.
+    #
+    #   attr_accessor :foo_bar
+    #   dbus_reader :foo_bar, "s"
+    #
+    # If the property value should change by other means than its attr_writer,
     # you should emit the `PropertiesChanged` signal by calling
+    # {#dbus_properties_changed}.
     #
-    #   object[DBus::PROPERTY_INTERFACE].PropertiesChanged(interface_name, 
{dbus_name.to_s => value}, [])
+    #   dbus_properties_changed(interface_name, {dbus_name.to_s => value}, [])
     #
     # or, omitting the value in the signal,
     #
-    #   object[DBus::PROPERTY_INTERFACE].PropertiesChanged(interface_name, {}, 
[dbus_name.to_s])
+    #   dbus_properties_changed(interface_name, {}, [dbus_name.to_s])
     #
     # @param  (see .dbus_attr_accessor)
     # @return (see .dbus_attr_accessor)
-    def self.dbus_reader(ruby_name, type, dbus_name: nil)
+    def self.dbus_reader(ruby_name, type, dbus_name: nil, 
emits_changed_signal: nil)
       raise UndefinedInterface, ruby_name if @@cur_intf.nil?
 
       dbus_name = make_dbus_name(ruby_name, dbus_name: dbus_name)
       property = Property.new(dbus_name, type, :read, ruby_name: ruby_name)
       @@cur_intf.define(property)
+
+      ruby_name_eq = "#{ruby_name}=".to_sym
+      return unless method_defined?(ruby_name_eq)
+
+      dbus_watcher(ruby_name, dbus_name: dbus_name, emits_changed_signal: 
emits_changed_signal)
     end
 
     # A write-only property accessing a writer method (which must already 
exist).
@@ -199,14 +227,14 @@
     #
     # @param  (see .dbus_attr_accessor)
     # @return (see .dbus_attr_accessor)
-    def self.dbus_writer(ruby_name, type, dbus_name: nil)
+    def self.dbus_writer(ruby_name, type, dbus_name: nil, 
emits_changed_signal: nil)
       raise UndefinedInterface, ruby_name if @@cur_intf.nil?
 
       dbus_name = make_dbus_name(ruby_name, dbus_name: dbus_name)
       property = Property.new(dbus_name, type, :write, ruby_name: ruby_name)
       @@cur_intf.define(property)
 
-      dbus_watcher(ruby_name, dbus_name: dbus_name)
+      dbus_watcher(ruby_name, dbus_name: dbus_name, emits_changed_signal: 
emits_changed_signal)
     end
 
     # Enables automatic sending of the PropertiesChanged signal.
@@ -218,11 +246,13 @@
     # @param dbus_name [String] if not given it is made
     #   by CamelCasing the ruby_name. foo_bar becomes FooBar
     #   to convert the Ruby convention to the DBus convention.
+    # @param emits_changed_signal [true,false,:const,:invalidates]
+    #   see {EmitsChangedSignal}; if unspecified, ask the interface.
     # @return [void]
-    def self.dbus_watcher(ruby_name, dbus_name: nil)
+    def self.dbus_watcher(ruby_name, dbus_name: nil, emits_changed_signal: nil)
       raise UndefinedInterface, ruby_name if @@cur_intf.nil?
 
-      cur_intf = @@cur_intf
+      interface_name = @@cur_intf.name
 
       ruby_name = ruby_name.to_s.sub(/=$/, "").to_sym
       ruby_name_eq = "#{ruby_name}=".to_sym
@@ -230,14 +260,27 @@
 
       dbus_name = make_dbus_name(ruby_name, dbus_name: dbus_name)
 
+      emits_changed_signal = EmitsChangedSignal.new(emits_changed_signal, 
interface: @@cur_intf)
+
       # the argument order is alias_method(new_name, existing_name)
       alias_method original_ruby_name_eq, ruby_name_eq
       define_method ruby_name_eq do |value|
-        public_send(original_ruby_name_eq, value)
+        result = public_send(original_ruby_name_eq, value)
 
-        # TODO: respect EmitsChangedSignal to use invalidated_properties 
instead
-        # PropertiesChanged, "interface:s, changed_properties:a{sv}, 
invalidated_properties:as"
-        PropertiesChanged(cur_intf.name, { dbus_name.to_s => value }, [])
+        case emits_changed_signal.value
+        when true
+          # signature: "interface:s, changed_props:a{sv}, invalidated_props:as"
+          dbus_properties_changed(interface_name, { dbus_name.to_s => value }, 
[])
+        when :invalidates
+          dbus_properties_changed(interface_name, {}, [dbus_name.to_s])
+        when :const
+          # Oh my, seeing a value change of a supposedly constant property.
+          # Maybe should have raised at declaration time, don't make a fuss 
now.
+        when false
+          # Do nothing
+        end
+
+        result
       end
     end
 
@@ -301,6 +344,25 @@
       dbus_name.to_sym
     end
 
+    # Use this instead of calling PropertiesChanged directly. This one
+    # considers not only the PC signature (which says that all property values
+    # are variants) but also the specific property type.
+    # @param interface_name [String] interface name like 
"org.example.ManagerManager"
+    # @param changed_props [Hash{String => ::Object}]
+    #   changed properties (D-Bus names) and their values.
+    # @param invalidated_props [Array<String>]
+    #   names of properties whose changed value is not specified
+    def dbus_properties_changed(interface_name, changed_props, 
invalidated_props)
+      typed_changed_props = changed_props.map do |dbus_name, value|
+        property = dbus_lookup_property(interface_name, dbus_name)
+        type = property.type
+        typed_value = Data.make_typed(type, value)
+        variant = Data::Variant.new(typed_value, member_type: type)
+        [dbus_name, variant]
+      end.to_h
+      PropertiesChanged(interface_name, typed_changed_props, invalidated_props)
+    end
+
     # @param interface_name [String]
     # @param property_name [String]
     # @return [Property]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dbus/type.rb new/lib/dbus/type.rb
--- old/lib/dbus/type.rb        2022-05-29 10:48:54.000000000 +0200
+++ new/lib/dbus/type.rb        2022-06-21 12:04:46.000000000 +0200
@@ -415,7 +415,7 @@
   # @param string_type [SingleCompleteType]
   # @param value [::Object]
   # @return [Array(DBus::Type::Type,::Object)]
-  # @deprecated Use {Data::Variant.new} instead
+  # @deprecated Use {Data::Variant#initialize} instead
   def variant(string_type, value)
     Data::Variant.new(value, member_type: string_type)
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dbus.rb new/lib/dbus.rb
--- old/lib/dbus.rb     2022-05-29 10:48:54.000000000 +0200
+++ new/lib/dbus.rb     2022-06-21 12:04:46.000000000 +0200
@@ -15,6 +15,7 @@
 require_relative "dbus/bus"
 require_relative "dbus/bus_name"
 require_relative "dbus/data"
+require_relative "dbus/emits_changed_signal"
 require_relative "dbus/error"
 require_relative "dbus/introspect"
 require_relative "dbus/logger"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata        2022-05-29 10:48:54.000000000 +0200
+++ new/metadata        2022-06-21 12:04:46.000000000 +0200
@@ -1,14 +1,14 @@
 --- !ruby/object:Gem::Specification
 name: ruby-dbus
 version: !ruby/object:Gem::Version
-  version: 0.18.0.beta7
+  version: 0.18.0.beta8
 platform: ruby
 authors:
 - Ruby DBus Team
-autorequire:
+autorequire: 
 bindir: bin
 cert_chain: []
-date: 2022-05-29 00:00:00.000000000 Z
+date: 2022-06-21 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
   name: rexml
@@ -146,6 +146,7 @@
 - lib/dbus/core_ext/class/attribute.rb
 - lib/dbus/core_ext/module/redefine_method.rb
 - lib/dbus/data.rb
+- lib/dbus/emits_changed_signal.rb
 - lib/dbus/error.rb
 - lib/dbus/introspect.rb
 - lib/dbus/logger.rb
@@ -172,12 +173,14 @@
 - spec/client_robustness_spec.rb
 - spec/data/marshall.yaml
 - spec/data_spec.rb
+- spec/emits_changed_signal_spec.rb
 - spec/err_msg_spec.rb
 - spec/introspect_xml_parser_spec.rb
 - spec/introspection_spec.rb
 - spec/main_loop_spec.rb
 - spec/node_spec.rb
 - spec/object_path_spec.rb
+- spec/object_spec.rb
 - spec/packet_marshaller_spec.rb
 - spec/packet_unmarshaller_spec.rb
 - spec/property_spec.rb
@@ -202,7 +205,7 @@
 licenses:
 - LGPL-2.1
 metadata: {}
-post_install_message:
+post_install_message: 
 rdoc_options: []
 require_paths:
 - lib
@@ -217,8 +220,9 @@
     - !ruby/object:Gem::Version
       version: 1.3.1
 requirements: []
-rubygems_version: 3.3.0.dev
-signing_key:
+rubyforge_project: 
+rubygems_version: 2.7.6.3
+signing_key: 
 specification_version: 4
 summary: Ruby module for interaction with D-Bus
 test_files: []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/emits_changed_signal_spec.rb 
new/spec/emits_changed_signal_spec.rb
--- old/spec/emits_changed_signal_spec.rb       1970-01-01 01:00:00.000000000 
+0100
+++ new/spec/emits_changed_signal_spec.rb       2022-06-21 12:04:46.000000000 
+0200
@@ -0,0 +1,58 @@
+#!/usr/bin/env rspec
+# frozen_string_literal: true
+
+require_relative "spec_helper"
+require "dbus"
+
+describe DBus::EmitsChangedSignal do
+  describe "#initialize" do
+    it "accepts a simple value" do
+      expect(described_class.new(:const).value).to eq :const
+    end
+
+    it "avoids nil by asking the interface" do
+      ifc = DBus::Interface.new("org.example.Foo")
+      ifc.emits_changed_signal = described_class.new(:invalidates)
+
+      expect(described_class.new(nil, interface: ifc).value).to eq :invalidates
+    end
+
+    it "fails for unknown value" do
+      expect { described_class.new(:huh) }.to raise_error(ArgumentError, /Seen 
:huh/)
+    end
+
+    it "fails for 2 nils" do
+      expect { described_class.new(nil, interface: nil) }.to 
raise_error(ArgumentError, /Both/)
+    end
+  end
+
+  describe "#==" do
+    it "is true for two different objects with the same value" do
+      const_a = described_class.new(:const)
+      const_b = described_class.new(:const)
+      expect(const_a == const_b).to be true
+    end
+  end
+
+  describe "#to_xml" do
+    it "uses a string value" do
+      expect(described_class.new(:const).to_xml)
+        .to eq "    <annotation 
name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"const\"/>\n"
+    end
+  end
+
+  describe "#to_s" do
+    it "uses a string value" do
+      expect(described_class.new(:const).to_s).to eq "const"
+    end
+  end
+end
+
+describe DBus::Interface do
+  describe ".emits_changed_signal=" do
+    it "only allows an EmitsChangedSignal as argument" do
+      ifc = described_class.new("org.ruby.Interface")
+      expect { ifc.emits_changed_signal = :const }.to raise_error(TypeError)
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/object_spec.rb new/spec/object_spec.rb
--- old/spec/object_spec.rb     1970-01-01 01:00:00.000000000 +0100
+++ new/spec/object_spec.rb     2022-06-21 12:04:46.000000000 +0200
@@ -0,0 +1,138 @@
+#!/usr/bin/env rspec
+# frozen_string_literal: true
+
+require_relative "spec_helper"
+require "dbus"
+
+class ObjectTest < DBus::Object
+  T = DBus::Type unless const_defined? "T"
+
+  dbus_interface "org.ruby.ServerTest" do
+    dbus_attr_writer :write_me, T::Struct[String, String]
+
+    attr_accessor :read_only_for_dbus
+
+    dbus_reader :read_only_for_dbus, T::STRING, emits_changed_signal: 
:invalidates
+  end
+end
+
+describe DBus::Object do
+  describe ".dbus_attr_writer" do
+    describe "the declared assignment method" do
+      # Slightly advanced RSpec:
+      # 
https://rspec.info/documentation/3.9/rspec-expectations/RSpec/Matchers.html#satisfy-instance_method
+      let(:a_struct_in_a_variant) do
+        satisfying { |x| x.is_a?(DBus::Data::Variant) && x.member_type.to_s == 
"(ss)" }
+        # ^ This formatting keeps the matcher on a single line
+        # which enables RSpec to cite it if it fails, instead of saying 
"block".
+      end
+
+      it "emits PropertyChanged with correctly typed argument" do
+        obj = ObjectTest.new("/test")
+        expect(obj).to receive(:PropertiesChanged).with(
+          "org.ruby.ServerTest",
+          {
+            "WriteMe" => a_struct_in_a_variant
+          },
+          []
+        )
+        # bug: call PC with simply the assigned value,
+        # which will need type guessing
+        obj.write_me = ["two", "strings"]
+      end
+    end
+  end
+
+  describe ".dbus_accessor" do
+    it "can only be used within a dbus_interface" do
+      expect do
+        ObjectTest.instance_exec do
+          dbus_accessor :foo, DBus::Type::STRING
+        end
+      end.to raise_error(DBus::Object::UndefinedInterface)
+    end
+  end
+
+  describe ".dbus_reader" do
+    it "can only be used within a dbus_interface" do
+      expect do
+        ObjectTest.instance_exec do
+          dbus_reader :foo, DBus::Type::STRING
+        end
+      end.to raise_error(DBus::Object::UndefinedInterface)
+    end
+  end
+
+  describe ".dbus_reader, when paired with attr_accessor" do
+    describe "the declared assignment method" do
+      it "emits PropertyChanged" do
+        obj = ObjectTest.new("/test")
+        expect(obj).to receive(:PropertiesChanged).with(
+          "org.ruby.ServerTest",
+          {},
+          ["ReadOnlyForDbus"]
+        )
+        obj.read_only_for_dbus = "myvalue"
+      end
+    end
+  end
+
+  describe ".dbus_writer" do
+    it "can only be used within a dbus_interface" do
+      expect do
+        ObjectTest.instance_exec do
+          dbus_writer :foo, DBus::Type::STRING
+        end
+      end.to raise_error(DBus::Object::UndefinedInterface)
+    end
+  end
+
+  describe ".dbus_watcher" do
+    it "can only be used within a dbus_interface" do
+      expect do
+        ObjectTest.instance_exec do
+          dbus_watcher :foo
+        end
+      end.to raise_error(DBus::Object::UndefinedInterface)
+    end
+  end
+
+  describe ".dbus_method" do
+    it "can only be used within a dbus_interface" do
+      expect do
+        ObjectTest.instance_exec do
+          dbus_method :foo do
+          end
+        end
+      end.to raise_error(DBus::Object::UndefinedInterface)
+    end
+  end
+
+  describe ".emits_changed_signal" do
+    it "raises UndefinedInterface when so" do
+      expect { ObjectTest.emits_changed_signal = false }
+        .to raise_error DBus::Object::UndefinedInterface
+    end
+
+    it "assigns to the current interface" do
+      ObjectTest.instance_exec do
+        dbus_interface "org.ruby.Interface" do
+          self.emits_changed_signal = false
+        end
+      end
+      ecs = ObjectTest.intfs["org.ruby.Interface"].emits_changed_signal
+      expect(ecs).to eq false
+    end
+
+    it "only can be assigned once" do
+      expect do
+        Class.new(DBus::Object) do
+          dbus_interface "org.ruby.Interface" do
+            self.emits_changed_signal = false
+            self.emits_changed_signal = :invalidates
+          end
+        end
+      end.to raise_error(RuntimeError, /assigned more than once/)
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/property_spec.rb new/spec/property_spec.rb
--- old/spec/property_spec.rb   2022-05-29 10:48:54.000000000 +0200
+++ new/spec/property_spec.rb   2022-06-21 12:04:46.000000000 +0200
@@ -110,6 +110,7 @@
     end
 
     @iface["ReadOrWriteMe"] = "VALUE"
+    @iface.SetTwoProperties("REAMDE", 255)
 
     # loop to process the signal. complicated :-( see signal_spec.rb
     loop = DBus::Main.new
@@ -123,6 +124,8 @@
     quitter.join
 
     expect(received["ReadOrWriteMe"]).to eq("VALUE")
+    expect(received["ReadMe"]).to eq("REAMDE")
+    expect(received["MyByte"]).to eq(255)
   end
 
   context "a struct-typed property" do
@@ -206,7 +209,7 @@
     let(:a_byte_in_a_variant) do
       satisfying { |x| x.is_a?(DBus::Data::Variant) && x.member_type.to_s == 
DBus::Type::BYTE }
       # ^ This formatting keeps the matcher on a single line
-      # which enables RSpect to cite it if it fails, instead of saying "block".
+      # which enables RSpec to cite it if it fails, instead of saying "block".
     end
 
     let(:prop_iface) { @obj[DBus::PROPERTY_INTERFACE] }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/service_newapi.rb new/spec/service_newapi.rb
--- old/spec/service_newapi.rb  2022-05-29 10:48:54.000000000 +0200
+++ new/spec/service_newapi.rb  2022-06-21 12:04:46.000000000 +0200
@@ -115,6 +115,15 @@
     dbus_attr_accessor :my_variant, "v"
 
     dbus_attr_accessor :my_byte, "y"
+
+    # to test dbus_properties_changed
+    dbus_method :SetTwoProperties, "in read_me:s, in byte:y" do |read_me, byte|
+      @read_me = read_me
+      @my_byte = byte
+      dbus_properties_changed(INTERFACE,
+                              { "ReadMe" => read_me, "MyByte" => byte },
+                              [])
+    end
   end
 
   # closing and reopening the same interface

Reply via email to