6363#include < lib/support/Span.h>
6464#include < protocols/interaction_model/StatusCode.h>
6565
66+ #include < optional>
6667#include < vector>
6768
6869using namespace chip ;
@@ -86,6 +87,15 @@ constexpr EndpointId kEndpointIdThatIsMissing = kMockEndpointMin - 1;
8687
8788constexpr AttributeId kReadOnlyAttributeId = 0x5001 ;
8889
90+ constexpr DeviceTypeId kDeviceTypeId1 = 123 ;
91+ constexpr uint8_t kDeviceTypeId1Version = 10 ;
92+
93+ constexpr DeviceTypeId kDeviceTypeId2 = 1122 ;
94+ constexpr uint8_t kDeviceTypeId2Version = 11 ;
95+
96+ constexpr DeviceTypeId kDeviceTypeId3 = 3 ;
97+ constexpr uint8_t kDeviceTypeId3Version = 33 ;
98+
8999static_assert (kEndpointIdThatIsMissing != kInvalidEndpointId );
90100static_assert (kEndpointIdThatIsMissing != kMockEndpoint1 );
91101static_assert (kEndpointIdThatIsMissing != kMockEndpoint2 );
@@ -270,6 +280,10 @@ const MockNodeConfig gTestNodeConfig({
270280 MockClusterConfig (MockClusterId (2 ), {
271281 ClusterRevision::Id, FeatureMap::Id, MockAttributeId (1 ),
272282 }),
283+ }, {
284+ { kDeviceTypeId1 , kDeviceTypeId1Version },
285+ { kDeviceTypeId2 , kDeviceTypeId2Version },
286+ { kDeviceTypeId3 , kDeviceTypeId3Version },
273287 }),
274288 MockEndpointConfig (kMockEndpoint2 , {
275289 MockClusterConfig (MockClusterId (1 ), {
@@ -296,6 +310,8 @@ const MockNodeConfig gTestNodeConfig({
296310 {11 }, /* acceptedCommands */
297311 {4 , 6 } /* generatedCommands */
298312 ),
313+ }, {
314+ { kDeviceTypeId2 , kDeviceTypeId2Version },
299315 }),
300316 MockEndpointConfig (kMockEndpoint3 , {
301317 MockClusterConfig (MockClusterId (1 ), {
@@ -2580,3 +2596,48 @@ TEST(TestCodegenModelViaMocks, EmberWriteInvalidDataType)
25802596 ASSERT_EQ (model.WriteAttribute (test.GetRequest (), decoder), Status::Failure);
25812597 ASSERT_TRUE (model.ChangeListener ().DirtyList ().empty ());
25822598}
2599+
2600+ TEST (TestCodegenModelViaMocks, DeviceTypeIteration)
2601+ {
2602+ UseMockNodeConfig config (gTestNodeConfig );
2603+ CodegenDataModelProviderWithContext model;
2604+
2605+ // Mock endpoint 1 has 3 device types
2606+ std::optional<DeviceTypeEntry> entry = model.FirstDeviceType (kMockEndpoint1 );
2607+ ASSERT_EQ (entry,
2608+ std::make_optional (DeviceTypeEntry{ .deviceTypeId = kDeviceTypeId1 , .deviceTypeVersion = kDeviceTypeId1Version }));
2609+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access): Assert above that this is not none
2610+ entry = model.NextDeviceType (kMockEndpoint1 , *entry);
2611+ ASSERT_EQ (entry,
2612+ std::make_optional (DeviceTypeEntry{ .deviceTypeId = kDeviceTypeId2 , .deviceTypeVersion = kDeviceTypeId2Version }));
2613+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access): Assert above that this is not none
2614+ entry = model.NextDeviceType (kMockEndpoint1 , *entry);
2615+ ASSERT_EQ (entry,
2616+ std::make_optional (DeviceTypeEntry{ .deviceTypeId = kDeviceTypeId3 , .deviceTypeVersion = kDeviceTypeId3Version }));
2617+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access): Assert above that this is not none
2618+ entry = model.NextDeviceType (kMockEndpoint1 , *entry);
2619+ ASSERT_FALSE (entry.has_value ());
2620+
2621+ // Mock endpoint 2 has 1 device types
2622+ entry = model.FirstDeviceType (kMockEndpoint2 );
2623+ ASSERT_EQ (entry,
2624+ std::make_optional (DeviceTypeEntry{ .deviceTypeId = kDeviceTypeId2 , .deviceTypeVersion = kDeviceTypeId2Version }));
2625+ // NOLINTNEXTLINE(bugprone-unchecked-optional-access): Assert above that this is not none
2626+ entry = model.NextDeviceType (kMockEndpoint2 , *entry);
2627+ ASSERT_FALSE (entry.has_value ());
2628+
2629+ // out of order query works
2630+ entry = std::make_optional (DeviceTypeEntry{ .deviceTypeId = kDeviceTypeId2 , .deviceTypeVersion = kDeviceTypeId2Version });
2631+ entry = model.NextDeviceType (kMockEndpoint1 , *entry);
2632+ ASSERT_EQ (entry,
2633+ std::make_optional (DeviceTypeEntry{ .deviceTypeId = kDeviceTypeId3 , .deviceTypeVersion = kDeviceTypeId3Version }));
2634+
2635+ // invalid query fails
2636+ entry = std::make_optional (DeviceTypeEntry{ .deviceTypeId = kDeviceTypeId1 , .deviceTypeVersion = kDeviceTypeId1Version });
2637+ entry = model.NextDeviceType (kMockEndpoint2 , *entry);
2638+ ASSERT_FALSE (entry.has_value ());
2639+
2640+ // empty endpoint works
2641+ entry = model.FirstDeviceType (kMockEndpoint3 );
2642+ ASSERT_FALSE (entry.has_value ());
2643+ }
0 commit comments