apply nullsafety

This commit is contained in:
Chen Asraf
2021-07-30 23:56:19 +03:00
parent 5ee3643e37
commit 0ded1f48e8
21 changed files with 166 additions and 179 deletions

View File

@@ -1,17 +1,16 @@
import 'package:meta/meta.dart';
import 'dw_entity.dart';
class Alignment extends DWEntity {
/// Alignment name
String/*!*/ name;
String name;
/// Alignment description
String/*!*/ description;
String description;
Alignment({
String key,
@required this.name,
@required this.description,
String? key,
required this.name,
required this.description,
}) : super(key: key ?? DWEntity.generateKey(name));
factory Alignment.fromJSON(Map map) => Alignment(

View File

@@ -9,10 +9,10 @@ class Dice {
num sides;
// Modifier value for dice, can be added to `DiceResult` value
num modifier;
num? modifier;
// Last result rolled by this die
DiceResult lastResult;
DiceResult? lastResult;
/// Simple dice, with sides, die count and modifier.
/// You can multiply, add or subtract Dice objects to change the amount of rolls (notice dice must
@@ -28,7 +28,7 @@ class Dice {
static Dice d12 = Dice(12);
static Dice d20 = Dice(20);
Dice copyWith({int sides, int amount, int modifier}) => Dice(
Dice copyWith({int? sides, int? amount, int? modifier}) => Dice(
sides ?? this.sides,
amount ?? this.amount,
modifier ?? this.modifier,
@@ -45,6 +45,7 @@ class Dice {
@override
String toString() =>
// ignore: unnecessary_brace_in_string_interps
'${amount}d${sides}${modifier != null && modifier != 0 ? modRepr : ''}';
Dice operator *(obj) {
@@ -125,7 +126,7 @@ class Dice {
DiceResult getRoll() {
var results = <num>[];
for (num i = 0; i < amount; i++) {
results.add(Random().nextInt(sides) + 1);
results.add(Random().nextInt(sides as int) + 1);
}
return lastResult = DiceResult(this, results);
}
@@ -143,7 +144,7 @@ class Dice {
return results;
}
String get modRepr => (modifier > 0 ? '+' : '') + modifier.toString();
String get modRepr => ((modifier ?? 0) > 0 ? '+' : '') + modifier.toString();
}
class DiceResult {
@@ -161,19 +162,20 @@ class DiceResult {
// More detailed version of `toString`.
String get toDetailedString =>
'$dice${didHitNaturalMax ? '*' : ''} => $total\n $mappedResults\n ${didHitNaturalMax ? "Die no. ${indexOfNaturalMax} hit 20" : "Didn\'t hit 20"}';
'$dice${didHitNaturalMax ? '*' : ''} => $total\n $mappedResults\n ${didHitNaturalMax ? "Die no. $indexOfNaturalMax hit 20" : "Didn\'t hit 20"}';
// All results layed out with their respective die.
String get mappedResults {
var out = <String>[];
for (num i = 0; i < results.length; i++) {
out.add('${i + 1}: ${results[i]}');
out.add('${i + 1}: ${results[i as int]}');
}
return out.toString() + (dice.modifier != 0 ? ' (${dice.modRepr})' : '');
}
/// Total (accumulated) value of result, including modifiers.
num get total => results.reduce((tot, cur) => tot + cur) + dice.modifier;
num get total =>
results.reduce((tot, cur) => tot + cur) + (dice.modifier ?? 0);
// Boolean that represents whether any of the rolled dice hit their natural max value (e.g. 20 for d20)
bool get didHitNaturalMax => results.any((r) => r == dice.sides);

View File

@@ -1,27 +1,26 @@
import 'package:meta/meta.dart';
import 'dw_entity.dart';
import 'tag.dart';
import 'mappers.dart';
class Equipment extends DWEntity {
/// Equipment name
String/*!*/ name;
String name;
/// Equipment name, in plural
String pluralName;
/// Item description
String/*!*/ description;
String? description;
/// Equipment tags
List<Tag/*!*/> tags;
List<Tag> tags;
Equipment({
String key,
@required this.name,
String pluralName,
@required this.description,
@required this.tags,
String? key,
required this.name,
String? pluralName,
this.description,
required this.tags,
}) : pluralName = pluralName ?? _calcPluralName(name),
super(key: key ?? DWEntity.generateKey(name));
@@ -33,7 +32,7 @@ class Equipment extends DWEntity {
name: map['name'],
pluralName: map['plural_name'],
description: map['description'],
tags: listMapper(map['tags'], (i) => Tag.fromJSON(i)),
tags: listMapper(map['tags'], (dynamic i) => Tag.fromJSON(i)),
);
@override

View File

@@ -1,19 +1,18 @@
import 'package:dungeon_world_data/tag.dart';
import 'package:meta/meta.dart';
import 'dw_entity.dart';
import 'mappers.dart';
class GearChoice extends DWEntity {
/// Description of choices, possibly with other benefits to the stats.
String/*!*/ label;
String label;
/// The list of options to choose from. `label` should specify how many to choose.
List<GearOption/*!*/> gearOptions;
List<GearOption> gearOptions;
GearChoice({
String key,
@required this.label,
@required this.gearOptions,
String? key,
required this.label,
required this.gearOptions,
}) : super(key: key);
factory GearChoice.fromJSON(Map map) => GearChoice(
@@ -36,19 +35,19 @@ class GearChoice extends DWEntity {
class GearOption extends DWEntity {
// String key;
String/*!*/ name;
List<Tag/*!*/>/*!*/ tags;
String name;
List<Tag> tags;
GearOption({
String key,
@required this.name,
@required this.tags,
String? key,
required this.name,
required this.tags,
}) : super(key: key ?? DWEntity.generateKey(name));
factory GearOption.fromJSON(Map map) => GearOption(
key: map['key'],
name: map['name'],
tags: listMapper(map['tags'], (t) => Tag.fromJSON(t)),
tags: listMapper(map['tags'], (dynamic t) => Tag.fromJSON(t)),
);
factory GearOption.parse(dynamic str) {
@@ -56,9 +55,9 @@ class GearOption extends DWEntity {
return GearOption.fromJSON(str);
}
final num openParen = str.indexOf('(');
final num closeParen = str.indexOf(')');
final num? closeParen = str.indexOf(')');
final name = str.substring(0, openParen > -1 ? openParen : null);
final rawTags = openParen > -1 && closeParen > -1
final rawTags = openParen > -1 && closeParen! > -1
? str.substring(openParen + 1, closeParen)
: '';
final tags = rawTags.isNotEmpty

View File

@@ -7,16 +7,18 @@ import 'monster.dart';
import 'player_class.dart';
import 'tag.dart';
List<R/*!*/> listMapper<T, R, A>(List<T> lst, R Function(A obj) mapper) =>
List<R> listMapper<T, R, A>(List<T>? lst, R Function(A obj) mapper) =>
lst != null && lst.isNotEmpty
? List.from(lst).map<R>((obj) => obj is A ? mapper(obj) : null).toList()
? (List<A>.from(lst.where((obj) => obj != null && obj is A))
.map<R>((obj) => mapper(obj))
.toList())
: <R>[];
Map<K, V/*!*/> mapMapper<K, V>(
Map map, MapEntry<K, V/*!*/> Function(dynamic key, dynamic obj) mapper) =>
Map<K, V> mapMapper<K, V>(
Map? map, MapEntry<K, V> Function(dynamic key, dynamic obj) mapper) =>
map != null ? Map.from(map).map<K, V>(mapper) : {};
List<Move/*!*/> moveListMapper(List lst) => lst == null || lst.isEmpty
List<Move> moveListMapper(List? lst) => lst == null || lst.isEmpty
? <Move>[]
: listMapper<Map, Move, dynamic>(
List<Map>.from(lst), (v) => Move.fromJSON(v));
@@ -29,33 +31,33 @@ Map<String, PlayerClass> classMapper(Map map) => mapMapper(
(k, v) =>
MapEntry<String, PlayerClass>(k.toString(), PlayerClass.fromJSON(v)));
Map<String, List<String/*!*/>/*!*/> nameMapper(Map map) =>
Map<String, List<String>> nameMapper(Map? map) =>
mapMapper<String, List<String>>(
map,
(k, v) => MapEntry<String, List<String>>(k.toString(),
listMapper<dynamic, String, dynamic>(v, (j) => j.toString())));
List<List<String>> looksMapper(List lst) =>
listMapper(lst, (i) => listMapper(i, (j) => j.toString()));
List<List<String>> looksMapper(List? lst) =>
listMapper(lst, (dynamic i) => listMapper(i, (dynamic j) => j.toString()));
Map<String, Alignment> alignmentsMapper(Map map) => mapMapper(map,
Map<String, Alignment> alignmentsMapper(Map? map) => mapMapper(map,
(k, v) => MapEntry<String, Alignment>(k.toString(), Alignment.fromJSON(v)));
List<GearChoice> gearChoiceMapper(List lst) =>
listMapper(lst, (v) => GearChoice.fromJSON(v));
List<GearChoice> gearChoiceMapper(List? lst) =>
listMapper(lst, (dynamic v) => GearChoice.fromJSON(v));
List<GearOption> gearOptionMapper(List lst) =>
listMapper(lst, (v) => GearOption.parse(v));
List<GearOption> gearOptionMapper(List? lst) =>
listMapper(lst, (dynamic v) => GearOption.parse(v));
Map<String, Equipment> equipmentMapper(Map map) => mapMapper(map,
(k, v) => MapEntry<String, Equipment>(k.toString(), Equipment.fromJSON(v)));
List<Spell> spellsMapper(List lst) {
List<Spell> spellsMapper(List? lst) {
if (lst == null) {
return [];
}
return listMapper(lst, (v) => Spell.fromJSON(v));
return listMapper(lst, (dynamic v) => Spell.fromJSON(v));
}
Map<String, Monster> monsterMapper(Map map) => mapMapper(map,

View File

@@ -1,44 +1,43 @@
import 'package:meta/meta.dart';
import 'dw_entity.dart';
import 'tag.dart';
import 'mappers.dart';
class Monster extends DWEntity {
/// Monster name
String /*!*/ name;
String name;
/// Monster description
String /*!*/ description;
String description;
/// Monster instinct
String /*!*/ instinct;
String instinct;
/// Monster tags
List<Tag/*!*/> tags;
List<Tag> tags;
/// Monster moves
List<String/*!*/> moves;
List<String> moves;
Monster({
String key,
@required this.name,
@required this.description,
@required this.instinct,
@required this.tags,
@required this.moves,
String? key,
required this.name,
required this.description,
required this.instinct,
required this.tags,
required this.moves,
}) : super(key: key ?? DWEntity.generateKey(name));
@override
String toString() =>
'$name\n tags: $tags,\n moves: ${moves}\n instinct: $instinct';
'$name\n tags: $tags,\n moves: $moves\n instinct: $instinct';
static Monster fromJSON(Map map) => Monster(
key: map['key'],
name: map['name'],
description: map['description'],
instinct: map['instinct'],
tags: listMapper(map['tags'], (i) => Tag.fromJSON(i)),
moves: listMapper(map['moves'], (i) => i.toString()));
tags: listMapper(map['tags'], (dynamic i) => Tag.fromJSON(i)),
moves: listMapper(map['moves'], (dynamic i) => i.toString()));
@override
Map toJSON() {

View File

@@ -1,34 +1,33 @@
import 'package:meta/meta.dart';
import 'dw_entity.dart';
import 'mappers.dart';
class Move extends DWEntity {
/// Move name
String/*!*/ name;
String name;
/// Move description
String/*!*/ description;
String description;
/// Move explanation
String/*!*/ explanation;
String? explanation;
/// Classes that can use this move.
/// The keys correspond to the `PlayerClass` key.
List<String/*!*/> classes;
List<String> classes;
Move({
String key,
@required this.name,
@required this.description,
@required this.explanation,
@required this.classes,
String? key,
required this.name,
required this.description,
this.explanation,
required this.classes,
}) : super(key: key ?? DWEntity.generateKey(name));
factory Move.fromJSON(Map map) => Move(
key: map['key'],
name: map['name'],
classes: map['classes'] != null
? listMapper(map['classes'], (j) => j.toString())
? listMapper(map['classes'], (dynamic j) => j.toString())
: [],
description: map['description'],
explanation: map['explanation'],

View File

@@ -1,4 +1,3 @@
import 'package:meta/meta.dart';
import 'alignment.dart';
import 'dice.dart';
import 'dw_entity.dart';
@@ -9,67 +8,67 @@ import 'gear_choice.dart';
class PlayerClass extends DWEntity {
/// Class name
String /*!*/ name;
String name;
/// Class description
String /*!*/ description;
String description;
/// Base max. weight load, without the +STR.
num /*!*/ load;
num load;
/// Base HP
num /*!*/ baseHP;
num baseHP;
/// Hit die
Dice /*!*/ damage;
Dice damage;
/// Character name options, mapped by race
Map<String, List<String /*!*/ > /*!*/ > names;
Map<String, List<String>> names;
/// Class Bonds
List<String /*!*/ > bonds;
List<String> bonds;
/// Character look options
List<List<String /*!*/ > /*!*/ > looks;
List<List<String>> looks;
/// Character alignment options. Map of `Alignment.key` => `Alignment`
Map<String, Alignment> alignments;
/// Race moves
List<Move /*!*/ > raceMoves;
List<Move> raceMoves;
/// Starting moves
List<Move /*!*/ > startingMoves;
List<Move> startingMoves;
/// Starting moves
List<Move /*!*/ > advancedMoves1;
List<Move> advancedMoves1;
/// Starting moves
List<Move /*!*/ > advancedMoves2;
List<Move> advancedMoves2;
/// Spells
List<Spell /*!*/ > spells;
List<Spell> spells;
/// Gear choices
List<GearChoice /*!*/ > gearChoices;
List<GearChoice> gearChoices;
PlayerClass({
String key,
@required this.name,
@required this.description,
@required this.load,
@required this.baseHP,
@required this.damage,
@required this.names,
@required this.bonds,
@required this.looks,
@required this.alignments,
@required this.raceMoves,
@required this.startingMoves,
@required this.advancedMoves1,
@required this.advancedMoves2,
@required this.spells,
@required this.gearChoices,
String? key,
required this.name,
required this.description,
required this.load,
required this.baseHP,
required this.damage,
required this.names,
required this.bonds,
required this.looks,
required this.alignments,
required this.raceMoves,
required this.startingMoves,
required this.advancedMoves1,
required this.advancedMoves2,
required this.spells,
required this.gearChoices,
}) : super(key: key ?? DWEntity.generateKey(name));
/// Combined list of `advancedMoves1` and `advancedMoves2`
@@ -92,7 +91,7 @@ class PlayerClass extends DWEntity {
baseHP: map['base_hp'],
damage: Dice.parse(map['damage']),
names: nameMapper(map['names']),
bonds: listMapper(map['bonds'], (j) => j.toString()),
bonds: listMapper(map['bonds'], (dynamic j) => j.toString()),
looks: looksMapper(map['looks']),
alignments: alignmentsMapper(map['alignments']),
raceMoves: moveListMapper(map['race_moves']),
@@ -114,8 +113,8 @@ class PlayerClass extends DWEntity {
'names': names,
'bonds': bonds,
'looks': looks,
'alignments': mapMapper<String, Map /*!*/ >(
alignments, (k, v) => MapEntry(k, v.toJSON())),
'alignments':
mapMapper(alignments, ((k, v) => MapEntry(k, v.toJSON()))),
'race_moves':
listMapper<Move, Map, Move>(raceMoves, (move) => move.toJSON()),
'starting_moves':
@@ -124,7 +123,7 @@ class PlayerClass extends DWEntity {
advancedMoves1, (move) => move.toJSON()),
'advanced_moves_2': listMapper<Move, Map, Move>(
advancedMoves2, (move) => move.toJSON()),
'spells': listMapper(spells, (v) => v.toJSON()),
'spells': listMapper(spells, (dynamic v) => v.toJSON()),
'gear_choices': listMapper<GearChoice, Map, GearChoice>(
gearChoices, (choice) => choice.toJSON()),
};

View File

@@ -1,27 +1,26 @@
import 'package:meta/meta.dart';
import 'dw_entity.dart';
import 'mappers.dart';
import 'tag.dart';
class Spell extends DWEntity {
/// Spell name
String/*!*/ name;
String name;
/// Spell description
String/*!*/ description;
String description;
/// Spell level
String level;
/// Spell tags
List<Tag/*!*/> tags;
List<Tag> tags;
Spell({
String key,
@required this.name,
@required this.description,
@required this.level,
@required this.tags,
String? key,
required this.name,
required this.description,
required this.level,
required this.tags,
}) : super(key: key ?? DWEntity.generateKey(name));
static Spell fromJSON(Map map) => Spell(
@@ -29,7 +28,7 @@ class Spell extends DWEntity {
name: map['name'],
description: map['description'],
level: map['level'].toString(),
tags: listMapper(map['tags'], (i) => Tag.fromJSON(i)),
tags: listMapper(map['tags'], (dynamic i) => Tag.fromJSON(i)),
);
@override

View File

@@ -1,9 +1,9 @@
part of '_dungeon_world_data.dart';
abstract class DWEntity {
String key;
String? key;
DWEntity({String key}) {
DWEntity({String? key}) {
this.key = key ?? DWEntity.generateKey(null);
}
@@ -13,7 +13,7 @@ abstract class DWEntity {
/// and turned to lowercase.
///
/// Otherwise, a `Uuid().v4()` is generated for it.
static String generateKey(String identifier) =>
static String generateKey(String? identifier) =>
identifier != null && identifier.trim().isNotEmpty
? identifier
.trim()
@@ -36,10 +36,9 @@ abstract class DWEntity {
DWEntity copy();
/// Helper method for getting any `DWEntity` by its key.
static T getByKey<T extends DWEntity>(String key, Iterable<T> list) =>
list.firstWhere(
static T? getByKey<T extends DWEntity>(String key, Iterable<T> list) =>
list.firstWhereOrNull(
(element) => element.key == key,
orElse: () => null,
);
}

View File

@@ -5969,14 +5969,6 @@ void initData() {
'Bring their word into abundance'
],
));
monsterList.add(Monster(
key: '4155de98-1286-46c8-a872-8a2545093d81',
name: null,
description: null,
instinct: null,
tags: [],
moves: [],
));
basicMovesList.add(Move(
key: 'hack_slash',
name: 'Hack & Slash',

View File

@@ -1,3 +1,4 @@
import 'package:collection/collection.dart' show IterableExtension;
import 'package:quiver/core.dart';
import 'package:uuid/uuid.dart';
import '../tag.dart';
@@ -20,40 +21,38 @@ part '_homebrew.dart';
const String VERSION = '2.0.0';
class DungeonWorldData {
/*late*/ Map<String, dynamic> _raw;
late Map<String, dynamic> _raw;
/// Raw data
Map<String, dynamic> get raw {
_raw ??= toJSON();
return _raw;
}
Map<String, dynamic> get raw => _raw;
/// Basic moves
/*late*/ List<Move> basicMoves;
late List<Move> basicMoves;
/// Special moves
/*late*/ List<Move> specialMoves;
late List<Move> specialMoves;
/// Classes
/*late*/ List<PlayerClass> classes;
late List<PlayerClass> classes;
/// Equipment
/*late*/ List<Equipment> equipment;
late List<Equipment> equipment;
/// Spells
/*late*/ List<Spell> spells;
late List<Spell> spells;
/// Monsters
/*late*/ List<Monster> monsters;
late List<Monster> monsters;
/// Tags
/*late*/ List<Tag> tags;
late List<Tag> tags;
/// Current version of data, corresponds to same version of https://www.npmjs.com/package/dungeonworld-data
final String version = VERSION;
DungeonWorldData() {
_initFromData();
_raw = toJSON();
}
void _initFromData() {
@@ -92,5 +91,5 @@ class DungeonWorldData {
list.map((v) => MapEntry<String, T>(key(v), v)),
);
static String entryKey(DWEntity item) => item.key /*!*/;
static String entryKey(DWEntity item) => item.key!;
}

View File

@@ -1,23 +1,23 @@
import 'dw_entity.dart';
class Tag<T> extends DWEntity {
static Map<String, String /*!*/ > tagInfoCache = {};
static Map<String, String > tagInfoCache = {};
/// Tag or feature name
String /*!*/ name;
String name;
/// Value, if applicable
T value;
T? value;
String description;
String? description;
Tag(this.name, [this.value, this.description]) : super(key: name) {
if (description != null &&
description.isNotEmpty &&
description!.isNotEmpty &&
!tagInfoCache.containsKey(key)) {
tagInfoCache[key] = description;
tagInfoCache[key] = description!;
} else if (description == null ||
description.isEmpty && tagInfoCache.containsKey(key)) {
description!.isEmpty && tagInfoCache.containsKey(key)) {
description = tagInfoCache[key];
}
}
@@ -39,16 +39,16 @@ class Tag<T> extends DWEntity {
var amountThenName = RegExp('([0-9]+)\\s(.*)');
if (amountThenName.hasMatch(obj)) {
var match = amountThenName.allMatches(obj).toList().first;
var name = match.group(2);
var value = int.tryParse(match.group(1));
var name = match.group(2)!;
var value = int.tryParse(match.group(1)!);
return Tag(name, value as dynamic);
}
var mapLike = RegExp('\\{(.*):\\s?([+-]?[0-9]+)\\}');
if (mapLike.hasMatch(obj)) {
var match = mapLike.allMatches(obj).toList().first;
var name = match.group(1);
var value = int.tryParse(match.group(2));
var name = match.group(1)!;
var value = int.tryParse(match.group(2)!);
return Tag(name, value as dynamic);
}
}

View File

@@ -51,7 +51,7 @@ packages:
source: hosted
version: "0.3.3"
collection:
dependency: transitive
dependency: "direct main"
description:
name: collection
url: "https://pub.dartlang.org"

View File

@@ -5,12 +5,13 @@ description: Data dump of Dungeon World classes, moves, equipment, and more.
version: 2.0.5+10
environment:
sdk: ">=2.11.0 <3.0.0"
sdk: ">=2.12.0 <3.0.0"
dependencies:
meta: ^1.1.0
quiver: ^3.0.1
uuid: ^3.0.4
collection: ^1.15.0-nullsafety.4
dev_dependencies:
flutter_lints: ^1.0.4

View File

@@ -33,9 +33,9 @@ void main() async {
.join('\n');
print('Writing string');
var str = '''
${arraysImports}
$arraysImports
void initData() {
${arrayFills}
$arrayFills
}
''';
var file = File(join(Directory.current.path, 'output.dart'));

View File

@@ -4,7 +4,7 @@ String dumpClass<T extends DWEntity>(
String className, T obj, String Function(T) parser,
{bool includeKey = true}) {
return """
${className}(${includeKey && obj.key != null ? "key: ${parseValue(obj.key)}, " : ""}${parser(obj).trim()})
$className(${includeKey && obj.key != null ? "key: ${parseValue(obj.key)}, " : ""}${parser(obj).trim()})
""";
}
@@ -29,7 +29,7 @@ String parseTag(Tag tag) {
}
String parseTagsArray(List<Tag> list) {
return parseArray('Tag', list.where((t) => t != null), parseTag);
return parseArray('Tag', list, parseTag);
}
String parseDice(Dice dice) {
@@ -65,7 +65,7 @@ String Function(Tag) parseInfoTags = createClassParser<Tag>(
includeKey: false,
);
String Function(Alignment/*!*/) parseAlignment = createClassParser<Alignment>(
String Function(Alignment) parseAlignment = createClassParser<Alignment>(
'Alignment',
(i) => '''
name: ${parseValue(i.name)},
@@ -91,7 +91,7 @@ String Function(PlayerClass) parsePlayerClass = createClassParser<PlayerClass>(
damage: ${parseDice(i.damage)},
names: ${i.names.map((r, s) => MapEntry(parseValue(r), parseArray('String', s, parseValue)))},
bonds: ${parseArray('String', i.bonds, parseValue)},
looks: ${parseArray('List<String>', i.looks, (s) => parseArray('String', s, parseValue))},
looks: ${parseArray('List<String>', i.looks, (dynamic s) => parseArray('String', s, parseValue))},
alignments: ${i.alignments.map((k, v) => MapEntry(parseValue(v.name), parseAlignment(v)))},
raceMoves: ${parseArray('Move', i.raceMoves, parseMove)},
startingMoves: ${parseArray('Move', i.startingMoves, parseMove)},
@@ -152,7 +152,7 @@ class ParseDef<T> {
String get file => _file;
String get arrayName => _arrayName;
ParseDef(this.name, this.list, this.parser, {String file, String arrayName})
ParseDef(this.name, this.list, this.parser, {String? file, String? arrayName})
: _file = file ?? _fileFromName(name),
_arrayName = arrayName ?? _arrayNameFromName(name);
@@ -166,7 +166,7 @@ class ParseDef<T> {
static String _fileFromName(String name) =>
name
.splitMapJoin(RegExp('([A-Z])'),
onMatch: (match) => '_' + match.group(1).toLowerCase(),
onMatch: (match) => '_' + match.group(1)!.toLowerCase(),
onNonMatch: (i) => i)
.substring(1) +
'.dart';

View File

@@ -1,12 +1,11 @@
import 'package:meta/meta.dart';
import 'package:test/test.dart';
import 'package:dungeon_world_data/dw_data.dart';
class Test1 extends DWEntity {
final int value;
Test1({
String key,
@required this.value,
String? key,
required this.value,
}) : super(key: key);
@override

View File

@@ -4,7 +4,7 @@ import 'package:dungeon_world_data/dw_data.dart';
void main() {
group('Equipment', () {
test('Key', () {
var equipment = DWEntity.getByKey('tricksy_rope', dungeonWorld.equipment);
var equipment = DWEntity.getByKey('tricksy_rope', dungeonWorld.equipment)!;
expect(equipment.key, equals('tricksy_rope'));
});
});

View File

@@ -4,7 +4,7 @@ import 'package:dungeon_world_data/dw_data.dart';
void main() {
group('PlayerClass', () {
test('Key', () {
var paladin = DWEntity.getByKey('paladin', dungeonWorld.classes);
var paladin = DWEntity.getByKey('paladin', dungeonWorld.classes)!;
expect(paladin.key, equals('paladin'));
});
});

View File

@@ -4,12 +4,12 @@ import 'package:dungeon_world_data/dw_data.dart';
void main() {
group('Spells', () {
test('Key', () {
var equipment = DWEntity.getByKey('plague', dungeonWorld.spells);
var equipment = DWEntity.getByKey('plague', dungeonWorld.spells)!;
expect(equipment.key, equals('plague'));
});
test('toJSON', () {
var equipment = DWEntity.getByKey('plague', dungeonWorld.spells);
var equipment = DWEntity.getByKey('plague', dungeonWorld.spells)!;
expect(equipment.toJSON()['tags'], contains('ongoing'));
var json = equipment.toJSON();
expect(json['key'], equals('plague'));