1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-09 23:34:20 +00:00

juce_core: Add tests and fix some bugs with Objective C helper functions

This commit is contained in:
Anthony Nicholls 2023-10-04 14:47:42 +01:00
parent 5e1865c1c2
commit 42ab5404c8
24 changed files with 164 additions and 99 deletions

View file

@ -1086,6 +1086,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_core/native/juce_Network_mac.mm"
"../../../../../modules/juce_core/native/juce_Network_windows.cpp"
"../../../../../modules/juce_core/native/juce_ObjCHelpers_mac.h"
"../../../../../modules/juce_core/native/juce_ObjCHelpers_mac_test.mm"
"../../../../../modules/juce_core/native/juce_PlatformTimer_generic.cpp"
"../../../../../modules/juce_core/native/juce_PlatformTimer_windows.cpp"
"../../../../../modules/juce_core/native/juce_PlatformTimerListener.h"
@ -3154,6 +3155,7 @@ set_source_files_properties(
"../../../../../modules/juce_core/native/juce_Network_mac.mm"
"../../../../../modules/juce_core/native/juce_Network_windows.cpp"
"../../../../../modules/juce_core/native/juce_ObjCHelpers_mac.h"
"../../../../../modules/juce_core/native/juce_ObjCHelpers_mac_test.mm"
"../../../../../modules/juce_core/native/juce_PlatformTimer_generic.cpp"
"../../../../../modules/juce_core/native/juce_PlatformTimer_windows.cpp"
"../../../../../modules/juce_core/native/juce_PlatformTimerListener.h"

View file

@ -2017,6 +2017,9 @@
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_Network_windows.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_ObjCHelpers_mac_test.mm">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_PlatformTimer_generic.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>

View file

@ -2017,6 +2017,9 @@
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_Network_windows.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_ObjCHelpers_mac_test.mm">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_PlatformTimer_generic.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>

View file

@ -2017,6 +2017,9 @@
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_Network_windows.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_ObjCHelpers_mac_test.mm">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_PlatformTimer_generic.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>

View file

@ -962,6 +962,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_core/native/juce_Network_mac.mm"
"../../../../../modules/juce_core/native/juce_Network_windows.cpp"
"../../../../../modules/juce_core/native/juce_ObjCHelpers_mac.h"
"../../../../../modules/juce_core/native/juce_ObjCHelpers_mac_test.mm"
"../../../../../modules/juce_core/native/juce_PlatformTimer_generic.cpp"
"../../../../../modules/juce_core/native/juce_PlatformTimer_windows.cpp"
"../../../../../modules/juce_core/native/juce_PlatformTimerListener.h"
@ -2730,6 +2731,7 @@ set_source_files_properties(
"../../../../../modules/juce_core/native/juce_Network_mac.mm"
"../../../../../modules/juce_core/native/juce_Network_windows.cpp"
"../../../../../modules/juce_core/native/juce_ObjCHelpers_mac.h"
"../../../../../modules/juce_core/native/juce_ObjCHelpers_mac_test.mm"
"../../../../../modules/juce_core/native/juce_PlatformTimer_generic.cpp"
"../../../../../modules/juce_core/native/juce_PlatformTimer_windows.cpp"
"../../../../../modules/juce_core/native/juce_PlatformTimerListener.h"

View file

@ -1726,6 +1726,9 @@
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_Network_windows.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_ObjCHelpers_mac_test.mm">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_PlatformTimer_generic.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>

View file

@ -995,6 +995,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_core/native/juce_Network_mac.mm"
"../../../../../modules/juce_core/native/juce_Network_windows.cpp"
"../../../../../modules/juce_core/native/juce_ObjCHelpers_mac.h"
"../../../../../modules/juce_core/native/juce_ObjCHelpers_mac_test.mm"
"../../../../../modules/juce_core/native/juce_PlatformTimer_generic.cpp"
"../../../../../modules/juce_core/native/juce_PlatformTimer_windows.cpp"
"../../../../../modules/juce_core/native/juce_PlatformTimerListener.h"
@ -2916,6 +2917,7 @@ set_source_files_properties(
"../../../../../modules/juce_core/native/juce_Network_mac.mm"
"../../../../../modules/juce_core/native/juce_Network_windows.cpp"
"../../../../../modules/juce_core/native/juce_ObjCHelpers_mac.h"
"../../../../../modules/juce_core/native/juce_ObjCHelpers_mac_test.mm"
"../../../../../modules/juce_core/native/juce_PlatformTimer_generic.cpp"
"../../../../../modules/juce_core/native/juce_PlatformTimer_windows.cpp"
"../../../../../modules/juce_core/native/juce_PlatformTimerListener.h"

View file

@ -1801,6 +1801,9 @@
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_Network_windows.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_ObjCHelpers_mac_test.mm">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_PlatformTimer_generic.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>

View file

@ -1801,6 +1801,9 @@
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_Network_windows.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_ObjCHelpers_mac_test.mm">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_PlatformTimer_generic.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>

View file

@ -1801,6 +1801,9 @@
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_Network_windows.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_ObjCHelpers_mac_test.mm">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_PlatformTimer_generic.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>

View file

@ -247,6 +247,9 @@
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_Network_windows.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_ObjCHelpers_mac_test.mm">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_PlatformTimer_generic.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>

View file

@ -966,6 +966,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_core/native/juce_Network_mac.mm"
"../../../../../modules/juce_core/native/juce_Network_windows.cpp"
"../../../../../modules/juce_core/native/juce_ObjCHelpers_mac.h"
"../../../../../modules/juce_core/native/juce_ObjCHelpers_mac_test.mm"
"../../../../../modules/juce_core/native/juce_PlatformTimer_generic.cpp"
"../../../../../modules/juce_core/native/juce_PlatformTimer_windows.cpp"
"../../../../../modules/juce_core/native/juce_PlatformTimerListener.h"
@ -2814,6 +2815,7 @@ set_source_files_properties(
"../../../../../modules/juce_core/native/juce_Network_mac.mm"
"../../../../../modules/juce_core/native/juce_Network_windows.cpp"
"../../../../../modules/juce_core/native/juce_ObjCHelpers_mac.h"
"../../../../../modules/juce_core/native/juce_ObjCHelpers_mac_test.mm"
"../../../../../modules/juce_core/native/juce_PlatformTimer_generic.cpp"
"../../../../../modules/juce_core/native/juce_PlatformTimer_windows.cpp"
"../../../../../modules/juce_core/native/juce_PlatformTimerListener.h"

View file

@ -1756,6 +1756,9 @@
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_Network_windows.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_ObjCHelpers_mac_test.mm">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_PlatformTimer_generic.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>

View file

@ -724,6 +724,9 @@
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_Network_windows.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_ObjCHelpers_mac_test.mm">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_PlatformTimer_generic.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>

View file

@ -724,6 +724,9 @@
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_Network_windows.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_ObjCHelpers_mac_test.mm">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_PlatformTimer_generic.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>

View file

@ -724,6 +724,9 @@
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_Network_windows.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_ObjCHelpers_mac_test.mm">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_PlatformTimer_generic.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>

View file

@ -1813,6 +1813,9 @@
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_Network_windows.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_ObjCHelpers_mac_test.mm">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_PlatformTimer_generic.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>

View file

@ -1813,6 +1813,9 @@
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_Network_windows.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_ObjCHelpers_mac_test.mm">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_PlatformTimer_generic.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>

View file

@ -1813,6 +1813,9 @@
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_Network_windows.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_ObjCHelpers_mac_test.mm">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_PlatformTimer_generic.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>

View file

@ -1753,6 +1753,9 @@
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_Network_windows.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_ObjCHelpers_mac_test.mm">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_PlatformTimer_generic.cpp">
<Filter>JUCE Modules\juce_core\native</Filter>
</ClCompile>

View file

@ -283,6 +283,9 @@
#include "misc/juce_EnumHelpers_test.cpp"
#include "containers/juce_FixedSizeFunction_test.cpp"
#include "javascript/juce_JSONSerialisation_test.cpp"
#if JUCE_MAC || JUCE_IOS
#include "native/juce_ObjCHelpers_mac_test.mm"
#endif
#endif
//==============================================================================

View file

@ -76,127 +76,62 @@ inline NSURL* createNSURLFromFile (const File& f)
inline NSArray* createNSArrayFromStringArray (const StringArray& strings)
{
auto array = [[NSMutableArray alloc] init];
auto array = [[NSMutableArray alloc] initWithCapacity: (NSUInteger) strings.size()];
for (auto string: strings)
[array addObject:juceStringToNS (string)];
for (const auto& string: strings)
[array addObject: juceStringToNS (string)];
return [array autorelease];
}
inline NSArray* varArrayToNSArray (const var& varToParse);
inline NSData* varToJsonData (const var& varToParse)
{
return [juceStringToNS (JSON::toString (varToParse)) dataUsingEncoding: NSUTF8StringEncoding];
}
inline var jsonDataToVar (NSData* jsonData)
{
auto* jsonString = [[NSString alloc] initWithData: jsonData
encoding: NSUTF8StringEncoding];
jassert (jsonString != nullptr);
return JSON::parse (nsStringToJuce ([jsonString autorelease]));
}
inline NSDictionary* varObjectToNSDictionary (const var& varToParse)
{
auto dictionary = [NSMutableDictionary dictionary];
jassert (varToParse.isObject());
if (varToParse.isObject())
{
auto* dynamicObject = varToParse.getDynamicObject();
if (! varToParse.isObject())
return nullptr;
auto& properties = dynamicObject->getProperties();
NSError* error { nullptr };
NSDictionary* dictionary = [NSJSONSerialization JSONObjectWithData: varToJsonData (varToParse)
options: NSJSONReadingMutableContainers
error: &error];
for (int i = 0; i < properties.size(); ++i)
{
auto* keyString = juceStringToNS (properties.getName (i).toString());
const var& valueVar = properties.getValueAt (i);
if (valueVar.isObject())
{
auto* valueDictionary = varObjectToNSDictionary (valueVar);
[dictionary setObject: valueDictionary forKey: keyString];
}
else if (valueVar.isArray())
{
auto* valueArray = varArrayToNSArray (valueVar);
[dictionary setObject: valueArray forKey: keyString];
}
else
{
auto* valueString = juceStringToNS (valueVar.toString());
[dictionary setObject: valueString forKey: keyString];
}
}
}
jassert (error == nullptr);
jassert (dictionary != nullptr);
return dictionary;
}
inline NSArray* varArrayToNSArray (const var& varToParse)
inline NSData* jsonObjectToData (const NSObject* jsonObject)
{
jassert (varToParse.isArray());
NSError* error { nullptr };
auto* jsonData = [NSJSONSerialization dataWithJSONObject: jsonObject
options: 0
error: &error];
if (! varToParse.isArray())
return nil;
jassert (error == nullptr);
jassert (jsonData != nullptr);
const auto* varArray = varToParse.getArray();
auto array = [NSMutableArray arrayWithCapacity: (NSUInteger) varArray->size()];
for (const auto& aVar : *varArray)
{
if (aVar.isObject())
{
auto* valueDictionary = varObjectToNSDictionary (aVar);
[array addObject: valueDictionary];
}
else if (aVar.isArray())
{
auto* valueArray = varArrayToNSArray (aVar);
[array addObject: valueArray];
}
else
{
auto* valueString = juceStringToNS (aVar.toString());
[array addObject: valueString];
}
}
return array;
return jsonData;
}
var nsObjectToVar (NSObject* array);
inline var nsDictionaryToVar (NSDictionary* dictionary)
{
DynamicObject::Ptr dynamicObject (new DynamicObject());
for (NSString* key in dictionary)
dynamicObject->setProperty (nsStringToJuce (key), nsObjectToVar ([dictionary objectForKey: key]));
return var (dynamicObject.get());
}
inline var nsArrayToVar (NSArray* array)
{
Array<var> resultArray;
for (id value in array)
resultArray.add (nsObjectToVar (value));
return var (resultArray);
}
inline var nsObjectToVar (NSObject* obj)
{
if ([obj isKindOfClass: [NSString class]]) return nsStringToJuce ((NSString*) obj);
else if ([obj isKindOfClass: [NSNumber class]]) return nsStringToJuce ([(NSNumber*) obj stringValue]);
else if ([obj isKindOfClass: [NSDictionary class]]) return nsDictionaryToVar ((NSDictionary*) obj);
else if ([obj isKindOfClass: [NSArray class]]) return nsArrayToVar ((NSArray*) obj);
else
{
// Unsupported yet, add here!
jassertfalse;
}
return {};
return jsonDataToVar (jsonObjectToData (dictionary));
}
#if JUCE_MAC

View file

@ -0,0 +1,70 @@
namespace juce {
class ObjCHelpersTest final : public UnitTest {
public:
ObjCHelpersTest() : UnitTest{"ObjCHelpers", UnitTestCategories::native} {}
void runTest() final {
beginTest("Range");
{
constexpr auto start = 10;
constexpr auto length = 20;
const auto juceRange = Range<int>::withStartAndLength(start, length);
const auto nsRange = NSMakeRange(start, length);
expect(nsRangeToJuce(nsRange) == juceRange);
expect(NSEqualRanges(nsRange, juceRangeToNS(juceRange)));
}
beginTest("String");
{
String juceString{"Hello world!"};
NSString *nsString{@"Hello world!"};
expect(nsStringToJuce(nsString) == juceString);
expect([nsString isEqualToString:juceStringToNS(juceString)]);
expect([nsString isEqualToString:nsStringLiteral("Hello world!")]);
}
beginTest("StringArray");
{
const StringArray stringArray{"Hello world!", "this", "is", "a", "test"};
NSArray *nsArray { @[ @"Hello world!", @"this", @"is", @"a", @"test" ] };
expect(
[nsArray isEqualToArray:createNSArrayFromStringArray(stringArray)]);
}
beginTest("Dictionary");
{
DynamicObject::Ptr data{new DynamicObject()};
data->setProperty("integer", 1);
data->setProperty("double", 2.3);
data->setProperty("boolean", true);
data->setProperty("string", "Hello world!");
Array<var> array{45, 67.8, true, "Hello array!"};
data->setProperty("array", array);
auto *nsDictionary = varObjectToNSDictionary(data.get());
auto clone = nsDictionaryToVar(nsDictionary);
expect(clone.getProperty("integer", {}).isInt());
expect(clone.getProperty("double", {}).isDouble());
expect(clone.getProperty("boolean", {}).isBool());
expect(clone.getProperty("string", {}).isString());
expect(clone.getProperty("array", {}).isArray());
expect(clone.getProperty("integer", {}) == var{1});
expect(clone.getProperty("double", {}) == var{2.3});
expect(clone.getProperty("boolean", {}) == var{true});
expect(clone.getProperty("string", {}) == var{"Hello world!"});
expect(clone.getProperty("array", {}) == array);
}
}
};
static ObjCHelpersTest objCHelpersTest;
} // namespace juce

View file

@ -40,6 +40,7 @@ namespace UnitTestCategories
static const String json { "JSON" };
static const String maths { "Maths" };
static const String midi { "MIDI" };
static const String native { "Native" };
static const String networking { "Networking" };
static const String osc { "OSC" };
static const String smoothedValues { "SmoothedValues" };