Skip to content

Commit

Permalink
Merge pull request #75 from tsimbalar/feat-shadows
Browse files Browse the repository at this point in the history
Introduce GoldenToolkitConfiguration.enableRealShadows
  • Loading branch information
coreysprague authored Nov 9, 2020
2 parents 96411b2 + 90cb227 commit 09de7fe
Show file tree
Hide file tree
Showing 10 changed files with 189 additions and 2 deletions.
16 changes: 14 additions & 2 deletions packages/golden_toolkit/lib/src/configuration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,15 @@ class GoldenToolkitConfiguration {
/// [deviceFileNameFactory] a func used to decide the final filename for multiScreenGolden() invocations
///
/// [primeAssets] a func that is used to ensure that all images have been decoded before trying to render
///
/// [enableRealShadows] a flag indicating that we want the goldens to have real shadows (instead of opaque shadows)
GoldenToolkitConfiguration({
this.skipGoldenAssertion = _doNotSkip,
this.fileNameFactory = defaultFileNameFactory,
this.deviceFileNameFactory = defaultDeviceFileNameFactory,
this.primeAssets = defaultPrimeAssets,
this.defaultDevices = const [Device.phone, Device.tabletLandscape],
this.enableRealShadows = false,
}) : assert(defaultDevices != null && defaultDevices.isNotEmpty);

/// a function indicating whether a golden assertion should be skipped
Expand All @@ -111,13 +114,19 @@ class GoldenToolkitConfiguration {
/// the default set of devices to use for multiScreenGolden assertions
final List<Device> defaultDevices;

/// whether shadows should have the real rendering
/// by default, Widget tests use opaque shadows to avoid golden test failures
/// See [debugDisableShadows] for more context
final bool enableRealShadows;

/// Copies the configuration with the given values overridden.
GoldenToolkitConfiguration copyWith({
SkipGoldenAssertion skipGoldenAssertion,
FileNameFactory fileNameFactory,
DeviceFileNameFactory deviceFileNameFactory,
PrimeAssets primeAssets,
List<Device> defaultDevices,
bool enableRealShadows,
}) {
return GoldenToolkitConfiguration(
skipGoldenAssertion: skipGoldenAssertion ?? this.skipGoldenAssertion,
Expand All @@ -126,6 +135,7 @@ class GoldenToolkitConfiguration {
deviceFileNameFactory ?? this.deviceFileNameFactory,
primeAssets: primeAssets ?? this.primeAssets,
defaultDevices: defaultDevices ?? this.defaultDevices,
enableRealShadows: enableRealShadows ?? this.enableRealShadows,
);
}

Expand All @@ -138,7 +148,8 @@ class GoldenToolkitConfiguration {
fileNameFactory == other.fileNameFactory &&
deviceFileNameFactory == other.deviceFileNameFactory &&
primeAssets == other.primeAssets &&
defaultDevices == other.defaultDevices;
defaultDevices == other.defaultDevices &&
enableRealShadows == other.enableRealShadows;
}

@override
Expand All @@ -147,7 +158,8 @@ class GoldenToolkitConfiguration {
fileNameFactory.hashCode ^
deviceFileNameFactory.hashCode ^
primeAssets.hashCode ^
defaultDevices.hashCode;
defaultDevices.hashCode ^
enableRealShadows.hashCode;
}

bool _doNotSkip() => false;
Expand Down
5 changes: 5 additions & 0 deletions packages/golden_toolkit/lib/src/testing_tools.dart
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,14 @@ void testGoldens(
return GoldenToolkit.runWithConfiguration(() async {
_inGoldenTest = true;
tester.binding.addTime(const Duration(seconds: 10));
final initialDebugDisableShadowsValue = debugDisableShadows;
final shouldUseRealShadows =
GoldenToolkit.configuration.enableRealShadows;
debugDisableShadows = !shouldUseRealShadows;
try {
await test(tester);
} finally {
debugDisableShadows = initialDebugDisableShadowsValue;
_inGoldenTest = false;
}
}, config: config);
Expand Down
51 changes: 51 additions & 0 deletions packages/golden_toolkit/test/configuration_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:golden_toolkit/golden_toolkit.dart';

import 'sample_widgets.dart';

void main() {
group('GoldenToolkitConfiguration Tests', () {
testGoldens(
Expand Down Expand Up @@ -173,6 +175,40 @@ void main() {
);
});

group('Shadows', () {
GoldenToolkit.runWithConfiguration(
() {
testGoldens(
'screenMatchesGolden method uses enableRealShadows from global configuration when GoldenToolkit.runWithConfiguration is outside testGoldens',
(tester) async {
await tester.pumpWidgetBuilder(WidgetWithShadows());
await screenMatchesGolden(
tester, 'enableRealShadows_honored_when_testGoldens_wrapped');

expect(debugDisableShadows, isFalse,
reason: 'debugDisableShadows should be false during this test');
});
},
config: GoldenToolkit.configuration.copyWith(enableRealShadows: true),
);

testGoldens(
'screenMatchesGolden method does not use enableRealShadows from global configuration when GoldenToolkit.runWithConfiguration is inside testGoldens',
(tester) async {
await GoldenToolkit.runWithConfiguration(
() async {
await tester.pumpWidgetBuilder(WidgetWithShadows());
await screenMatchesGolden(tester,
'enableRealShadows_ignored_when_testGoldens_not_wrapped');

expect(debugDisableShadows, isTrue,
reason: 'debugDisableShadows should be true during this test');
},
config: GoldenToolkit.configuration.copyWith(enableRealShadows: true),
);
});
});

test('Default Configuration', () {
final config = GoldenToolkitConfiguration();
expect(config.skipGoldenAssertion(), isFalse);
Expand All @@ -185,6 +221,7 @@ void main() {
);
expect(config.defaultDevices,
equals([Device.phone, Device.tabletLandscape]));
expect(config.enableRealShadows, isFalse);
});

group('Equality/Hashcode/CopyWith', () {
Expand All @@ -193,13 +230,15 @@ void main() {
String deviceFileNameFactory(String filename, Device device) => '';
Future<void> primeAssets(WidgetTester tester) async {}
final devices = [Device.iphone11, Device.iphone11.dark()];
const enableRealShadows = true;

final config = GoldenToolkitConfiguration(
skipGoldenAssertion: skipGoldenAssertion,
deviceFileNameFactory: deviceFileNameFactory,
fileNameFactory: fileNameFactory,
primeAssets: primeAssets,
defaultDevices: devices,
enableRealShadows: enableRealShadows,
);

test('config with identical params should be equal', () {
Expand Down Expand Up @@ -254,6 +293,18 @@ void main() {
isNot(equals(config.copyWith(
defaultDevices: [Device.tabletPortrait]).hashCode)));
});

test('enableRealShadows', () {
expect(
config,
isNot(equals(
config.copyWith(enableRealShadows: !enableRealShadows))));
expect(
config.hashCode,
isNot(equals(config
.copyWith(enableRealShadows: !enableRealShadows)
.hashCode)));
});
});
});
});
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 36 additions & 0 deletions packages/golden_toolkit/test/sample_widgets.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

class WidgetWithShadows extends StatelessWidget {
@override
Widget build(BuildContext context) {
const borderRadius = BorderRadius.all(Radius.circular(10));
return Padding(
padding: const EdgeInsets.all(30),
child: Container(
decoration: BoxDecoration(
color: Colors.yellow,
borderRadius: borderRadius,
boxShadow: [
BoxShadow(
offset: const Offset(10, 10),
blurRadius: 16,
color: Colors.black.withOpacity(0.3),
)
],
),
child: ClipRRect(
borderRadius: borderRadius,
child: Column(
children: const [
Padding(
padding: EdgeInsets.all(3),
child: Text('this is the content'),
),
],
),
),
),
);
}
}
29 changes: 29 additions & 0 deletions packages/golden_toolkit/test/shadows/flutter_test_config.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/// ***************************************************
/// Copyright 2019-2020 eBay Inc.
///
/// Use of this source code is governed by a BSD-style
/// license that can be found in the LICENSE file or at
/// https://opensource.org/licenses/BSD-3-Clause
/// ***************************************************
///
import 'dart:async';
import 'dart:io';

import 'package:golden_toolkit/golden_toolkit.dart';

Future<void> main(FutureOr<void> Function() testMain) async {
return GoldenToolkit.runWithConfiguration(
() async {
await testMain();
},
config: GoldenToolkitConfiguration(
// Currently, goldens are not generated/validated in CI for this repo. We have settled on the goldens for this package
// being captured/validated by developers running on MacOSX. We may revisit this in the future if there is a reason to invest
// in more sophistication
skipGoldenAssertion: () => !Platform.isMacOS,
// enableRealShadows can only work when "outside" of a `testGoldens` , for instance here at the root
enableRealShadows: true,
),
);
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
54 changes: 54 additions & 0 deletions packages/golden_toolkit/test/shadows/shadows_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/// ***************************************************
/// Copyright 2019-2020 eBay Inc.
///
/// Use of this source code is governed by a BSD-style
/// license that can be found in the LICENSE file or at
/// https://opensource.org/licenses/BSD-3-Clause
/// ***************************************************
///
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:golden_toolkit/golden_toolkit.dart';

import '../sample_widgets.dart';

void main() {
group('Shadows Tests', () {
setUp(() {
expect(debugDisableShadows, isTrue,
reason: 'debugDisableShadows should always be true before test');
});

tearDown(() {
expect(debugDisableShadows, isTrue,
reason: 'debugDisableShadows should always be true after test');
});

testGoldens(
'screenMatchesGolden method uses enableRealShadows from global configuration (flutter_test_config.dart)',
(tester) async {
await tester.pumpWidgetBuilder(WidgetWithShadows());
await screenMatchesGolden(tester, 'realShadows_enabled_globally');

expect(debugDisableShadows, isFalse,
reason: 'debugDisableShadows should be false during test');
});

// wraping needs to happen outside of testGoldens
GoldenToolkit.runWithConfiguration(
() => {
testGoldens(
'screenMatchesGolden method can disable enableRealShadows temporarily',
(tester) async {
await tester.pumpWidgetBuilder(WidgetWithShadows());
await screenMatchesGolden(tester, 'realShadows_disabled_locally');

expect(debugDisableShadows, isTrue,
reason: 'debugDisableShadows should be false during test');
})
},
config: GoldenToolkit.configuration.copyWith(enableRealShadows: false),
);
});
}

0 comments on commit 09de7fe

Please sign in to comment.