Makefile.in                               |    1 
 net_ure/DotnetTest_net_basetypes_tests.mk |   17 +++
 net_ure/Module_net_ure.mk                 |    4 
 net_ure/qa/basetypes/AnyTests.cs          |  100 ++++++++++++++++++++
 net_ure/source/basetypes/Any.cs           |   13 ++
 solenv/gbuild/DotnetTest.mk               |  146 ++++++++++++++++++++++++++++++
 solenv/gbuild/TargetLocations.mk          |    3 
 solenv/gbuild/gbuild.help.txt             |    1 
 solenv/gbuild/gbuild.mk                   |    1 
 9 files changed, 284 insertions(+), 2 deletions(-)

New commits:
commit e8a8d32fb3cc8b1f8fc17788ab00dffff1f4a950
Author:     RMZeroFour <ritobrot...@gmail.com>
AuthorDate: Sat Jul 27 20:06:56 2024 +0530
Commit:     Hossein <hoss...@libreoffice.org>
CommitDate: Sat Aug 3 12:07:11 2024 +0200

    .NET Bindings: Add DotnetTest class to gbuild
    
    This commit adds the DotnetTest gbuild class to build a unit test
    suite using the .NET SDK and the NUnit testing framework.
    
    Also adds a DotnetTest target for the net_ure module, with unit tests
    for the Any type, as well as some minor changes to the Any type that
    came about when writing the test cases.
    
    Change-Id: Idbc08ac8f0736dd7355092dd1e69a5f1b4137c4c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168956
    Tested-by: Jenkins
    Reviewed-by: Hossein <hoss...@libreoffice.org>

diff --git a/Makefile.in b/Makefile.in
index b2d59e3075ab..32ee72b2e099 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -138,6 +138,7 @@ gbuild_TARGETS := AllLangHelp \
        CustomTarget \
        Dictionary \
        DotnetLibrary \
+       DotnetTest \
        Executable \
        Extension \
        ExtensionPackage \
diff --git a/net_ure/DotnetTest_net_basetypes_tests.mk 
b/net_ure/DotnetTest_net_basetypes_tests.mk
new file mode 100644
index 000000000000..3a2406a859dc
--- /dev/null
+++ b/net_ure/DotnetTest_net_basetypes_tests.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+$(eval $(call 
gb_DotnetTest_DotnetTest,net_basetypes_tests,$(gb_DotnetTest_CS)))
+
+$(eval $(call gb_DotnetTest_add_sources,net_basetypes_tests,\
+       net_ure/qa/basetypes/AnyTests \
+))
+
+$(eval $(call gb_DotnetTest_link_library,net_basetypes_tests,net_basetypes))
+
+# vim: set noet sw=4 ts=4:
diff --git a/net_ure/Module_net_ure.mk b/net_ure/Module_net_ure.mk
index 98e3a80505e3..e5bf692114f4 100644
--- a/net_ure/Module_net_ure.mk
+++ b/net_ure/Module_net_ure.mk
@@ -19,6 +19,10 @@ $(eval $(call gb_Module_add_targets,net_ure,\
        Package_net_uretypes \
        Package_net_oootypes \
 ))
+
+$(eval $(call gb_Module_add_subsequentcheck_targets,net_ure,\
+       DotnetTest_net_basetypes_tests \
+))
 endif
 
 # vim: set noet sw=4 ts=4:
