mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
Merge pull request #1229 from enzoftware/main
test: Improve Code Coverage for extensions files
This commit is contained in:
commit
06f1d52cc0
@ -17,9 +17,9 @@ extension NodeAttributesExtensions on Attributes {
|
|||||||
return containsKey(BuiltInAttributeKey.quote);
|
return containsKey(BuiltInAttributeKey.quote);
|
||||||
}
|
}
|
||||||
|
|
||||||
int? get number {
|
num? get number {
|
||||||
if (containsKey(BuiltInAttributeKey.number) &&
|
if (containsKey(BuiltInAttributeKey.number) &&
|
||||||
this[BuiltInAttributeKey.number] is int) {
|
this[BuiltInAttributeKey.number] is num) {
|
||||||
return this[BuiltInAttributeKey.number];
|
return this[BuiltInAttributeKey.number];
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -27,7 +27,7 @@ extension NodeAttributesExtensions on Attributes {
|
|||||||
|
|
||||||
bool get code {
|
bool get code {
|
||||||
if (containsKey(BuiltInAttributeKey.code) &&
|
if (containsKey(BuiltInAttributeKey.code) &&
|
||||||
this[BuiltInAttributeKey.code] == true) {
|
this[BuiltInAttributeKey.code] is bool) {
|
||||||
return this[BuiltInAttributeKey.code];
|
return this[BuiltInAttributeKey.code];
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -63,11 +63,14 @@ extension DeltaAttributesExtensions on Attributes {
|
|||||||
this[BuiltInAttributeKey.strikethrough] == true);
|
this[BuiltInAttributeKey.strikethrough] == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const whiteInt = 0XFFFFFFFF;
|
||||||
|
|
||||||
Color? get color {
|
Color? get color {
|
||||||
if (containsKey(BuiltInAttributeKey.color) &&
|
if (containsKey(BuiltInAttributeKey.color) &&
|
||||||
this[BuiltInAttributeKey.color] is String) {
|
this[BuiltInAttributeKey.color] is String) {
|
||||||
return Color(
|
return Color(
|
||||||
int.parse(this[BuiltInAttributeKey.color]),
|
// If the parse fails returns white by default
|
||||||
|
int.tryParse(this[BuiltInAttributeKey.color]) ?? whiteInt,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -77,8 +80,7 @@ extension DeltaAttributesExtensions on Attributes {
|
|||||||
if (containsKey(BuiltInAttributeKey.backgroundColor) &&
|
if (containsKey(BuiltInAttributeKey.backgroundColor) &&
|
||||||
this[BuiltInAttributeKey.backgroundColor] is String) {
|
this[BuiltInAttributeKey.backgroundColor] is String) {
|
||||||
return Color(
|
return Color(
|
||||||
int.parse(this[BuiltInAttributeKey.backgroundColor]),
|
int.tryParse(this[BuiltInAttributeKey.backgroundColor]) ?? whiteInt);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import 'package:appflowy_editor/src/document/text_delta.dart';
|
|||||||
import 'package:appflowy_editor/src/document/built_in_attribute_keys.dart';
|
import 'package:appflowy_editor/src/document/built_in_attribute_keys.dart';
|
||||||
|
|
||||||
extension TextNodeExtension on TextNode {
|
extension TextNodeExtension on TextNode {
|
||||||
dynamic getAttributeInSelection(Selection selection, String styleKey) {
|
T? getAttributeInSelection<T>(Selection selection, String styleKey) {
|
||||||
final ops = delta.whereType<TextInsert>();
|
final ops = delta.whereType<TextInsert>();
|
||||||
final startOffset =
|
final startOffset =
|
||||||
selection.isBackward ? selection.start.offset : selection.end.offset;
|
selection.isBackward ? selection.start.offset : selection.end.offset;
|
||||||
@ -19,8 +19,9 @@ extension TextNodeExtension on TextNode {
|
|||||||
}
|
}
|
||||||
final length = op.length;
|
final length = op.length;
|
||||||
if (start < endOffset && start + length > startOffset) {
|
if (start < endOffset && start + length > startOffset) {
|
||||||
if (op.attributes?.containsKey(styleKey) == true) {
|
final attributes = op.attributes;
|
||||||
return op.attributes![styleKey];
|
if (attributes != null && attributes[styleKey] is T?) {
|
||||||
|
return attributes[styleKey];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
start += length;
|
start += length;
|
||||||
|
@ -26,6 +26,7 @@ import 'messages_hu-HU.dart' as messages_hu_hu;
|
|||||||
import 'messages_id-ID.dart' as messages_id_id;
|
import 'messages_id-ID.dart' as messages_id_id;
|
||||||
import 'messages_it-IT.dart' as messages_it_it;
|
import 'messages_it-IT.dart' as messages_it_it;
|
||||||
import 'messages_ja-JP.dart' as messages_ja_jp;
|
import 'messages_ja-JP.dart' as messages_ja_jp;
|
||||||
|
import 'messages_ml_IN.dart' as messages_ml_in;
|
||||||
import 'messages_nl-NL.dart' as messages_nl_nl;
|
import 'messages_nl-NL.dart' as messages_nl_nl;
|
||||||
import 'messages_pl-PL.dart' as messages_pl_pl;
|
import 'messages_pl-PL.dart' as messages_pl_pl;
|
||||||
import 'messages_pt-BR.dart' as messages_pt_br;
|
import 'messages_pt-BR.dart' as messages_pt_br;
|
||||||
@ -48,6 +49,7 @@ Map<String, LibraryLoader> _deferredLibraries = {
|
|||||||
'id_ID': () => new Future.value(null),
|
'id_ID': () => new Future.value(null),
|
||||||
'it_IT': () => new Future.value(null),
|
'it_IT': () => new Future.value(null),
|
||||||
'ja_JP': () => new Future.value(null),
|
'ja_JP': () => new Future.value(null),
|
||||||
|
'ml_IN': () => new Future.value(null),
|
||||||
'nl_NL': () => new Future.value(null),
|
'nl_NL': () => new Future.value(null),
|
||||||
'pl_PL': () => new Future.value(null),
|
'pl_PL': () => new Future.value(null),
|
||||||
'pt_BR': () => new Future.value(null),
|
'pt_BR': () => new Future.value(null),
|
||||||
@ -82,6 +84,8 @@ MessageLookupByLibrary? _findExact(String localeName) {
|
|||||||
return messages_it_it.messages;
|
return messages_it_it.messages;
|
||||||
case 'ja_JP':
|
case 'ja_JP':
|
||||||
return messages_ja_jp.messages;
|
return messages_ja_jp.messages;
|
||||||
|
case 'ml_IN':
|
||||||
|
return messages_ml_in.messages;
|
||||||
case 'nl_NL':
|
case 'nl_NL':
|
||||||
return messages_nl_nl.messages;
|
return messages_nl_nl.messages;
|
||||||
case 'pl_PL':
|
case 'pl_PL':
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
|
||||||
|
// This is a library that provides messages for a ml_IN locale. All the
|
||||||
|
// messages from the main program should be duplicated here with the same
|
||||||
|
// function name.
|
||||||
|
|
||||||
|
// Ignore issues from commonly used lints in this file.
|
||||||
|
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
|
||||||
|
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
|
||||||
|
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
|
||||||
|
// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes
|
||||||
|
// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes
|
||||||
|
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:intl/message_lookup_by_library.dart';
|
||||||
|
|
||||||
|
final messages = new MessageLookup();
|
||||||
|
|
||||||
|
typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
|
||||||
|
|
||||||
|
class MessageLookup extends MessageLookupByLibrary {
|
||||||
|
String get localeName => 'ml_IN';
|
||||||
|
|
||||||
|
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||||
|
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
|
||||||
|
"bold": MessageLookupByLibrary.simpleMessage("ബോൾഡ്"),
|
||||||
|
"bulletedList":
|
||||||
|
MessageLookupByLibrary.simpleMessage("ബുള്ളറ്റഡ് പട്ടിക"),
|
||||||
|
"checkbox": MessageLookupByLibrary.simpleMessage("ചെക്ക്ബോക്സ്"),
|
||||||
|
"embedCode": MessageLookupByLibrary.simpleMessage("എംബെഡഡ് കോഡ്"),
|
||||||
|
"heading1": MessageLookupByLibrary.simpleMessage("തലക്കെട്ട് 1"),
|
||||||
|
"heading2": MessageLookupByLibrary.simpleMessage("തലക്കെട്ട് 2"),
|
||||||
|
"heading3": MessageLookupByLibrary.simpleMessage("തലക്കെട്ട് 3"),
|
||||||
|
"highlight":
|
||||||
|
MessageLookupByLibrary.simpleMessage("പ്രമുഖമാക്കിക്കാട്ടുക"),
|
||||||
|
"image": MessageLookupByLibrary.simpleMessage("ചിത്രം"),
|
||||||
|
"italic": MessageLookupByLibrary.simpleMessage("ഇറ്റാലിക്"),
|
||||||
|
"link": MessageLookupByLibrary.simpleMessage("ലിങ്ക്"),
|
||||||
|
"numberedList":
|
||||||
|
MessageLookupByLibrary.simpleMessage("അക്കമിട്ട പട്ടിക"),
|
||||||
|
"quote": MessageLookupByLibrary.simpleMessage("ഉദ്ധരണി"),
|
||||||
|
"strikethrough": MessageLookupByLibrary.simpleMessage("സ്ട്രൈക്ക്ത്രൂ"),
|
||||||
|
"text": MessageLookupByLibrary.simpleMessage("വചനം"),
|
||||||
|
"underline": MessageLookupByLibrary.simpleMessage("അടിവരയിടുക")
|
||||||
|
};
|
||||||
|
}
|
@ -229,6 +229,7 @@ class AppLocalizationDelegate
|
|||||||
Locale.fromSubtags(languageCode: 'id', countryCode: 'ID'),
|
Locale.fromSubtags(languageCode: 'id', countryCode: 'ID'),
|
||||||
Locale.fromSubtags(languageCode: 'it', countryCode: 'IT'),
|
Locale.fromSubtags(languageCode: 'it', countryCode: 'IT'),
|
||||||
Locale.fromSubtags(languageCode: 'ja', countryCode: 'JP'),
|
Locale.fromSubtags(languageCode: 'ja', countryCode: 'JP'),
|
||||||
|
Locale.fromSubtags(languageCode: 'ml', countryCode: 'IN'),
|
||||||
Locale.fromSubtags(languageCode: 'nl', countryCode: 'NL'),
|
Locale.fromSubtags(languageCode: 'nl', countryCode: 'NL'),
|
||||||
Locale.fromSubtags(languageCode: 'pl', countryCode: 'PL'),
|
Locale.fromSubtags(languageCode: 'pl', countryCode: 'PL'),
|
||||||
Locale.fromSubtags(languageCode: 'pt', countryCode: 'BR'),
|
Locale.fromSubtags(languageCode: 'pt', countryCode: 'BR'),
|
||||||
|
@ -333,8 +333,10 @@ void showLinkMenu(
|
|||||||
final textNode = node.first as TextNode;
|
final textNode = node.first as TextNode;
|
||||||
String? linkText;
|
String? linkText;
|
||||||
if (textNode.allSatisfyLinkInSelection(selection)) {
|
if (textNode.allSatisfyLinkInSelection(selection)) {
|
||||||
linkText =
|
linkText = textNode.getAttributeInSelection<String>(
|
||||||
textNode.getAttributeInSelection(selection, BuiltInAttributeKey.href);
|
selection,
|
||||||
|
BuiltInAttributeKey.href,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
_linkMenuOverlay = OverlayEntry(builder: (context) {
|
_linkMenuOverlay = OverlayEntry(builder: (context) {
|
||||||
return Positioned(
|
return Positioned(
|
||||||
|
@ -33,6 +33,7 @@ dev_dependencies:
|
|||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_lints: ^2.0.1
|
flutter_lints: ^2.0.1
|
||||||
network_image_mock: ^2.1.1
|
network_image_mock: ^2.1.1
|
||||||
|
mockito: ^5.3.2
|
||||||
|
|
||||||
# For information on the generic Dart part of this file, see the
|
# For information on the generic Dart part of this file, see the
|
||||||
# following page: https://dart.dev/tools/pub/pubspec
|
# following page: https://dart.dev/tools/pub/pubspec
|
||||||
|
@ -0,0 +1,201 @@
|
|||||||
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('NodeAttributesExtensions::', () {
|
||||||
|
test('heading', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'subtype': 'heading',
|
||||||
|
'heading': 'AppFlowy',
|
||||||
|
};
|
||||||
|
expect(attribute.heading, 'AppFlowy');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('heading - text is not String return null', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'subtype': 'heading',
|
||||||
|
'heading': 123,
|
||||||
|
};
|
||||||
|
expect(attribute.heading, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('heading - subtype is not "heading" return null', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'subtype': 'code',
|
||||||
|
'heading': 'Hello World!',
|
||||||
|
};
|
||||||
|
expect(attribute.heading, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('quote', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'quote': 'quote text',
|
||||||
|
};
|
||||||
|
expect(attribute.quote, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('number - int', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'number': 99,
|
||||||
|
};
|
||||||
|
expect(attribute.number, 99);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('number - double', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'number': 12.34,
|
||||||
|
};
|
||||||
|
expect(attribute.number, 12.34);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('number - return null', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'code': 12.34,
|
||||||
|
};
|
||||||
|
expect(attribute.number, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('code', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'code': true,
|
||||||
|
};
|
||||||
|
expect(attribute.code, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('code - return false', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'quote': true,
|
||||||
|
};
|
||||||
|
expect(attribute.code, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('check', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'checkbox': true,
|
||||||
|
};
|
||||||
|
expect(attribute.check, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('check - return false', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'quote': true,
|
||||||
|
};
|
||||||
|
expect(attribute.check, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group('DeltaAttributesExtensions::', () {
|
||||||
|
test('bold', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'bold': true,
|
||||||
|
};
|
||||||
|
expect(attribute.bold, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('bold - return false', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'bold': 123,
|
||||||
|
};
|
||||||
|
expect(attribute.bold, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('italic', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'italic': true,
|
||||||
|
};
|
||||||
|
expect(attribute.italic, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('italic - return false', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'italic': 123,
|
||||||
|
};
|
||||||
|
expect(attribute.italic, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('underline', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'underline': true,
|
||||||
|
};
|
||||||
|
expect(attribute.underline, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('underline - return false', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'underline': 123,
|
||||||
|
};
|
||||||
|
expect(attribute.underline, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('strikethrough', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'strikethrough': true,
|
||||||
|
};
|
||||||
|
expect(attribute.strikethrough, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('strikethrough - return false', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'strikethrough': 123,
|
||||||
|
};
|
||||||
|
expect(attribute.strikethrough, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('color', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'color': '0xff212fff',
|
||||||
|
};
|
||||||
|
expect(attribute.color, const Color(0XFF212FFF));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('color - return null', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'color': 123,
|
||||||
|
};
|
||||||
|
expect(attribute.color, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('color - parse failure return white', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'color': 'hello123',
|
||||||
|
};
|
||||||
|
expect(attribute.color, const Color(0XFFFFFFFF));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('backgroundColor', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'backgroundColor': '0xff678fff',
|
||||||
|
};
|
||||||
|
expect(attribute.backgroundColor, const Color(0XFF678FFF));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('backgroundColor - return null', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'backgroundColor': 123,
|
||||||
|
};
|
||||||
|
expect(attribute.backgroundColor, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('backgroundColor - parse failure return white', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'backgroundColor': 'hello123',
|
||||||
|
};
|
||||||
|
expect(attribute.backgroundColor, const Color(0XFFFFFFFF));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('href', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'href': '/app/flowy',
|
||||||
|
};
|
||||||
|
expect(attribute.href, '/app/flowy');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('href - return null', () {
|
||||||
|
final Attributes attribute = {
|
||||||
|
'href': 123,
|
||||||
|
};
|
||||||
|
expect(attribute.href, null);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
import 'package:appflowy_editor/src/extensions/color_extension.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('ColorExtension::', () {
|
||||||
|
const white = Color(0XFFFFFFFF);
|
||||||
|
const black = Color(0XFF000000);
|
||||||
|
const blue = Color(0XFF000FFF);
|
||||||
|
const blueRgba = 'rgba(0, 15, 255, 255)';
|
||||||
|
test('ToRgbaString', () {
|
||||||
|
expect(blue.toRgbaString(), 'rgba(0, 15, 255, 255)');
|
||||||
|
expect(white.toRgbaString(), 'rgba(255, 255, 255, 255)');
|
||||||
|
expect(black.toRgbaString(), 'rgba(0, 0, 0, 255)');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('tryFromRgbaString', () {
|
||||||
|
final color = ColorExtension.tryFromRgbaString(blueRgba);
|
||||||
|
expect(color, const Color.fromARGB(255, 0, 15, 255));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('tryFromRgbaString - wrong rgba format return null', () {
|
||||||
|
const wrongRgba = 'abc(1,2,3,4)';
|
||||||
|
final color = ColorExtension.tryFromRgbaString(wrongRgba);
|
||||||
|
expect(color, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('tryFromRgbaString - wrong length return null', () {
|
||||||
|
const wrongRgba = 'rgba(0, 15, 255)';
|
||||||
|
final color = ColorExtension.tryFromRgbaString(wrongRgba);
|
||||||
|
expect(color, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('tryFromRgbaString - wrong values return null', () {
|
||||||
|
const wrongRgba = 'rgba(-12, 999, 1234, 619)';
|
||||||
|
final color = ColorExtension.tryFromRgbaString(wrongRgba);
|
||||||
|
expect(color, null);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
import 'dart:collection';
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:mockito/mockito.dart';
|
||||||
|
import 'package:appflowy_editor/src/extensions/node_extensions.dart';
|
||||||
|
|
||||||
|
class MockNode extends Mock implements Node {}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
final mockNode = MockNode();
|
||||||
|
|
||||||
|
group('NodeExtensions::', () {
|
||||||
|
final selection = Selection(
|
||||||
|
start: Position(path: [0]),
|
||||||
|
end: Position(path: [1]),
|
||||||
|
);
|
||||||
|
|
||||||
|
test('rect - renderBox is null', () {
|
||||||
|
when(mockNode.renderBox).thenReturn(null);
|
||||||
|
final result = mockNode.rect;
|
||||||
|
expect(result, Rect.zero);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('inSelection', () {
|
||||||
|
// I use an empty implementation instead of mock, because the mocked
|
||||||
|
// version throws error trying to access the path.
|
||||||
|
|
||||||
|
final subLinkedList = LinkedList<Node>()
|
||||||
|
..addAll([
|
||||||
|
Node(type: 'type', children: LinkedList(), attributes: {}),
|
||||||
|
Node(type: 'type', children: LinkedList(), attributes: {}),
|
||||||
|
Node(type: 'type', children: LinkedList(), attributes: {}),
|
||||||
|
Node(type: 'type', children: LinkedList(), attributes: {}),
|
||||||
|
Node(type: 'type', children: LinkedList(), attributes: {}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
final linkedList = LinkedList<Node>()
|
||||||
|
..addAll([
|
||||||
|
Node(
|
||||||
|
type: 'type',
|
||||||
|
children: subLinkedList,
|
||||||
|
attributes: {},
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
|
final node = Node(
|
||||||
|
type: 'type',
|
||||||
|
children: linkedList,
|
||||||
|
attributes: {},
|
||||||
|
);
|
||||||
|
final result = node.inSelection(selection);
|
||||||
|
expect(result, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/gestures.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:appflowy_editor/src/extensions/object_extensions.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('FlowyObjectExtensions::', () {
|
||||||
|
test('unwrapOrNull', () {
|
||||||
|
final result = const TextSpan().unwrapOrNull<HitTestTarget>();
|
||||||
|
assert(result is TextSpan);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('unwrapOrNull - return null', () {
|
||||||
|
final result = const TextSpan().unwrapOrNull<ServerSocket>();
|
||||||
|
expect(result, null);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('TextNodeExtension::', () {
|
||||||
|
test('description', () {});
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:appflowy_editor/src/extensions/text_style_extension.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('TextStyleExtensions::', () {
|
||||||
|
const style = TextStyle(
|
||||||
|
color: Colors.blue,
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
fontSize: 14,
|
||||||
|
height: 100,
|
||||||
|
wordSpacing: 2,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
);
|
||||||
|
|
||||||
|
const otherStyle = TextStyle(
|
||||||
|
color: Colors.red,
|
||||||
|
backgroundColor: Colors.black,
|
||||||
|
fontSize: 12,
|
||||||
|
height: 10,
|
||||||
|
wordSpacing: 1,
|
||||||
|
);
|
||||||
|
test('combine', () {
|
||||||
|
final result = style.combine(otherStyle);
|
||||||
|
expect(result.color, Colors.red);
|
||||||
|
expect(result.backgroundColor, Colors.black);
|
||||||
|
expect(result.fontSize, 12);
|
||||||
|
expect(result.height, 10);
|
||||||
|
expect(result.wordSpacing, 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('combine - return this', () {
|
||||||
|
final result = style.combine(null);
|
||||||
|
expect(result, style);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('combine - return null with inherit', () {
|
||||||
|
final styleCopy = otherStyle.copyWith(inherit: false);
|
||||||
|
final result = style.combine(styleCopy);
|
||||||
|
expect(result, styleCopy);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
import 'package:appflowy_editor/src/extensions/url_launcher_extension.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
test('safeLaunchUrl without scheme', () async {
|
||||||
|
const href = null;
|
||||||
|
final result = await safeLaunchUrl(href);
|
||||||
|
expect(result, false);
|
||||||
|
});
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user