Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/Core/src/Handlers/Editor/EditorHandler.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,12 @@ public static void MapHorizontalTextAlignment(IEditorHandler handler, IEditor ed
public static void MapVerticalTextAlignment(IEditorHandler handler, IEditor editor) =>
handler.PlatformView?.UpdateVerticalTextAlignment(editor);

public static void MapKeyboard(IEditorHandler handler, IEditor editor) =>
public static void MapKeyboard(IEditorHandler handler, IEditor editor)
{
handler.UpdateValue(nameof(IEditor.Text));

handler.PlatformView?.UpdateKeyboard(editor);
}

public static void MapCursorPosition(IEditorHandler handler, ITextInput editor) =>
handler.PlatformView?.UpdateCursorPosition(editor);
Expand Down
18 changes: 15 additions & 3 deletions src/Core/src/Handlers/Entry/EntryHandler.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,12 @@ public static void MapText(IEntryHandler handler, IEntry entry) =>
public static void MapTextColor(IEntryHandler handler, IEntry entry) =>
handler.PlatformView?.UpdateTextColor(entry);

public static void MapIsPassword(IEntryHandler handler, IEntry entry) =>
public static void MapIsPassword(IEntryHandler handler, IEntry entry)
{
handler.UpdateValue(nameof(IEntry.Text));

handler.PlatformView?.UpdateIsPassword(entry);
}

public static void MapHorizontalTextAlignment(IEntryHandler handler, IEntry entry) =>
handler.PlatformView?.UpdateHorizontalTextAlignment(entry);
Expand Down Expand Up @@ -103,11 +107,19 @@ public static void MapPlaceholderColor(IEntryHandler handler, IEntry entry)
public static void MapFont(IEntryHandler handler, IEntry entry) =>
handler.PlatformView?.UpdateFont(entry, handler.GetRequiredService<IFontManager>());

public static void MapIsReadOnly(IEntryHandler handler, IEntry entry) =>
public static void MapIsReadOnly(IEntryHandler handler, IEntry entry)
{
handler.UpdateValue(nameof(IEntry.Text));

handler.PlatformView?.UpdateIsReadOnly(entry);
}

public static void MapKeyboard(IEntryHandler handler, IEntry entry)
{
handler.UpdateValue(nameof(IEntry.Text));

public static void MapKeyboard(IEntryHandler handler, IEntry entry) =>
handler.PlatformView?.UpdateKeyboard(entry);
}

public static void MapReturnType(IEntryHandler handler, IEntry entry) =>
handler.PlatformView?.UpdateReturnType(entry);
Expand Down
2 changes: 2 additions & 0 deletions src/Core/src/Handlers/SearchBar/SearchBarHandler.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ public static void MapCancelButtonColor(ISearchBarHandler handler, ISearchBar se

public static void MapKeyboard(ISearchBarHandler handler, ISearchBar searchBar)
{
handler.UpdateValue(nameof(ISearchBar.Text));

handler.PlatformView?.UpdateKeyboard(searchBar);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,26 @@ protected Task<TValue> GetValueAsync<TValue>(IView view, Func<THandler, Task<TVa
});
}

protected Task<TValue> GetValueAsync<TValue, TCustomHandler>(IView view, Func<TCustomHandler, TValue> func)
where TCustomHandler : IElementHandler, new()
{
return InvokeOnMainThreadAsync(() =>
{
var handler = CreateHandler<TCustomHandler>(view);
return func(handler);
});
}

protected Task<TValue> GetValueAsync<TValue, TCustomHandler>(IView view, Func<TCustomHandler, Task<TValue>> func)
where TCustomHandler : IElementHandler, new()
{
return InvokeOnMainThreadAsync(() =>
{
var handler = CreateHandler<TCustomHandler>(view);
return func(handler);
});
}

protected Task SetValueAsync<TValue>(IView view, TValue value, Action<THandler, TValue> func)
{
return SetValueAsync<TValue, THandler>(view, value, func);
Expand All @@ -98,6 +118,26 @@ async protected Task ValidatePropertyInitValue<TValue>(
Assert.Equal(expectedValue, values.PlatformViewValue);
}

async protected Task ValidatePropertyInitValue<TValue, TCustomHandler>(
IView view,
Func<TValue> GetValue,
Func<TCustomHandler, TValue> GetPlatformValue,
TValue expectedValue)
where TCustomHandler : IElementHandler, new()
{
var values = await GetValueAsync(view, (TCustomHandler handler) =>
{
return new
{
ViewValue = GetValue(),
PlatformViewValue = GetPlatformValue(handler)
};
});

Assert.Equal(expectedValue, values.ViewValue);
Assert.Equal(expectedValue, values.PlatformViewValue);
}

async protected Task ValidatePropertyInitValue<TValue>(
IView view,
Func<TValue> GetValue,
Expand All @@ -118,6 +158,27 @@ async protected Task ValidatePropertyInitValue<TValue>(
Assert.Equal(expectedPlatformValue, values.PlatformViewValue);
}

async protected Task ValidatePropertyInitValue<TValue, TCustomHandler>(
IView view,
Func<TValue> GetValue,
Func<TCustomHandler, TValue> GetPlatformValue,
TValue expectedValue,
TValue expectedPlatformValue)
where TCustomHandler : IElementHandler, new()
{
var values = await GetValueAsync(view, (TCustomHandler handler) =>
{
return new
{
ViewValue = GetValue(),
PlatformViewValue = GetPlatformValue(handler)
};
});

Assert.Equal(expectedValue, values.ViewValue);
Assert.Equal(expectedPlatformValue, values.PlatformViewValue);
Comment thread
rachelkang marked this conversation as resolved.
}

async protected Task ValidatePropertyUpdatesValue<TValue>(
IView view,
string property,
Expand Down
30 changes: 30 additions & 0 deletions src/Core/tests/DeviceTests/Handlers/Editor/EditorHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,23 @@ public async Task TextInitializesCorrectly()
await ValidatePropertyInitValue(editor, () => editor.Text, GetNativeText, editor.Text);
}

[Fact(DisplayName = "Text Property Initializes Correctly when Keyboard Mapper is Executed Before Text Mapper")]
public async Task TextInitializesCorrectlyWhenKeyboardIsBeforeText()
{
var editor = new EditorStub()
{
Text = "Test Text Here"
};

CustomEditorHandler.TestMapper = new PropertyMapper<IEditor, IEditorHandler>(EditorHandler.Mapper)
{
// this mapper is run first and then the ones in the ctor arg (EditorHandler.Mapper)
[nameof(IEditor.Keyboard)] = EditorHandler.MapKeyboard
};

await ValidatePropertyInitValue<string, CustomEditorHandler>(editor, () => editor.Text, GetNativeText, editor.Text);
}

[Theory(DisplayName = "Text Updates Correctly")]
[InlineData(null, null)]
[InlineData(null, "Hello")]
Expand Down Expand Up @@ -515,5 +532,18 @@ protected override int GetCursorStartPosition(EditorHandler editorHandler) =>
protected override void UpdateCursorStartPosition(EditorHandler editorHandler, int position) =>
EditorHandlerTests.UpdateCursorStartPosition(editorHandler, position);
}

class CustomEditorHandler : EditorHandler
{
// make a copy of the Core mappers because we don't want any Controls changes or to override us
public static PropertyMapper<IEditor, IEditorHandler> TestMapper = new(Mapper);
public static CommandMapper<IEditor, IEditorHandler> TestCommandMapper = new(CommandMapper);

// make sure to use our mappers
public CustomEditorHandler()
: base(TestMapper, TestCommandMapper)
{
}
}
Comment thread
rachelkang marked this conversation as resolved.
}
}
64 changes: 64 additions & 0 deletions src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,57 @@ public async Task TextInitializesCorrectly()
await ValidatePropertyInitValue(entry, () => entry.Text, GetNativeText, entry.Text);
}