diff --git a/net_ure/qa/basetypes/AnyTests.cs b/net_ure/qa/basetypes/AnyTests.cs
new file mode 100644
index 000000000000..cee504a1744f
--- /dev/null
+++ b/net_ure/qa/basetypes/AnyTests.cs
@@ -0,0 +1,100 @@
+using NUnit.Framework;
+
+using com.sun.star.uno;
+
+[TestFixture]
+public class AnyTests
+{
+    [Test]
+    [Description("Tests if Any.VOID has a null value and type as void")]
+    public void VOID_HasNullValueAndVoidType()
+    {
+        Assert.That(Any.VOID, Is.Not.Null);
+        Assert.That(Any.VOID.Value, Is.Null);
+        Assert.That(Any.VOID.Type, Is.EqualTo(typeof(void)));
+    }
+
+    [Test]
+    [Description("Tests if the Any(type, value) constructor throws on invalid 
args")]
+    public void ctor_RejectsInvalidParams()
+    {
+        Assert.That(() => new Any(null, 10), Throws.ArgumentNullException);
+        Assert.That(() => new Any(typeof(Any), Any.VOID), 
Throws.ArgumentException);
+        Assert.That(() => new Any(typeof(int), null), 
Throws.ArgumentException);
+    }
+
+    [Test]
+    [Description("Tests if Any.with<T>(value) throws on invalid args")]
+    public void with_RejectsInvalidParams()
+    {
+        Assert.That(() => new Any(typeof(Any), Any.VOID), 
Throws.ArgumentException);
+    }
+
+    [Test]
+    [Description("Tests if Any.equals(other) and Any.operator== returns true 
for identical values")]
+    public void equals_ReturnsTrueForSame()
+    {
+        Assert.That(Any.VOID == new Any(typeof(void), null), Is.True);
+        Assert.That(Any.with(10).equals(new Any(typeof(int), 10)), Is.True);
+        Assert.That(new Any(typeof(bool), false).Equals(Any.with(false)), 
Is.True);
+    }
+
+    [Test]
+    [Description("Tests if Any.equals(other) and Any.operator== returns false 
for different values")]
+    public void equals_ReturnsTrueForDifferent()
+    {
+        Assert.That(Any.VOID == Any.with(10), Is.False);
+        Assert.That(Any.VOID != Any.with(10), Is.True);
+        Assert.That(Any.with(10).equals(Any.with(20)), Is.False);
+        Assert.That(Any.with(true).Equals(Any.with(1)), Is.False);
+    }
+
+    [Test]
+    [Description("Tests if Any.hasValue() returns false for Any.VOID and true 
for all else")]
+    public void hasValue_ReturnsFalseOnlyForVOID()
+    {
+        Assert.That(Any.VOID.hasValue, Is.False);
+        Assert.That(Any.with(10).hasValue, Is.True);
+        Assert.That(new Any(typeof(string), "hello").hasValue, Is.True);
+    }
+
+    [Test]
+    [Description("Tests if Any.setValue(type, value) method updates type and 
value correctly")]
+    public void setValue_UpdatesTypeAndValue()
+    {
+        Any any = new Any(typeof(int), 10);
+        Assert.That(any.Type, Is.EqualTo(typeof(int)));
+        Assert.That(any.Value, Is.EqualTo(10));
+        any.setValue(typeof(string), "hello");
+        Assert.That(any.Type, Is.EqualTo(typeof(string)));
+        Assert.That(any.Value, Is.EqualTo("hello"));
+        any.setValue(false);
+        Assert.That(any.Type, Is.EqualTo(typeof(bool)));
+        Assert.That(any.Value, Is.EqualTo(false));
+    }
+
+    [Test]
+    [Description("Tests if Any.setValue(type, value) method throws on invalid 
args")]
+    public void setValue_RejectsInvalidParams()
+    {
+        Any any = Any.with(10);
+        Assert.That(() => any.setValue(null, 10), 
Throws.ArgumentNullException);
+        Assert.That(() => any.setValue(Any.VOID), Throws.ArgumentException);
+        Assert.That(() => any.setValue(typeof(int), null), 
Throws.ArgumentException);
+    }
+
+    [Test]
+    [Description("Tests if Any.GetHashCode() returns same hash for identical 
values")]
+    public void GetHashCode_ReturnsTrueForSame()
+    {
+        Assert.That(Any.VOID.GetHashCode() == Any.VOID.GetHashCode(), Is.True);
+        Assert.That(Any.with(10).GetHashCode() == Any.with(10).GetHashCode(), 
Is.True);
+    }
+
+    [Test]
+    [Description("Tests if Any.GetHashCode() returns different hash for 
different values")]
+    public void GetHashCode_ReturnsTrueForDifferent()
+    {
+        Assert.That(Any.VOID.GetHashCode() == Any.with(10).GetHashCode(), 
Is.False);
+    }
+}
diff --git a/net_ure/source/basetypes/Any.cs b/net_ure/source/basetypes/Any.cs
index 163bc59de631..7f4a8580b019 100644
--- a/net_ure/source/basetypes/Any.cs
+++ b/net_ure/source/basetypes/Any.cs
@@ -37,11 +37,20 @@ namespace com.sun.star.uno
             Type = type;
             Value = value;
         }
+        public void setValue<T>(T value) => setValue(typeof(T), value);
 
-        public bool equals(Any obj) => Type == obj.Type && Value == obj.Value;
+        public bool equals(Any other)
+        {
+            return other != null && Type.Equals(other.Type)
+                && (Value == null ? other.Value == null : 
Value.Equals(other.Value));
+        }
 
-        public override bool Equals(object obj) => (obj is Any other) && 
equals(other);
+        public static bool operator ==(Any left, Any right) => 
left?.Equals(right) ?? false;
+        public static bool operator !=(Any left, Any right) => !(left == 
right);
+
+        public override bool Equals(object obj) => obj is Any other && 
equals(other);
         public override int GetHashCode() => (Type, Value).GetHashCode();
+
         public override string ToString() => $"uno.Any {{ Type = {Type}, Value 
= {Value ?? "Null"} }}";
     }
 }
diff --git a/solenv/gbuild/DotnetTest.mk b/solenv/gbuild/DotnetTest.mk
new file mode 100644
index 000000000000..c51487cecf5c
--- /dev/null
+++ b/solenv/gbuild/DotnetTest.mk
@@ -0,0 +1,146 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+###########################
+# DotnetTest Target Class #
+###########################
+
+####### Constant Strings #########
+
+gb_DotnetTest_CS := cs
+gb_DotnetTest_FS := fs
+gb_DotnetTest_VB := vb
+
+define gb_DotnetTest__TEST_NUGETS
+<PackageReference Include="NUnit" Version="4.1.0" /> \
+<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" /> \
+<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" /> \
+
+endef
+
+####### Build and Clean Targets #########
+
+# Template for a target to generate the project file for a DotnetTest
+define gb_DotnetTest__project_target
+$$(gb_DotnetTest_$(1)_project) :
+       $$(shell mkdir -p $$(dir $$@))
+       $$(file  >$$@,<Project Sdk="Microsoft.NET.Sdk">)
+       $$(file >>$$@,<PropertyGroup>)
+       $$(file >>$$@,$$(DOTNET_PROPERTY_ELEMENTS))
+       $$(file >>$$@,</PropertyGroup>)
+       $$(file >>$$@,<ItemGroup>)
+       $$(file >>$$@,$$(DOTNET_ITEM_ELEMENTS))
+       $$(file >>$$@,</ItemGroup>)
+       $$(file >>$$@,</Project>)
+
+endef
+
+# Template for a target to build and run a DotnetTest
+define gb_DotnetTest__build_target
+$$(call gb_DotnetTest_get_target,$(1)) : $$(gb_DotnetTest_$(1)_project)
+       $$(call gb_Output_announce,$(1),$(true),NET,4)
+       $$(call gb_Trace_StartRange,$(1),NET)
+       $$(call gb_Helper_abbreviate_dirs,\
+               $$(call gb_Helper_print_on_error,\
+                       "$$(DOTNET)" test $$< $$(DOTNET_BUILD_FLAGS) -o $$(dir 
$$@),\
+                       $$(gb_DotnetTest_workdir)/$(1)/log))
+       $$(call gb_Trace_EndRange,$(1),NET)
+
+endef
+
+# Template for a target to clean a DotnetTest
+define gb_DotnetTest__clean_target
+$$(call gb_DotnetTest_get_clean_target,$(1)) :
+       $$(call gb_Output_announce,$(1),$(false),NET,4)
+       $$(call gb_Helper_abbreviate_dirs,\
+               rm -rf $$(gb_DotnetTest_$(1)_project))
+
+endef
+
+####### Test Target Constructor #########
+
+# Generates one test project for the given language, instantiating 
+# the project file, build/run and clean targets from above templates
+# call gb_DotnetTest_DotnetTest,targetname,language
+define gb_DotnetTest_DotnetTest
+gb_DotnetTest_$(1)_language := $(2)
+gb_DotnetTest_$(1)_project := $(gb_DotnetTest_workdir)/$(1)/$(1).$(2)proj
+
+$$(gb_DotnetTest_$(1)_project) : DOTNET_PROPERTY_ELEMENTS := 
<TargetFramework>net8.0</TargetFramework>
+$$(gb_DotnetTest_$(1)_project) : DOTNET_PROPERTY_ELEMENTS += 
<IsPackable>false</IsPackable>
+$$(gb_DotnetTest_$(1)_project) : DOTNET_PROPERTY_ELEMENTS += 
<IsTestProject>true</IsTestProject>
+$$(gb_DotnetTest_$(1)_project) : DOTNET_PROPERTY_ELEMENTS += 
<AssemblyName>$(1)</AssemblyName>
+$$(gb_DotnetTest_$(1)_project) : DOTNET_ITEM_ELEMENTS := 
$(gb_DotnetTest__TEST_NUGETS)
+$$(eval $$(call gb_DotnetTest__project_target,$(1)))
+
+$$(call gb_DotnetTest_get_target,$(1)) : DOTNET_BUILD_FLAGS := $(if 
$(ENABLE_DEBUG),-c Debug,-c Release)
+.PHONY : $$(call gb_DotnetTest_get_target,$(1))
+$$(eval $$(call gb_DotnetTest__build_target,$(1)))
+
+.PHONY : $$(call gb_DotnetTest_get_clean_target,$(1))
+$$(eval $$(call gb_DotnetTest__clean_target,$(1)))
+
+$$(eval $$(call gb_Module_register_target, \
+       $(call gb_DotnetTest_get_target,$(1)), \
+       $(call gb_DotnetTest_get_clean_target,$(1))))
+$(call gb_Helper_make_userfriendly_targets,$(1),DotnetTest)
+
+endef
+
+####### Target Property Setters #########
+
+# Add flags used for compilation
+# call gb_DotnetTest_add_build_flags,target,flags
+define gb_DotnetTest_add_build_flags
+$(call gb_DotnetTest_get_target,$(1)) : DOTNET_BUILD_FLAGS += $(2)
+
+endef
+
+# Add <PropertyGroup> elements to the project file
+# call gb_DotnetTest_add_properties,target,properties
+define gb_DotnetTest_add_properties
+$(gb_DotnetTest_$(1)_project) : DOTNET_PROPERTY_ELEMENTS += $(2)
+
+endef
+
+# Add <ItemGroup> elements to the project file
+# call gb_DotnetTest_add_items,target,items
+define gb_DotnetTest_add_items
+$(gb_DotnetTest_$(1)_project) : DOTNET_ITEM_ELEMENTS += $(2)
+
+endef
+
+# Add one source file to the project file
+# This adds it to the project, and makes it a build dependency
+# so the test is rebuilt if the source changes
+# call gb_DotnetTest_add_source,target,source
+define gb_DotnetTest_add_source
+$(gb_DotnetTest_$(1)_project) : $(SRCDIR)/$(2).$(gb_DotnetTest_$(1)_language)
+$(call gb_DotnetTest_add_items,$(1),<Compile 
Include="$(SRCDIR)/$(2).$(gb_DotnetTest_$(1)_language)"/>)
+
+endef
+
+# Add source files to the project file
+# This adds them to the project, and makes it them build dependency
+# so the test is rebuilt if the sources change
+# call gb_DotnetTest_add_sources,target,sources
+define gb_DotnetTest_add_sources
+$(foreach source,$(2),$(call gb_DotnetTest_add_source,$(1),$(source)))
+
+endef
+
+# Link to a DotnetLibrary target
+# call gb_DotnetTest_link_library,target,library
+define gb_DotnetTest_link_library
+$(gb_DotnetTest_$(1)_project) : $(call gb_DotnetLibrary_get_target,$(2))
+$(call gb_DotnetTest_add_items,$(1),<ProjectReference 
Include="$(gb_DotnetLibrary_$(2)_project)"/>)
+
+endef
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/TargetLocations.mk b/solenv/gbuild/TargetLocations.mk
index edfd2459cd62..9b950eb3f94e 100644
--- a/solenv/gbuild/TargetLocations.mk
+++ b/solenv/gbuild/TargetLocations.mk
@@ -65,6 +65,8 @@ gb_CxxObject_get_target = $(WORKDIR)/CxxObject/$(1).o
 gb_CxxObject_get_dwo_target = $(WORKDIR)/CxxObject/$(1).dwo
 gb_DotnetLibrary_get_target = $(WORKDIR)/DotnetLibrary/$(1)/$(1).dll
 gb_DotnetLibrary_workdir = $(WORKDIR)/DotnetLibrary
+gb_DotnetTest_get_target = $(WORKDIR)/DotnetTest/$(1)/done
+gb_DotnetTest_workdir = $(WORKDIR)/DotnetTest
 gb_GenCxxObject_get_target = $(WORKDIR)/GenCxxObject/$(1).o
 gb_GenCxxObject_get_dwo_target = $(WORKDIR)/GenCxxObject/$(1).dwo
 gb_GenAsmObject_get_target = $(WORKDIR)/GenAsmObject/$(1).o
@@ -276,6 +278,7 @@ $(eval $(call gb_Helper_make_clean_targets,\
        DescriptionTranslateTarget \
        Dictionary \
        DotnetLibrary \
+       DotnetTest \
        Executable \
        ExternalPackage \
        Extension \
diff --git a/solenv/gbuild/gbuild.help.txt b/solenv/gbuild/gbuild.help.txt
index 7b66d154b73a..640abe863fb3 100644
--- a/solenv/gbuild/gbuild.help.txt
+++ b/solenv/gbuild/gbuild.help.txt
@@ -83,6 +83,7 @@ AVAILABLE TARGETS
            o CustomTarget
            o Dictionary
            o DotnetLibrary
+           o DotnetTest
            o Executable
            o Extension
            o ExternalPackage
diff --git a/solenv/gbuild/gbuild.mk b/solenv/gbuild/gbuild.mk
index 2a2f89cf8f45..b3ae841c1c15 100644
--- a/solenv/gbuild/gbuild.mk
+++ b/solenv/gbuild/gbuild.mk
@@ -331,6 +331,7 @@ include $(foreach class, \
        CliNativeLibrary \
        CliUnoApi \
        DotnetLibrary \
+       DotnetTest \
        Zip \
        AllLangPackage \
        Configuration \

Reply via email to