Skip to content
This repository has been archived by the owner on May 28, 2024. It is now read-only.

Commit

Permalink
Add ImageButtonPlayer
Browse files Browse the repository at this point in the history
Signed-off-by: Leandro Lucarella <[email protected]>
  • Loading branch information
llucax committed Feb 18, 2021
1 parent 5d53ef7 commit adce590
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 1 deletion.
6 changes: 5 additions & 1 deletion lib/src/button_player.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import 'package:flutter/material.dart' hide Action;

import 'package:lunofono_bundle/lunofono_bundle.dart'
show Action, Button, Color, StyledButton;
show Action, Button, Color, StyledButton, ImageButton;
import 'package:lunofono_player/src/button_player/image_button_player.dart';

import 'action_player.dart' show ActionPlayer;
import 'button_player/image_button_player.dart' show ImageButtonPlayer;
import 'button_player/styled_button_player.dart' show StyledButtonPlayer;
import 'dynamic_dispatch_registry.dart' show DynamicDispatchRegistry;

Expand All @@ -15,6 +17,8 @@ void _registerBuiltin(ButtonPlayerRegistry registry) {
// New wrappers should be registered here
registry.register(
StyledButton, (button) => StyledButtonPlayer(button as StyledButton));
registry.register(
ImageButton, (button) => ImageButtonPlayer(button as ImageButton));
}

/// A wrapper to manage how a [Button] is played by the player.
Expand Down
49 changes: 49 additions & 0 deletions lib/src/button_player/image_button_player.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import 'package:flutter/material.dart';

import 'package:lunofono_bundle/lunofono_bundle.dart'
show Button, Color, ImageButton;

import '../button_player.dart' show ButtonPlayer;

/// A wrapper to play a [ImageButton].
class ImageButtonPlayer extends ButtonPlayer {
/// The underlaying model's [Button].
@override
final ImageButton button;

/// Constructs a [ButtonPlayer] using [button] as the underlaying [Button].
ImageButtonPlayer(this.button)
: assert(button != null),
super(button);

/// The background [Color] of the underlaying [button].
///
/// TODO: This is very hacky and should be removed.
/// https://github.com/lunofono/lunofono_player/issues/25
@override
Color get backgroundColor => Colors.white;

/// The location of the image of the underlaying [button].
Uri get imageUri => button.imageUri;

@override
Widget build(BuildContext context) =>
ImageButtonWidget(button: this, key: ObjectKey(button));
}

/// A widget to display a [ImageButton].
class ImageButtonWidget extends StatelessWidget {
/// The button to display.
final ImageButtonPlayer button;

/// Creates a new [ImageButtonWidget] to display [button].
const ImageButtonWidget({@required this.button, Key key})
: assert(button != null),
super(key: key);

@override
Widget build(BuildContext context) => GestureDetector(
onTap: () => button.action.act(context, button),
child: Image.asset(button.imageUri.toString()),
);
}
108 changes: 108 additions & 0 deletions test/unit/button_player/image_button_player_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
@Tags(['unit', 'player'])

import 'package:flutter/material.dart' hide Action;

import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';

import 'package:lunofono_bundle/lunofono_bundle.dart' show Action, ImageButton;

import 'package:lunofono_player/src/action_player.dart';
import 'package:lunofono_player/src/button_player.dart';

import 'package:lunofono_player/src/button_player/image_button_player.dart';

import '../../util/test_asset_bundle.dart' show TestAssetBundle;

class FakeAction extends Action {
final actCalls = <ButtonPlayer>[];
}

class FakeActionPlayer extends ActionPlayer {
@override
final FakeAction action;
@override
void act(BuildContext context, ButtonPlayer button) =>
action.actCalls.add(button);
FakeActionPlayer(this.action) : assert(action != null);
}

class FakeContext extends Fake implements BuildContext {}

void main() {
final imageUri = Uri.parse('assets/10x10-red.png');
final oldActionRegistry = ActionPlayer.registry;

setUp(() {
ActionPlayer.registry = ActionPlayerRegistry();
ActionPlayer.registry
.register(FakeAction, (a) => FakeActionPlayer(a as FakeAction));
});

tearDown(() => ActionPlayer.registry = oldActionRegistry);

group('ImageButtonPlayer', () {
FakeContext fakeContext;

setUp(() {
fakeContext = FakeContext();
});

test('constructor asserts on null', () {
expect(() => ImageButtonPlayer(null), throwsAssertionError);
});

test('build creates a ImageButtonWidget', () {
final button = ImageButton(FakeAction(), imageUri);
final buttonPlayer = ButtonPlayer.wrap(button);
expect(buttonPlayer.button, same(button));
expect((buttonPlayer as ImageButtonPlayer).imageUri, button.imageUri);
final widget = buttonPlayer.build(fakeContext);
expect(widget.key, ObjectKey(button));
});
});

group('ImageButtonWidget', () {
test('constructor asserts on null button', () {
expect(() => ImageButtonWidget(button: null), throwsAssertionError);
});

testWidgets('tapping calls action.act()', (tester) async {
final action = FakeAction();
final button = ImageButton(action, imageUri);
final buttonPlayer = ButtonPlayer.wrap(button);
Widget widget;
await tester.pumpWidget(
MaterialApp(
home: DefaultAssetBundle(
bundle: TestAssetBundle(),
child: Builder(builder: (context) {
widget = buttonPlayer.build(context);
return widget;
}),
),
),
);
expect(widget.key, ObjectKey(button));
expect(widget, isA<ImageButtonWidget>());
expect((widget as ImageButtonWidget).button, same(buttonPlayer));
expect(action.actCalls.length, 0);
final buttonFinder = find.byKey(ObjectKey(button));
expect(buttonFinder, findsOneWidget);
final imageFinder = find.byType(Image);
expect(imageFinder, findsOneWidget);

// tap the button should call button.act()
await tester.tap(buttonFinder);
await tester.pump();
expect(action.actCalls.length, 1);
expect(action.actCalls.last, buttonPlayer);

// tap the image should call button.act()
await tester.tap(imageFinder);
await tester.pump();
expect(action.actCalls.length, 2);
expect(action.actCalls.last, buttonPlayer);
});
});
}

0 comments on commit adce590

Please sign in to comment.