[Fact(DisplayName = "Text Property Initializes Correctly when Keyboard Mapper is Executed Before Text Mapper")]
public async Task TextInitializesCorrectlyWhenKeyboardIsBeforeText()
{
var entry = new EntryStub()
{
Text = "Test Text Here"
};

CustomEntryHandler.TestMapper = new PropertyMapper<IEntry, IEntryHandler>(EntryHandler.Mapper)
Comment thread
rachelkang marked this conversation as resolved.
{
// this mapper is run first and then the ones in the ctor arg (EntryHandler.Mapper)
[nameof(IEntry.Keyboard)] = EntryHandler.MapKeyboard
};

await ValidatePropertyInitValue<string, CustomEntryHandler>(entry, () => entry.Text, GetNativeText, entry.Text);
}

[Fact(DisplayName = "Text Property Initializes Correctly when IsReadOnly Mapper is Executed Before Text Mapper")]
public async Task TextInitializesCorrectlyWhenIsReadOnlyIsBeforeText()
{
var entry = new EntryStub()
{
Text = "Test Text Here"
};

CustomEntryHandler.TestMapper = new PropertyMapper<IEntry, IEntryHandler>(EntryHandler.Mapper)
{
// this mapper is run first and then the ones in the ctor arg (EntryHandler.Mapper)
[nameof(IEntry.IsReadOnly)] = EntryHandler.MapIsReadOnly
};

await ValidatePropertyInitValue<string, CustomEntryHandler>(entry, () => entry.Text, GetNativeText, entry.Text);
}

