Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Cannot get QtTest to verify an signal parameter
Forum Updated to NodeBB v4.3 + New Features

Cannot get QtTest to verify an signal parameter

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 4 Posters 3.9k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    gaylord
    wrote on last edited by
    #1

    Hello. I'm trying to verify my application code, a card game, using QtTest. One thing I'm doing is emitting a signal when a card is turned face up or down.

    class Card : public QObject
    {
    		Q_OBJECT
    
    	public:
    		...
    		enum Orientation { FACE_UP, FACE_DOWN };
    		Q_ENUM(Orientation)
    		Q_PROPERTY(Orientation orientation
    		           READ getOrientation
    		           WRITE setOrientation
    		           NOTIFY orientationChanged)
    		Orientation getOrientation() const;
    		void setOrientation(Orientation orientation);
    
    	signals:
    		void orientationChanged(Orientation orientation);
    }
    
    Q_DECLARE_METATYPE(Card::Orientation);
    
    

    The signal "orientationChanged" includes an enum of type "Orientation" to indicate if the card has been turned up or down.

    In my module tests, I turn the card up and down, and can verify that the number of signals are increasing using QSignalSpy. However, I cannot figure out how to verify that the included parameter is FACE_UP or FACE_DOWN.

    	qRegisterMetaType<Card::Orientation>("Card::Orientation");
    	QSignalSpy spyCard_2_spades(card_2_Spades, SIGNAL(orientationChanged(Orientation)));
    	QVERIFY(spyCard_2_spades.count() == 0);
    
    

    I've seen messages that say to use qRegisterMetaType, so I've added that. Still, I get a warning about QSignalSpy cannot handle the parameter orientation.

    ********* Start testing of ModuleTests *********
    Config: Using QtTest library 5.9.5, Qt 5.9.5 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 7.3.0)
    PASS   : ModuleTests::initTestCase()
    QWARN  : ModuleTests::test_Card() QSignalSpy: Unable to handle parameter 'orientation' of type 'Orientation' of method 'orientationChanged', use qRegisterMetaType to register it.
    PASS   : ModuleTests::test_Card()
    PASS   : ModuleTests::cleanupTestCase()
    Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms
    ********* Finished testing of ModuleTests *********
    

    I see examples online, but using a custom type seems to bring its own issues. Can anyone tell me what I'm doing wrong, or point me to an example that handles custom data types?

    BTW, if you want to see all the code in context, it's on github at git@github.com:bob-weber/cardGame-500.git.

    Thanks everyone.

    aha_1980A 1 Reply Last reply
    0
    • G gaylord

      Hello. I'm trying to verify my application code, a card game, using QtTest. One thing I'm doing is emitting a signal when a card is turned face up or down.

      class Card : public QObject
      {
      		Q_OBJECT
      
      	public:
      		...
      		enum Orientation { FACE_UP, FACE_DOWN };
      		Q_ENUM(Orientation)
      		Q_PROPERTY(Orientation orientation
      		           READ getOrientation
      		           WRITE setOrientation
      		           NOTIFY orientationChanged)
      		Orientation getOrientation() const;
      		void setOrientation(Orientation orientation);
      
      	signals:
      		void orientationChanged(Orientation orientation);
      }
      
      Q_DECLARE_METATYPE(Card::Orientation);
      
      

      The signal "orientationChanged" includes an enum of type "Orientation" to indicate if the card has been turned up or down.

      In my module tests, I turn the card up and down, and can verify that the number of signals are increasing using QSignalSpy. However, I cannot figure out how to verify that the included parameter is FACE_UP or FACE_DOWN.

      	qRegisterMetaType<Card::Orientation>("Card::Orientation");
      	QSignalSpy spyCard_2_spades(card_2_Spades, SIGNAL(orientationChanged(Orientation)));
      	QVERIFY(spyCard_2_spades.count() == 0);
      
      

      I've seen messages that say to use qRegisterMetaType, so I've added that. Still, I get a warning about QSignalSpy cannot handle the parameter orientation.

      ********* Start testing of ModuleTests *********
      Config: Using QtTest library 5.9.5, Qt 5.9.5 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 7.3.0)
      PASS   : ModuleTests::initTestCase()
      QWARN  : ModuleTests::test_Card() QSignalSpy: Unable to handle parameter 'orientation' of type 'Orientation' of method 'orientationChanged', use qRegisterMetaType to register it.
      PASS   : ModuleTests::test_Card()
      PASS   : ModuleTests::cleanupTestCase()
      Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms
      ********* Finished testing of ModuleTests *********
      

      I see examples online, but using a custom type seems to bring its own issues. Can anyone tell me what I'm doing wrong, or point me to an example that handles custom data types?

      BTW, if you want to see all the code in context, it's on github at git@github.com:bob-weber/cardGame-500.git.

      Thanks everyone.

      aha_1980A Offline
      aha_1980A Offline
      aha_1980
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi @gaylord, welcome!

      Unfortunately your github repo is empty except the readme...

      You are alread using Q_ENUM, which is good. You can change the Q_DECLARE_METATYPE to:

      Q_DECLARE_METATYPE(Card::Orientation, Q_PRIMITIVE_TYPE);

      qRegisterMetaTypeCard::Orientation("Card::Orientation");
      QSignalSpy spyCard_2_spades(card_2_Spades, SIGNAL(orientationChanged(Orientation)));
      QVERIFY(spyCard_2_spades.count() == 0);

      I'd try two things here:

      1. qRegisterMetaType<Card::Orientation>(); should be enough
      2. QSignalSpy spyCard_2_spades(card_2_Spades, &Card::orientationChanged); to establish the connection at compile time

      I hope one of these steps brings the solution. Regards

      Qt has to stay free or it will die.

      1 Reply Last reply
      1
      • Christian EhrlicherC Online
        Christian EhrlicherC Online
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #3

        The SIGNAL declaration is wrong. It must contain the fully qualified type:

        void orientationChanged(Card::Orientation orientation);

        because the old Signal/Slot syntax is using string comparison.
        If you use the new Signal/Slot syntax as @aha_1980 mentioned the problem should also go away.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        1 Reply Last reply
        1
        • G Offline
          G Offline
          gaylord
          wrote on last edited by
          #4

          Thanks aha_1980 and Chrisitan.

          Sorry about the code not being in github. I guess I didn't push it. Now I have.

          Christian, why do I need to fully qualify the type in the signal definition? It's defined in the class, so I would think that's enough. Is it because signals are used in a global fashion, and where they're defined isn't preserved when used by the system?

          I had trouble getting aha_1980's approach to work, but adding the fully qualified type to the signal parameter did make the error go away.

          I've updated the code to retrieve the parameters, but now I'm running into a problem with the QSignalSpy.count(). It's getting reset to 0. Maybe retrieving the arguments with "spyCard_2_spaces.takeAt() resets the signal count? I thought count() would return the total # of signals generated, and I could use that as an index to retrieve the arguments, but I'm obviously not understanding this.

          	unsigned int signalCount;
          	QList<QVariant> arguments;
          
          	// Verify no signals have been emitted for the 2 of spades
          	qRegisterMetaType<Card::Orientation>();
          	QSignalSpy spyCard_2_spades(card_2_Spades, &Card::orientationChanged);
          	signalCount = spyCard_2_spades.count();
          	QVERIFY(signalCount == 0);
          
          	// Set card face down; it should currently be face up. Signal should be emitted.
          	card_2_Spades->setOrientation(Card::FACE_DOWN);
          	signalCount = spyCard_2_spades.count();
          	// Arguments for this signal event are 0 based, so the 1st signal event's arguments are at QList[0].
          	arguments = spyCard_2_spades.takeAt(signalCount-1);
          	QVERIFY(card_2_Spades->getOrientation() == Card::FACE_DOWN);
          	QVERIFY(signalCount == 1);
          	QVERIFY(arguments.at(0) == Card::FACE_DOWN);
          
          	// Set card face down again. They're already face down, so no signal should be emitted.
          	card_2_Spades->setOrientation(Card::FACE_DOWN);
          	signalCount = spyCard_2_spades.count();
          	/ ERROR HERE. count returns 0. I didn't expect the counter to get reset.
          	// This causes the next call to seg fault.
          	arguments = spyCard_2_spades.takeAt(signalCount-1);;
          	QVERIFY(card_2_Spades->getOrientation() == Card::FACE_DOWN);
          	QVERIFY(spyCard_2_spades.count() == 1);
          	QVERIFY(arguments.at(0) == Card::FACE_DOWN);
          
          1 Reply Last reply
          0
          • Christian EhrlicherC Online
            Christian EhrlicherC Online
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @gaylord said in Cannot get QtTest to verify an signal parameter:

            Christian, why do I need to fully qualify the type in the signal definition?

            I already answered it:

            because the old Signal/Slot syntax is using string comparison.

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            1 Reply Last reply
            1
            • G Offline
              G Offline
              gaylord
              wrote on last edited by
              #6

              I guess I don't quite understand what "using string comparison" means. I did some searching and found this thread, and it has the comment:

              For the record, the reason why this solves the problem is that the metaobject system is deciding signal/slot compatibility based on (normalized) string comparisons. It doesn't "know" that StateMachine::state and state refer to the same type in this context. – rohanpm Sep 12 '12 at 1:26
              

              I'll accept this as "that's the way it works", with a loose belief that it's because signals and slots are parsed as strings in a global context, and where they're declared is not available to the parser. As I learn more about Qt, I expect I'll understand this better and refine my belief to something more accurate.

              aha_1980A 1 Reply Last reply
              0
              • G gaylord

                I guess I don't quite understand what "using string comparison" means. I did some searching and found this thread, and it has the comment:

                For the record, the reason why this solves the problem is that the metaobject system is deciding signal/slot compatibility based on (normalized) string comparisons. It doesn't "know" that StateMachine::state and state refer to the same type in this context. – rohanpm Sep 12 '12 at 1:26
                

                I'll accept this as "that's the way it works", with a loose belief that it's because signals and slots are parsed as strings in a global context, and where they're declared is not available to the parser. As I learn more about Qt, I expect I'll understand this better and refine my belief to something more accurate.

                aha_1980A Offline
                aha_1980A Offline
                aha_1980
                Lifetime Qt Champion
                wrote on last edited by
                #7

                Hi @gaylord,

                please have a look at https://wiki.qt.io/New_Signal_Slot_Syntax for the "new" syntax, which is checked at compile time.

                The "old-style" connect however was done at runtime, by simply comparing strings of SIGNAL and SLOT. I could therefore happen that you renamed one of them and the connect in turn no longer worked.

                Regards

                Qt has to stay free or it will die.

                Pablo J. RoginaP 1 Reply Last reply
                2
                • aha_1980A aha_1980

                  Hi @gaylord,

                  please have a look at https://wiki.qt.io/New_Signal_Slot_Syntax for the "new" syntax, which is checked at compile time.

                  The "old-style" connect however was done at runtime, by simply comparing strings of SIGNAL and SLOT. I could therefore happen that you renamed one of them and the connect in turn no longer worked.

                  Regards

                  Pablo J. RoginaP Offline
                  Pablo J. RoginaP Offline
                  Pablo J. Rogina
                  wrote on last edited by
                  #8

                  @gaylord as mentioned before, you may want to switch to the new syntax for signals and slots.
                  This answer is even proposing getting rid of QSignalSpy by just using connect with a lambda function.

                  Upvote the answer(s) that helped you solve the issue
                  Use "Topic Tools" button to mark your post as Solved
                  Add screenshots via postimage.org
                  Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

                  1 Reply Last reply
                  1

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved