import 'package:platform_container/container.dart'; import 'package:platform_pipeline/pipeline.dart'; import 'package:test/test.dart'; // Test pipe classes to match Laravel's test classes class PipelineTestPipeOne { static String? testPipeOne; Future handle(dynamic piped, Function next) async { testPipeOne = piped.toString(); return next(piped); } Future differentMethod(dynamic piped, Function next) async { return next(piped); } } class PipelineTestPipeTwo { static String? testPipeOne; Future call(dynamic piped, Function next) async { testPipeOne = piped.toString(); return next(piped); } } class PipelineTestParameterPipe { static List? testParameters; Future handle(dynamic piped, Function next, [String? parameter1, String? parameter2]) async { testParameters = [ if (parameter1 != null) parameter1, if (parameter2 != null) parameter2 ]; return next(piped); } } void main() { group('Laravel Pipeline Tests', () { late Container container; late Pipeline pipeline; setUp(() { container = Container(const EmptyReflector()); pipeline = Pipeline(container); // Register test classes with container container .registerFactory((c) => PipelineTestPipeOne()); container .registerFactory((c) => PipelineTestPipeTwo()); container.registerFactory( (c) => PipelineTestParameterPipe()); // Register types with pipeline pipeline.registerPipeType('PipelineTestPipeOne', PipelineTestPipeOne); pipeline.registerPipeType('PipelineTestPipeTwo', PipelineTestPipeTwo); pipeline.registerPipeType( 'PipelineTestParameterPipe', PipelineTestParameterPipe); // Reset static test variables PipelineTestPipeOne.testPipeOne = null; PipelineTestPipeTwo.testPipeOne = null; PipelineTestParameterPipe.testParameters = null; }); test('Pipeline basic usage', () async { String? testPipeTwo; final pipeTwo = (dynamic piped, Function next) { testPipeTwo = piped.toString(); return next(piped); }; final result = await Pipeline(container) .send('foo') .through([PipelineTestPipeOne(), pipeTwo]).then((piped) => piped); expect(result, equals('foo')); expect(PipelineTestPipeOne.testPipeOne, equals('foo')); expect(testPipeTwo, equals('foo')); }); test('Pipeline usage with objects', () async { final result = await Pipeline(container) .send('foo') .through([PipelineTestPipeOne()]).then((piped) => piped); expect(result, equals('foo')); expect(PipelineTestPipeOne.testPipeOne, equals('foo')); }); test('Pipeline usage with invokable objects', () async { final result = await Pipeline(container) .send('foo') .through([PipelineTestPipeTwo()]).then((piped) => piped); expect(result, equals('foo')); expect(PipelineTestPipeTwo.testPipeOne, equals('foo')); }); test('Pipeline usage with callable', () async { String? testPipeOne; final function = (dynamic piped, Function next) { testPipeOne = 'foo'; return next(piped); }; var result = await Pipeline(container) .send('foo') .through([function]).then((piped) => piped); expect(result, equals('foo')); expect(testPipeOne, equals('foo')); testPipeOne = null; result = await Pipeline(container).send('bar').through(function).thenReturn(); expect(result, equals('bar')); expect(testPipeOne, equals('foo')); }); test('Pipeline usage with pipe', () async { final object = {'value': 0}; final function = (dynamic obj, Function next) { obj['value']++; return next(obj); }; final result = await Pipeline(container) .send(object) .through([function]).pipe([function]).then((piped) => piped); expect(result, equals(object)); expect(object['value'], equals(2)); }); test('Pipeline usage with invokable class', () async { final result = await Pipeline(container) .send('foo') .through([PipelineTestPipeTwo()]).then((piped) => piped); expect(result, equals('foo')); expect(PipelineTestPipeTwo.testPipeOne, equals('foo')); }); test('Then method is not called if the pipe returns', () async { String thenValue = '(*_*)'; String secondValue = '(*_*)'; final result = await Pipeline(container).send('foo').through([ (value, next) => 'm(-_-)m', (value, next) { secondValue = 'm(-_-)m'; return next(value); }, ]).then((piped) { thenValue = '(0_0)'; return piped; }); expect(result, equals('m(-_-)m')); // The then callback is not called expect(thenValue, equals('(*_*)')); // The second pipe is not called expect(secondValue, equals('(*_*)')); }); test('Then method input value', () async { String? pipeReturn; String? thenArg; final result = await Pipeline(container).send('foo').through([ (value, next) async { final nextValue = await next('::not_foo::'); pipeReturn = nextValue; return 'pipe::$nextValue'; } ]).then((piped) { thenArg = piped; return 'then$piped'; }); expect(result, equals('pipe::then::not_foo::')); expect(thenArg, equals('::not_foo::')); }); test('Pipeline usage with parameters', () async { final parameters = ['one', 'two']; final result = await Pipeline(container) .send('foo') .through('PipelineTestParameterPipe:${parameters.join(',')}') .then((piped) => piped); expect(result, equals('foo')); expect(PipelineTestParameterPipe.testParameters, equals(parameters)); }); test('Pipeline via changes the method being called on the pipes', () async { final result = await Pipeline(container) .send('data') .through(PipelineTestPipeOne()) .via('differentMethod') .then((piped) => piped); expect(result, equals('data')); }); test('Pipeline throws exception on resolve without container', () async { expect( () => Pipeline(null) .send('data') .through(PipelineTestPipeOne()) .then((piped) => piped), throwsA(isA().having( (e) => e.toString(), 'message', contains( 'A container instance has not been passed to the Pipeline')))); }); test('Pipeline thenReturn method runs pipeline then returns passable', () async { final result = await Pipeline(container) .send('foo') .through([PipelineTestPipeOne()]).thenReturn(); expect(result, equals('foo')); expect(PipelineTestPipeOne.testPipeOne, equals('foo')); }); test('Pipeline conditionable', () async { var result = await Pipeline(container).send('foo').when(() => true, (Pipeline pipeline) { pipeline.pipe([PipelineTestPipeOne()]); }).then((piped) => piped); expect(result, equals('foo')); expect(PipelineTestPipeOne.testPipeOne, equals('foo')); PipelineTestPipeOne.testPipeOne = null; result = await Pipeline(container).send('foo').when(() => false, (Pipeline pipeline) { pipeline.pipe([PipelineTestPipeOne()]); }).then((piped) => piped); expect(result, equals('foo')); expect(PipelineTestPipeOne.testPipeOne, isNull); }); }); }