[Fact(DisplayName = "Text Property Initializes Correctly when IsPassword Mapper is Executed Before Text Mapper")]
public async Task TextInitializesCorrectlyWhenIsPasswordIsBeforeText()
{
var entry = new EntryStub()
{
Text = "Test Text Here"
};

CustomEntryHandler.TestMapper = new PropertyMapper<IEntry, IEntryHandler>(EntryHandler.Mapper)
{
// this mapper is run first and then the ones in the ctor arg (EntryHandler.Mapper)
[nameof(IEntry.IsPassword)] = EntryHandler.MapIsPassword
};

await ValidatePropertyInitValue<string, CustomEntryHandler>(entry, () => entry.Text, GetNativeText, entry.Text);
}

[Fact(DisplayName = "TextColor Initializes Correctly")]
public async Task TextColorInitializesCorrectly()
{
Expand Down Expand Up @@ -734,5 +785,18 @@ protected override int GetCursorStartPosition(EntryHandler entryHandler) =>
protected override void UpdateCursorStartPosition(EntryHandler entryHandler, int position) =>
EntryHandlerTests.UpdateCursorStartPosition(entryHandler, position);
}

class CustomEntryHandler : EntryHandler
{
// make a copy of the Core mappers because we don't want any Controls changes or to override us
public static PropertyMapper<IEntry, IEntryHandler> TestMapper = new(Mapper);
public static CommandMapper<IEntry, IEntryHandler> TestCommandMapper = new(CommandMapper);

// make sure to use our mappers
public CustomEntryHandler()
: base(TestMapper, TestCommandMapper)
{
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,23 @@ public async Task TextInitializesCorrectly()
await ValidatePropertyInitValue(searchBar, () => searchBar.Text, GetNativeText, searchBar.Text);
}

[Fact(DisplayName = "Text Property Initializes Correctly when Keyboard Mapper is Executed Before Text Mapper")]
public async Task TextInitializesCorrectlyWhenKeyboardIsBeforeText()
{
var searchBar = new SearchBarStub()
{
Text = "Test Text Here"
};

CustomSearchBarHandler.TestMapper = new PropertyMapper<ISearchBar, ISearchBarHandler>(SearchBarHandler.Mapper)
Comment thread
rachelkang marked this conversation as resolved.
{
// this mapper is run first and then the ones in the ctor arg (SearchBarHandler.Mapper)
[nameof(ISearchBar.Keyboard)] = SearchBarHandler.MapKeyboard
};

await ValidatePropertyInitValue<string, CustomSearchBarHandler>(searchBar, () => searchBar.Text, GetNativeText, searchBar.Text);
}

[Theory(DisplayName = "Query Text Updates Correctly")]
[InlineData(null, null)]
[InlineData(null, "Query")]
Expand Down Expand Up @@ -451,5 +468,18 @@ public SearchBarFocusTests()
}
}
#endif

class CustomSearchBarHandler : SearchBarHandler
{
// make a copy of the Core mappers because we don't want any Controls changes or to override us
public static PropertyMapper<ISearchBar, ISearchBarHandler> TestMapper = new(Mapper);
public static CommandMapper<ISearchBar, ISearchBarHandler> TestCommandMapper = new(CommandMapper);

// make sure to use our mappers
public CustomSearchBarHandler()
: base(TestMapper, TestCommandMapper)
{
}
}
}
}