[libcamera-devel,3/7] test: yaml_parser: Extend tests to cover the iterator API
diff mbox series

Message ID 20220616142403.20723-4-laurent.pinchart@ideasonboard.com
State Accepted
Headers show
Series
  • libcamera: yaml_parser: Add iterator API
Related show

Commit Message

Laurent Pinchart June 16, 2022, 2:23 p.m. UTC
Test iteration over lists and dictionaries to test the YamlObject
iterator API.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 test/yaml-parser.cpp | 99 +++++++++++++++++++++++++++++++++++---------
 1 file changed, 80 insertions(+), 19 deletions(-)

Comments

Jacopo Mondi June 17, 2022, 3:15 p.m. UTC | #1
Hi Laurent

On Thu, Jun 16, 2022 at 05:23:59PM +0300, Laurent Pinchart via libcamera-devel wrote:
> Test iteration over lists and dictionaries to test the YamlObject
> iterator API.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  test/yaml-parser.cpp | 99 +++++++++++++++++++++++++++++++++++---------
>  1 file changed, 80 insertions(+), 19 deletions(-)
>
> diff --git a/test/yaml-parser.cpp b/test/yaml-parser.cpp
> index 5ff4c3236dbf..ab6e9a01c0fe 100644
> --- a/test/yaml-parser.cpp
> +++ b/test/yaml-parser.cpp
> @@ -5,11 +5,14 @@
>   * yaml-parser.cpp - YAML parser operations tests
>   */
>
> +#include <array>
>  #include <iostream>
> +#include <map>
>  #include <string>
>  #include <unistd.h>
>
>  #include <libcamera/base/file.h>
> +#include <libcamera/base/utils.h>
>
>  #include "libcamera/internal/yaml_parser.h"
>
> @@ -373,15 +376,39 @@ protected:
>  			return TestFail;
>  		}
>
> -		if (listObj.size() > 2) {
> +		static constexpr std::array<const char *, 2> listValues{
> +			"James",
> +			"Mary",
> +		};
> +
> +		if (listObj.size() != listValues.size()) {
>  			cerr << "List object parse with wrong size" << std::endl;
>  			return TestFail;
>  		}
>
> -		if (listObj[0].get<string>("") != "James" ||
> -		    listObj[1].get<string>("") != "Mary") {
> -			cerr << "List object parse as wrong value" << std::endl;
> -			return TestFail;
> +		unsigned int i = 0;
> +		for (auto &elem : listObj.asList()) {
> +			if (i >= listValues.size()) {
> +				std::cerr << "Too many elements in list during iteration"
> +					  << std::endl;
> +				return TestFail;
> +			}
> +
> +			std::string value = listValues[i];
> +
> +			if (&elem != &listObj[i]) {
> +				std::cerr << "List element " << i << " has wrong address"
> +					  << std::endl;
> +				return TestFail;
> +			}
> +
> +			if (elem.get<std::string>("") != value) {
> +				std::cerr << "List element " << i << " has wrong value"
> +					  << std::endl;
> +				return TestFail;
> +			}
> +
> +			i++;
>  		}
>
>  		/* Test dictionary object */
> @@ -422,19 +449,60 @@ protected:
>  			return TestFail;
>  		}
>
> -		if (dictObj.size() != 3) {
> -			cerr << "Dictionary object parse with wrong size" << std::endl;
> +		std::map<std::string, int> dictValues{ {
> +			{ "a", 1 },
> +			{ "b", 2 },
> +			{ "c", 3 },
> +		} };
> +
> +		size_t dictSize = dictValues.size();
> +
> +		if (dictObj.size() != dictSize) {
> +			cerr << "Dictionary object has wrong size" << std::endl;
>  			return TestFail;
>  		}
>
> +		i = 0;
> +		for (const auto &[key, elem] : dictObj.asDict()) {
> +			if (i >= dictSize) {
> +				std::cerr << "Too many elements in dictionary during iteration"
> +					  << std::endl;
> +				return TestFail;
> +			}
> +
> +			const auto item = dictValues.find(key);
> +			if (item == dictValues.end()) {
> +				std::cerr << "Dictionary key " << i << " has wrong value"
> +					  << std::endl;
> +				return TestFail;
> +			}
> +
> +			if (&elem != &dictObj[key]) {
> +				std::cerr << "Dictionary element " << i << " has wrong address"
> +					  << std::endl;
> +				return TestFail;
> +			}
> +
> +			if (elem.get<int32_t>(0) != item->second) {
> +				std::cerr << "Dictionary element " << i << " has wrong value"
> +					  << std::endl;
> +				return TestFail;
> +			}
> +
> +			/*
> +			 * Erase the item to make sure that each iteration
> +			 * produces a different value.
> +			 */
> +			dictValues.erase(item);

Can the iteration return the same element twice ?

With this clarified
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>

Thanks
  j

> +			i++;
> +		}
> +
> +		/* Make sure utils::map_keys() works on the adapter. */
> +		(void)utils::map_keys(dictObj.asDict());
> +
>  		auto memeberNames = dictObj.memberNames();
>  		sort(memeberNames.begin(), memeberNames.end());
>
> -		if (memeberNames.size() != 3) {
> -			cerr << "Dictionary object fail to extra member names" << std::endl;
> -			return TestFail;
> -		}
> -
>  		if (memeberNames[0] != "a" ||
>  		    memeberNames[1] != "b" ||
>  		    memeberNames[2] != "c") {
> @@ -442,13 +510,6 @@ protected:
>  			return TestFail;
>  		}
>
> -		if (dictObj["a"].get<int32_t>(0) != 1 ||
> -		    dictObj["b"].get<int32_t>(0) != 2 ||
> -		    dictObj["c"].get<int32_t>(0) != 3) {
> -			cerr << "Dictionary object fail to parse member value" << std::endl;
> -			return TestFail;
> -		}
> -
>  		/* Test leveled objects */
>  		auto &level1Obj = (*root)["level1"];
>
> --
> Regards,
>
> Laurent Pinchart
>
Laurent Pinchart June 17, 2022, 3:55 p.m. UTC | #2
Hi Jacopo,

On Fri, Jun 17, 2022 at 05:15:25PM +0200, Jacopo Mondi wrote:
> On Thu, Jun 16, 2022 at 05:23:59PM +0300, Laurent Pinchart via libcamera-devel wrote:
> > Test iteration over lists and dictionaries to test the YamlObject
> > iterator API.
> >
> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > ---
> >  test/yaml-parser.cpp | 99 +++++++++++++++++++++++++++++++++++---------
> >  1 file changed, 80 insertions(+), 19 deletions(-)
> >
> > diff --git a/test/yaml-parser.cpp b/test/yaml-parser.cpp
> > index 5ff4c3236dbf..ab6e9a01c0fe 100644
> > --- a/test/yaml-parser.cpp
> > +++ b/test/yaml-parser.cpp
> > @@ -5,11 +5,14 @@
> >   * yaml-parser.cpp - YAML parser operations tests
> >   */
> >
> > +#include <array>
> >  #include <iostream>
> > +#include <map>
> >  #include <string>
> >  #include <unistd.h>
> >
> >  #include <libcamera/base/file.h>
> > +#include <libcamera/base/utils.h>
> >
> >  #include "libcamera/internal/yaml_parser.h"
> >
> > @@ -373,15 +376,39 @@ protected:
> >  			return TestFail;
> >  		}
> >
> > -		if (listObj.size() > 2) {
> > +		static constexpr std::array<const char *, 2> listValues{
> > +			"James",
> > +			"Mary",
> > +		};
> > +
> > +		if (listObj.size() != listValues.size()) {
> >  			cerr << "List object parse with wrong size" << std::endl;
> >  			return TestFail;
> >  		}
> >
> > -		if (listObj[0].get<string>("") != "James" ||
> > -		    listObj[1].get<string>("") != "Mary") {
> > -			cerr << "List object parse as wrong value" << std::endl;
> > -			return TestFail;
> > +		unsigned int i = 0;
> > +		for (auto &elem : listObj.asList()) {
> > +			if (i >= listValues.size()) {
> > +				std::cerr << "Too many elements in list during iteration"
> > +					  << std::endl;
> > +				return TestFail;
> > +			}
> > +
> > +			std::string value = listValues[i];
> > +
> > +			if (&elem != &listObj[i]) {
> > +				std::cerr << "List element " << i << " has wrong address"
> > +					  << std::endl;
> > +				return TestFail;
> > +			}
> > +
> > +			if (elem.get<std::string>("") != value) {
> > +				std::cerr << "List element " << i << " has wrong value"
> > +					  << std::endl;
> > +				return TestFail;
> > +			}
> > +
> > +			i++;
> >  		}
> >
> >  		/* Test dictionary object */
> > @@ -422,19 +449,60 @@ protected:
> >  			return TestFail;
> >  		}
> >
> > -		if (dictObj.size() != 3) {
> > -			cerr << "Dictionary object parse with wrong size" << std::endl;
> > +		std::map<std::string, int> dictValues{ {
> > +			{ "a", 1 },
> > +			{ "b", 2 },
> > +			{ "c", 3 },
> > +		} };
> > +
> > +		size_t dictSize = dictValues.size();
> > +
> > +		if (dictObj.size() != dictSize) {
> > +			cerr << "Dictionary object has wrong size" << std::endl;
> >  			return TestFail;
> >  		}
> >
> > +		i = 0;
> > +		for (const auto &[key, elem] : dictObj.asDict()) {
> > +			if (i >= dictSize) {
> > +				std::cerr << "Too many elements in dictionary during iteration"
> > +					  << std::endl;
> > +				return TestFail;
> > +			}
> > +
> > +			const auto item = dictValues.find(key);
> > +			if (item == dictValues.end()) {
> > +				std::cerr << "Dictionary key " << i << " has wrong value"
> > +					  << std::endl;
> > +				return TestFail;
> > +			}
> > +
> > +			if (&elem != &dictObj[key]) {
> > +				std::cerr << "Dictionary element " << i << " has wrong address"
> > +					  << std::endl;
> > +				return TestFail;
> > +			}
> > +
> > +			if (elem.get<int32_t>(0) != item->second) {
> > +				std::cerr << "Dictionary element " << i << " has wrong value"
> > +					  << std::endl;
> > +				return TestFail;
> > +			}
> > +
> > +			/*
> > +			 * Erase the item to make sure that each iteration
> > +			 * produces a different value.
> > +			 */
> > +			dictValues.erase(item);
> 
> Can the iteration return the same element twice ?

It's not supposed to. That's why this is trying to catch, without the
erase, if the iterator returned the same element three times, the test
would pass.

> With this clarified
> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
> 
> > +			i++;
> > +		}
> > +
> > +		/* Make sure utils::map_keys() works on the adapter. */
> > +		(void)utils::map_keys(dictObj.asDict());
> > +
> >  		auto memeberNames = dictObj.memberNames();
> >  		sort(memeberNames.begin(), memeberNames.end());
> >
> > -		if (memeberNames.size() != 3) {
> > -			cerr << "Dictionary object fail to extra member names" << std::endl;
> > -			return TestFail;
> > -		}
> > -
> >  		if (memeberNames[0] != "a" ||
> >  		    memeberNames[1] != "b" ||
> >  		    memeberNames[2] != "c") {
> > @@ -442,13 +510,6 @@ protected:
> >  			return TestFail;
> >  		}
> >
> > -		if (dictObj["a"].get<int32_t>(0) != 1 ||
> > -		    dictObj["b"].get<int32_t>(0) != 2 ||
> > -		    dictObj["c"].get<int32_t>(0) != 3) {
> > -			cerr << "Dictionary object fail to parse member value" << std::endl;
> > -			return TestFail;
> > -		}
> > -
> >  		/* Test leveled objects */
> >  		auto &level1Obj = (*root)["level1"];
> >
Hanlin Chen June 20, 2022, 12:06 p.m. UTC | #3
Hi Laurent,

Reviewed-by: Han-Lin Chen <hanlinchen@chromium.org>
Thanks.

On Fri, Jun 17, 2022 at 11:55 PM Laurent Pinchart via libcamera-devel
<libcamera-devel@lists.libcamera.org> wrote:
>
> Hi Jacopo,
>
> On Fri, Jun 17, 2022 at 05:15:25PM +0200, Jacopo Mondi wrote:
> > On Thu, Jun 16, 2022 at 05:23:59PM +0300, Laurent Pinchart via libcamera-devel wrote:
> > > Test iteration over lists and dictionaries to test the YamlObject
> > > iterator API.
> > >
> > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > > ---
> > >  test/yaml-parser.cpp | 99 +++++++++++++++++++++++++++++++++++---------
> > >  1 file changed, 80 insertions(+), 19 deletions(-)
> > >
> > > diff --git a/test/yaml-parser.cpp b/test/yaml-parser.cpp
> > > index 5ff4c3236dbf..ab6e9a01c0fe 100644
> > > --- a/test/yaml-parser.cpp
> > > +++ b/test/yaml-parser.cpp
> > > @@ -5,11 +5,14 @@
> > >   * yaml-parser.cpp - YAML parser operations tests
> > >   */
> > >
> > > +#include <array>
> > >  #include <iostream>
> > > +#include <map>
> > >  #include <string>
> > >  #include <unistd.h>
> > >
> > >  #include <libcamera/base/file.h>
> > > +#include <libcamera/base/utils.h>
> > >
> > >  #include "libcamera/internal/yaml_parser.h"
> > >
> > > @@ -373,15 +376,39 @@ protected:
> > >                     return TestFail;
> > >             }
> > >
> > > -           if (listObj.size() > 2) {
> > > +           static constexpr std::array<const char *, 2> listValues{
> > > +                   "James",
> > > +                   "Mary",
> > > +           };
> > > +
> > > +           if (listObj.size() != listValues.size()) {
> > >                     cerr << "List object parse with wrong size" << std::endl;
> > >                     return TestFail;
> > >             }
> > >
> > > -           if (listObj[0].get<string>("") != "James" ||
> > > -               listObj[1].get<string>("") != "Mary") {
> > > -                   cerr << "List object parse as wrong value" << std::endl;
> > > -                   return TestFail;
> > > +           unsigned int i = 0;
> > > +           for (auto &elem : listObj.asList()) {
> > > +                   if (i >= listValues.size()) {
> > > +                           std::cerr << "Too many elements in list during iteration"
> > > +                                     << std::endl;
> > > +                           return TestFail;
> > > +                   }
> > > +
> > > +                   std::string value = listValues[i];
> > > +
> > > +                   if (&elem != &listObj[i]) {
> > > +                           std::cerr << "List element " << i << " has wrong address"
> > > +                                     << std::endl;
> > > +                           return TestFail;
> > > +                   }
> > > +
> > > +                   if (elem.get<std::string>("") != value) {
> > > +                           std::cerr << "List element " << i << " has wrong value"
> > > +                                     << std::endl;
> > > +                           return TestFail;
> > > +                   }
> > > +
> > > +                   i++;
> > >             }
> > >
> > >             /* Test dictionary object */
> > > @@ -422,19 +449,60 @@ protected:
> > >                     return TestFail;
> > >             }
> > >
> > > -           if (dictObj.size() != 3) {
> > > -                   cerr << "Dictionary object parse with wrong size" << std::endl;
> > > +           std::map<std::string, int> dictValues{ {
> > > +                   { "a", 1 },
> > > +                   { "b", 2 },
> > > +                   { "c", 3 },
> > > +           } };
> > > +
> > > +           size_t dictSize = dictValues.size();
> > > +
> > > +           if (dictObj.size() != dictSize) {
> > > +                   cerr << "Dictionary object has wrong size" << std::endl;
> > >                     return TestFail;
> > >             }
> > >
> > > +           i = 0;
> > > +           for (const auto &[key, elem] : dictObj.asDict()) {
> > > +                   if (i >= dictSize) {
> > > +                           std::cerr << "Too many elements in dictionary during iteration"
> > > +                                     << std::endl;
> > > +                           return TestFail;
> > > +                   }
> > > +
> > > +                   const auto item = dictValues.find(key);
> > > +                   if (item == dictValues.end()) {
> > > +                           std::cerr << "Dictionary key " << i << " has wrong value"
> > > +                                     << std::endl;
> > > +                           return TestFail;
> > > +                   }
> > > +
> > > +                   if (&elem != &dictObj[key]) {
> > > +                           std::cerr << "Dictionary element " << i << " has wrong address"
> > > +                                     << std::endl;
> > > +                           return TestFail;
> > > +                   }
> > > +
> > > +                   if (elem.get<int32_t>(0) != item->second) {
> > > +                           std::cerr << "Dictionary element " << i << " has wrong value"
> > > +                                     << std::endl;
> > > +                           return TestFail;
> > > +                   }
> > > +
> > > +                   /*
> > > +                    * Erase the item to make sure that each iteration
> > > +                    * produces a different value.
> > > +                    */
> > > +                   dictValues.erase(item);
> >
> > Can the iteration return the same element twice ?
>
> It's not supposed to. That's why this is trying to catch, without the
> erase, if the iterator returned the same element three times, the test
> would pass.
>
> > With this clarified
> > Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
> >
> > > +                   i++;
> > > +           }
> > > +
> > > +           /* Make sure utils::map_keys() works on the adapter. */
> > > +           (void)utils::map_keys(dictObj.asDict());
> > > +
> > >             auto memeberNames = dictObj.memberNames();
> > >             sort(memeberNames.begin(), memeberNames.end());
> > >
> > > -           if (memeberNames.size() != 3) {
> > > -                   cerr << "Dictionary object fail to extra member names" << std::endl;
> > > -                   return TestFail;
> > > -           }
> > > -
> > >             if (memeberNames[0] != "a" ||
> > >                 memeberNames[1] != "b" ||
> > >                 memeberNames[2] != "c") {
> > > @@ -442,13 +510,6 @@ protected:
> > >                     return TestFail;
> > >             }
> > >
> > > -           if (dictObj["a"].get<int32_t>(0) != 1 ||
> > > -               dictObj["b"].get<int32_t>(0) != 2 ||
> > > -               dictObj["c"].get<int32_t>(0) != 3) {
> > > -                   cerr << "Dictionary object fail to parse member value" << std::endl;
> > > -                   return TestFail;
> > > -           }
> > > -
> > >             /* Test leveled objects */
> > >             auto &level1Obj = (*root)["level1"];
> > >
>
> --
> Regards,
>
> Laurent Pinchart

Patch
diff mbox series

diff --git a/test/yaml-parser.cpp b/test/yaml-parser.cpp
index 5ff4c3236dbf..ab6e9a01c0fe 100644
--- a/test/yaml-parser.cpp
+++ b/test/yaml-parser.cpp
@@ -5,11 +5,14 @@ 
  * yaml-parser.cpp - YAML parser operations tests
  */
 
+#include <array>
 #include <iostream>
+#include <map>
 #include <string>
 #include <unistd.h>
 
 #include <libcamera/base/file.h>
+#include <libcamera/base/utils.h>
 
 #include "libcamera/internal/yaml_parser.h"
 
@@ -373,15 +376,39 @@  protected:
 			return TestFail;
 		}
 
-		if (listObj.size() > 2) {
+		static constexpr std::array<const char *, 2> listValues{
+			"James",
+			"Mary",
+		};
+
+		if (listObj.size() != listValues.size()) {
 			cerr << "List object parse with wrong size" << std::endl;
 			return TestFail;
 		}
 
-		if (listObj[0].get<string>("") != "James" ||
-		    listObj[1].get<string>("") != "Mary") {
-			cerr << "List object parse as wrong value" << std::endl;
-			return TestFail;
+		unsigned int i = 0;
+		for (auto &elem : listObj.asList()) {
+			if (i >= listValues.size()) {
+				std::cerr << "Too many elements in list during iteration"
+					  << std::endl;
+				return TestFail;
+			}
+
+			std::string value = listValues[i];
+
+			if (&elem != &listObj[i]) {
+				std::cerr << "List element " << i << " has wrong address"
+					  << std::endl;
+				return TestFail;
+			}
+
+			if (elem.get<std::string>("") != value) {
+				std::cerr << "List element " << i << " has wrong value"
+					  << std::endl;
+				return TestFail;
+			}
+
+			i++;
 		}
 
 		/* Test dictionary object */
@@ -422,19 +449,60 @@  protected:
 			return TestFail;
 		}
 
-		if (dictObj.size() != 3) {
-			cerr << "Dictionary object parse with wrong size" << std::endl;
+		std::map<std::string, int> dictValues{ {
+			{ "a", 1 },
+			{ "b", 2 },
+			{ "c", 3 },
+		} };
+
+		size_t dictSize = dictValues.size();
+
+		if (dictObj.size() != dictSize) {
+			cerr << "Dictionary object has wrong size" << std::endl;
 			return TestFail;
 		}
 
+		i = 0;
+		for (const auto &[key, elem] : dictObj.asDict()) {
+			if (i >= dictSize) {
+				std::cerr << "Too many elements in dictionary during iteration"
+					  << std::endl;
+				return TestFail;
+			}
+
+			const auto item = dictValues.find(key);
+			if (item == dictValues.end()) {
+				std::cerr << "Dictionary key " << i << " has wrong value"
+					  << std::endl;
+				return TestFail;
+			}
+
+			if (&elem != &dictObj[key]) {
+				std::cerr << "Dictionary element " << i << " has wrong address"
+					  << std::endl;
+				return TestFail;
+			}
+
+			if (elem.get<int32_t>(0) != item->second) {
+				std::cerr << "Dictionary element " << i << " has wrong value"
+					  << std::endl;
+				return TestFail;
+			}
+
+			/*
+			 * Erase the item to make sure that each iteration
+			 * produces a different value.
+			 */
+			dictValues.erase(item);
+			i++;
+		}
+
+		/* Make sure utils::map_keys() works on the adapter. */
+		(void)utils::map_keys(dictObj.asDict());
+
 		auto memeberNames = dictObj.memberNames();
 		sort(memeberNames.begin(), memeberNames.end());
 
-		if (memeberNames.size() != 3) {
-			cerr << "Dictionary object fail to extra member names" << std::endl;
-			return TestFail;
-		}
-
 		if (memeberNames[0] != "a" ||
 		    memeberNames[1] != "b" ||
 		    memeberNames[2] != "c") {
@@ -442,13 +510,6 @@  protected:
 			return TestFail;
 		}
 
-		if (dictObj["a"].get<int32_t>(0) != 1 ||
-		    dictObj["b"].get<int32_t>(0) != 2 ||
-		    dictObj["c"].get<int32_t>(0) != 3) {
-			cerr << "Dictionary object fail to parse member value" << std::endl;
-			return TestFail;
-		}
-
 		/* Test leveled objects */
 		auto &level1Obj = (*root)["level1"];