@@ -1313,5 +1313,167 @@ def test_to_string_complex_nested_selectors_with_attribute_selector_space_invali
13131313 )
13141314
13151315
1316+ class TestQSSParserQProperty (unittest .TestCase ):
1317+ def setUp (self ) -> None :
1318+ """
1319+ Set up the test environment for qproperty parsing tests.
1320+ """
1321+ self .parser : QSSParser = QSSParser ()
1322+ self .errors : List [str ] = []
1323+ self .parser .on (ParserEvent .ERROR_FOUND , lambda error : self .errors .append (error ))
1324+ self .qss : str = """
1325+ QPushButton {
1326+ qproperty-icon: url(:/icons/test.png);
1327+ qproperty-text: "Click Me";
1328+ color: blue;
1329+ }
1330+ #customButton {
1331+ qproperty-enabled: false;
1332+ background: gray;
1333+ }
1334+ .iconButton[qproperty-icon="url(:/icons/test.png)"] {
1335+ border: 1px solid black;
1336+ }
1337+ """
1338+
1339+ def test_parse_qproperty_attributes (self ) -> None :
1340+ """
1341+ Test parsing QSS with valid qproperty attributes.
1342+ """
1343+ self .parser .parse (self .qss )
1344+ self .assertEqual (
1345+ len (self .parser ._state .rules ), 3 , "Should parse all rules correctly"
1346+ )
1347+ self .assertEqual (
1348+ self .errors , [], "Valid qproperty QSS should produce no errors"
1349+ )
1350+
1351+ # Test QPushButton rule
1352+ push_button_rule : QSSRule = self .parser ._state .rules [0 ]
1353+ self .assertEqual (push_button_rule .selector , "QPushButton" )
1354+ self .assertEqual (len (push_button_rule .properties ), 3 )
1355+ self .assertEqual (push_button_rule .properties [0 ].name , "qproperty-icon" )
1356+ self .assertEqual (push_button_rule .properties [0 ].value , "url(:/icons/test.png)" )
1357+ self .assertEqual (push_button_rule .properties [1 ].name , "qproperty-text" )
1358+ self .assertEqual (push_button_rule .properties [1 ].value , '"Click Me"' )
1359+ self .assertEqual (push_button_rule .properties [2 ].name , "color" )
1360+ self .assertEqual (push_button_rule .properties [2 ].value , "blue" )
1361+
1362+ # Test #customButton rule
1363+ custom_button_rule : QSSRule = self .parser ._state .rules [1 ]
1364+ self .assertEqual (custom_button_rule .selector , "#customButton" )
1365+ self .assertEqual (len (custom_button_rule .properties ), 2 )
1366+ self .assertEqual (custom_button_rule .properties [0 ].name , "qproperty-enabled" )
1367+ self .assertEqual (custom_button_rule .properties [0 ].value , "false" )
1368+ self .assertEqual (custom_button_rule .properties [1 ].name , "background" )
1369+ self .assertEqual (custom_button_rule .properties [1 ].value , "gray" )
1370+
1371+ # Test .iconButton rule with qproperty in selector
1372+ icon_button_rule : QSSRule = self .parser ._state .rules [2 ]
1373+ self .assertEqual (
1374+ icon_button_rule .selector ,
1375+ '.iconButton[qproperty-icon="url(:/icons/test.png)"]' ,
1376+ )
1377+ self .assertEqual (len (icon_button_rule .properties ), 1 )
1378+ self .assertEqual (icon_button_rule .properties [0 ].name , "border" )
1379+ self .assertEqual (icon_button_rule .properties [0 ].value , "1px solid black" )
1380+ self .assertEqual (
1381+ icon_button_rule .attributes , ['[qproperty-icon="url(:/icons/test.png)"]' ]
1382+ )
1383+
1384+ def test_get_styles_for_qproperty (self ) -> None :
1385+ """
1386+ Test style retrieval for a widget with qproperty attributes.
1387+ """
1388+ self .parser .parse (self .qss )
1389+ widget : Mock = Mock ()
1390+ widget .objectName .return_value = "customButton"
1391+ widget .metaObject .return_value .className .return_value = "QPushButton"
1392+
1393+ stylesheet : str = self .parser .get_styles_for (widget )
1394+ expected : str = """#customButton {
1395+ qproperty-enabled: false;
1396+ background: gray;
1397+ }"""
1398+ self .assertEqual (stylesheet .strip (), expected .strip ())
1399+ self .assertEqual (
1400+ self .errors , [], "Valid qproperty style retrieval should produce no errors"
1401+ )
1402+
1403+ def test_get_styles_for_qproperty_with_class_and_object_name (self ) -> None :
1404+ """
1405+ Test style retrieval including class styles for a widget with qproperty attributes.
1406+ """
1407+ self .parser .parse (self .qss )
1408+ widget : Mock = Mock ()
1409+ widget .objectName .return_value = "customButton"
1410+ widget .metaObject .return_value .className .return_value = "QPushButton"
1411+
1412+ stylesheet : str = self .parser .get_styles_for (
1413+ widget , include_class_if_object_name = True
1414+ )
1415+ expected : str = """#customButton {
1416+ qproperty-enabled: false;
1417+ background: gray;
1418+ }
1419+ QPushButton {
1420+ qproperty-icon: url(:/icons/test.png);
1421+ qproperty-text: "Click Me";
1422+ color: blue;
1423+ }"""
1424+ self .assertEqual (stylesheet .strip (), expected .strip ())
1425+ self .assertEqual (
1426+ self .errors , [], "Valid qproperty style retrieval should produce no errors"
1427+ )
1428+
1429+ def test_parse_invalid_qproperty_name (self ) -> None :
1430+ """
1431+ Test parsing QSS with an invalid qproperty name.
1432+ """
1433+ qss : str = """
1434+ QPushButton {
1435+ qproperty-123invalid: true;
1436+ color: blue;
1437+ }
1438+ """
1439+ self .parser .parse (qss )
1440+ self .assertEqual (
1441+ len (self .parser ._state .rules ), 1 , "Should parse rule with valid properties"
1442+ )
1443+ rule : QSSRule = self .parser ._state .rules [0 ]
1444+ self .assertEqual (len (rule .properties ), 1 , "Should skip invalid qproperty" )
1445+ self .assertEqual (rule .properties [0 ].name , "color" )
1446+ self .assertEqual (rule .properties [0 ].value , "blue" )
1447+ self .assertEqual (len (self .errors ), 1 , "Should report invalid qproperty name" )
1448+ self .assertTrue (
1449+ "Invalid property name: 'qproperty-123invalid'" in self .errors [0 ]
1450+ )
1451+
1452+ def test_to_string_with_qproperty (self ) -> None :
1453+ """
1454+ Test to_string() output for QSS rules with qproperty attributes.
1455+ """
1456+ self .parser .parse (self .qss )
1457+ expected : str = """QPushButton {
1458+ qproperty-icon: url(:/icons/test.png);
1459+ qproperty-text: "Click Me";
1460+ color: blue;
1461+ }
1462+
1463+ #customButton {
1464+ qproperty-enabled: false;
1465+ background: gray;
1466+ }
1467+
1468+ .iconButton[qproperty-icon="url(:/icons/test.png)"] {
1469+ border: 1px solid black;
1470+ }
1471+ """
1472+ self .assertEqual (self .parser .to_string (), expected )
1473+ self .assertEqual (
1474+ self .errors , [], "Valid qproperty QSS should produce no errors"
1475+ )
1476+
1477+
13161478if __name__ == "__main__" :
13171479 unittest .main ()
0 commit comments