diff --git a/playground/frontend/lib/modules/examples/repositories/models/get_example_request.dart b/playground/frontend/lib/modules/examples/repositories/models/get_example_request.dart index d86367c0422d..da87f09b2881 100644 --- a/playground/frontend/lib/modules/examples/repositories/models/get_example_request.dart +++ b/playground/frontend/lib/modules/examples/repositories/models/get_example_request.dart @@ -16,6 +16,7 @@ * limitations under the License. */ +import 'package:flutter/cupertino.dart'; import 'package:playground/modules/sdk/models/sdk.dart'; class GetExampleRequestWrapper { @@ -23,4 +24,14 @@ class GetExampleRequestWrapper { final SDK sdk; GetExampleRequestWrapper(this.path, this.sdk); + + @override + bool operator ==(Object other) => + identical(this, other) || + other is GetExampleRequestWrapper && + path == other.path && + sdk == other.sdk; + + @override + int get hashCode => hashValues(path.hashCode, sdk.hashCode); } diff --git a/playground/frontend/lib/modules/examples/repositories/models/get_list_of_examples_request.dart b/playground/frontend/lib/modules/examples/repositories/models/get_list_of_examples_request.dart index 395c5d0cf91a..0d39df522d5c 100644 --- a/playground/frontend/lib/modules/examples/repositories/models/get_list_of_examples_request.dart +++ b/playground/frontend/lib/modules/examples/repositories/models/get_list_of_examples_request.dart @@ -16,6 +16,7 @@ * limitations under the License. */ +import 'package:flutter/cupertino.dart'; import 'package:playground/modules/sdk/models/sdk.dart'; class GetListOfExamplesRequestWrapper { @@ -23,4 +24,14 @@ class GetListOfExamplesRequestWrapper { final String? category; GetListOfExamplesRequestWrapper({required this.sdk, required this.category}); + + @override + bool operator ==(Object other) => + identical(this, other) || + other is GetListOfExamplesRequestWrapper && + category == other.category && + sdk == other.sdk; + + @override + int get hashCode => hashValues(category.hashCode, sdk.hashCode); } diff --git a/playground/frontend/pubspec.lock b/playground/frontend/pubspec.lock index 4c0b78e3a0e1..ed703fd55687 100644 --- a/playground/frontend/pubspec.lock +++ b/playground/frontend/pubspec.lock @@ -272,7 +272,7 @@ packages: name: google_fonts url: "https://pub.dartlang.org" source: hosted - version: "2.3.1" + version: "2.3.0" googleapis_auth: dependency: transitive description: @@ -385,13 +385,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.12.11" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" meta: dependency: transitive description: @@ -690,7 +683,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.8" + version: "0.4.3" timing: dependency: transitive description: @@ -753,7 +746,7 @@ packages: name: url_launcher_web url: "https://pub.dartlang.org" source: hosted - version: "2.0.9" + version: "2.0.6" url_launcher_windows: dependency: transitive description: @@ -819,4 +812,4 @@ packages: version: "3.1.0" sdks: dart: ">=2.15.0 <3.0.0" - flutter: ">=2.10.0" + flutter: ">=2.8.0" diff --git a/playground/frontend/test/modules/editor/repository/example_repository/example_repository_test.dart b/playground/frontend/test/modules/editor/repository/example_repository/example_repository_test.dart new file mode 100644 index 000000000000..5e08b3773847 --- /dev/null +++ b/playground/frontend/test/modules/editor/repository/example_repository/example_repository_test.dart @@ -0,0 +1,130 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'package:playground/modules/examples/repositories/example_client/example_client.dart'; +import 'package:playground/modules/examples/repositories/example_repository.dart'; + +import '../../../../pages/playground/states/mocks/request_mock.dart'; +import 'example_repository_test.mocks.dart'; + +@GenerateMocks([ExampleClient]) +void main() { + late ExampleRepository repo; + late ExampleClient client; + + setUp( + () { + client = MockExampleClient(); + repo = ExampleRepository(client); + }, + ); + + test( + 'Example repository getListOfExamples should return response with categories', + () async { + when(client.getListOfExamples(kGetListOfExamplesRequestMock)) + .thenAnswer((_) async => kGetListOfExamplesResponseMock); + expect( + await repo.getListOfExamples(kGetListOfExamplesRequestMock), + kGetListOfExamplesResponseMock.categories, + ); + verify(client.getListOfExamples(kGetListOfExamplesRequestMock)).called(1); + }, + ); + + test( + 'Example repository getDefaultExample should return defaultExample for chosen Sdk', + () async { + when(client.getDefaultExample(kGetExampleRequestMock)) + .thenAnswer((_) async => kGetExampleResponseMock); + expect( + await repo.getDefaultExample(kGetExampleRequestMock), + kGetExampleResponseMock.example, + ); + verify(client.getDefaultExample(kGetExampleRequestMock)).called(1); + }, + ); + + test( + 'Example repository getExampleSource should return source code for example', + () async { + when(client.getExampleSource(kGetExampleRequestMock)) + .thenAnswer((_) async => kGetExampleCodeResponseMock); + expect( + await repo.getExampleSource(kGetExampleRequestMock), + kGetExampleCodeResponseMock.code, + ); + verify(client.getExampleSource(kGetExampleRequestMock)).called(1); + }, + ); + + test( + 'Example repository getExampleOutput should return output for example', + () async { + when(client.getExampleOutput(kGetExampleRequestMock)) + .thenAnswer((_) async => kOutputResponseMock); + expect( + await repo.getExampleOutput(kGetExampleRequestMock), + kOutputResponseMock.output, + ); + verify(client.getExampleOutput(kGetExampleRequestMock)).called(1); + }, + ); + + test( + 'Example repository getExampleLogs should return logs for example', + () async { + when(client.getExampleLogs(kGetExampleRequestMock)) + .thenAnswer((_) async => kOutputResponseMock); + expect( + await repo.getExampleLogs(kGetExampleRequestMock), + kOutputResponseMock.output, + ); + verify(client.getExampleLogs(kGetExampleRequestMock)).called(1); + }, + ); + + test( + 'Example repository getExampleLogs should return logs for example', + () async { + when(client.getExampleGraph(kGetExampleRequestMock)) + .thenAnswer((_) async => kOutputResponseMock); + expect( + await repo.getExampleGraph(kGetExampleRequestMock), + kOutputResponseMock.output, + ); + verify(client.getExampleGraph(kGetExampleRequestMock)).called(1); + }, + ); + + test( + 'Example repository getExample should return ExampleModel', + () async { + when(client.getExample(kGetExampleRequestMock)) + .thenAnswer((_) async => kGetExampleResponseMock); + expect( + await repo.getExample(kGetExampleRequestMock), + kGetExampleResponseMock.example, + ); + verify(client.getExample(kGetExampleRequestMock)).called(1); + }, + ); +} diff --git a/playground/frontend/test/modules/editor/repository/example_repository/example_repository_test.mocks.dart b/playground/frontend/test/modules/editor/repository/example_repository/example_repository_test.mocks.dart new file mode 100644 index 000000000000..61dd8b27670b --- /dev/null +++ b/playground/frontend/test/modules/editor/repository/example_repository/example_repository_test.mocks.dart @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Mocks generated by Mockito 5.1.0 from annotations +// in playground/test/modules/editor/repository/example_repository/example_repository_test.dart. +// Do not manually edit this file. + +import 'dart:async' as _i7; + +import 'package:mockito/mockito.dart' as _i1; +import 'package:playground/modules/editor/repository/code_repository/code_client/output_response.dart' + as _i5; +import 'package:playground/modules/examples/repositories/example_client/example_client.dart' + as _i6; +import 'package:playground/modules/examples/repositories/models/get_example_code_response.dart' + as _i3; +import 'package:playground/modules/examples/repositories/models/get_example_request.dart' + as _i9; +import 'package:playground/modules/examples/repositories/models/get_example_response.dart' + as _i4; +import 'package:playground/modules/examples/repositories/models/get_list_of_examples_request.dart' + as _i8; +import 'package:playground/modules/examples/repositories/models/get_list_of_examples_response.dart' + as _i2; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types + +class _FakeGetListOfExampleResponse_0 extends _i1.Fake + implements _i2.GetListOfExampleResponse {} + +class _FakeGetExampleCodeResponse_1 extends _i1.Fake + implements _i3.GetExampleCodeResponse {} + +class _FakeGetExampleResponse_2 extends _i1.Fake + implements _i4.GetExampleResponse {} + +class _FakeOutputResponse_3 extends _i1.Fake implements _i5.OutputResponse {} + +/// A class which mocks [ExampleClient]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockExampleClient extends _i1.Mock implements _i6.ExampleClient { + MockExampleClient() { + _i1.throwOnMissingStub(this); + } + + @override + _i7.Future<_i2.GetListOfExampleResponse> getListOfExamples( + _i8.GetListOfExamplesRequestWrapper? request) => + (super.noSuchMethod(Invocation.method(#getListOfExamples, [request]), + returnValue: Future<_i2.GetListOfExampleResponse>.value( + _FakeGetListOfExampleResponse_0())) + as _i7.Future<_i2.GetListOfExampleResponse>); + @override + _i7.Future<_i3.GetExampleCodeResponse> getExampleSource( + _i9.GetExampleRequestWrapper? request) => + (super.noSuchMethod(Invocation.method(#getExampleSource, [request]), + returnValue: Future<_i3.GetExampleCodeResponse>.value( + _FakeGetExampleCodeResponse_1())) + as _i7.Future<_i3.GetExampleCodeResponse>); + @override + _i7.Future<_i4.GetExampleResponse> getDefaultExample( + _i9.GetExampleRequestWrapper? request) => + (super.noSuchMethod(Invocation.method(#getDefaultExample, [request]), + returnValue: Future<_i4.GetExampleResponse>.value( + _FakeGetExampleResponse_2())) + as _i7.Future<_i4.GetExampleResponse>); + @override + _i7.Future<_i4.GetExampleResponse> getExample( + _i9.GetExampleRequestWrapper? request) => + (super.noSuchMethod(Invocation.method(#getExample, [request]), + returnValue: Future<_i4.GetExampleResponse>.value( + _FakeGetExampleResponse_2())) + as _i7.Future<_i4.GetExampleResponse>); + @override + _i7.Future<_i5.OutputResponse> getExampleOutput( + _i9.GetExampleRequestWrapper? request) => + (super.noSuchMethod(Invocation.method(#getExampleOutput, [request]), + returnValue: + Future<_i5.OutputResponse>.value(_FakeOutputResponse_3())) + as _i7.Future<_i5.OutputResponse>); + @override + _i7.Future<_i5.OutputResponse> getExampleLogs( + _i9.GetExampleRequestWrapper? request) => + (super.noSuchMethod(Invocation.method(#getExampleLogs, [request]), + returnValue: + Future<_i5.OutputResponse>.value(_FakeOutputResponse_3())) + as _i7.Future<_i5.OutputResponse>); + @override + _i7.Future<_i5.OutputResponse> getExampleGraph( + _i9.GetExampleRequestWrapper? request) => + (super.noSuchMethod(Invocation.method(#getExampleGraph, [request]), + returnValue: + Future<_i5.OutputResponse>.value(_FakeOutputResponse_3())) + as _i7.Future<_i5.OutputResponse>); +} diff --git a/playground/frontend/test/pages/playground/states/example_selector_state_test.dart b/playground/frontend/test/pages/playground/states/example_selector_state_test.dart index 21259a5fcabf..0198397a7953 100644 --- a/playground/frontend/test/pages/playground/states/example_selector_state_test.dart +++ b/playground/frontend/test/pages/playground/states/example_selector_state_test.dart @@ -28,44 +28,69 @@ import 'package:playground/pages/playground/states/playground_state.dart'; import 'example_selector_state_test.mocks.dart'; import 'mocks/categories_mock.dart'; -final playgroundState = PlaygroundState(); -final ExampleClient client = MockExampleClient(); - @GenerateMocks([ExampleClient]) void main() { + late PlaygroundState playgroundState; + late ExampleState exampleState; + late ExampleSelectorState state; + late ExampleClient client; + + setUp(() { + client = MockExampleClient(); + playgroundState = PlaygroundState(); + exampleState = ExampleState(ExampleRepository(client)); + state = ExampleSelectorState(exampleState, playgroundState, []); + }); + test( - 'ExampleSelector state should notify all listeners about filter type change', - () { - final exampleState = ExampleState(ExampleRepository(client)); - final state = ExampleSelectorState(exampleState, playgroundState, []); - state.addListener(() { - expect(state.selectedFilterType, ExampleType.example); - }); - state.setSelectedFilterType(ExampleType.example); + 'ExampleSelector state selectedFilterType should be ExampleType.all by default', + () { + expect(state.selectedFilterType, ExampleType.all); + }, + ); + + test( + 'ExampleSelector state filterText should be empty string by default', + () { + expect(state.filterText, ''); + }, + ); + + test( + 'ExampleSelector state should notify all listeners about filter type change', + () { + state.addListener(() { + expect(state.selectedFilterType, ExampleType.example); + }); + state.setSelectedFilterType(ExampleType.example); + }, + ); + + test( + 'ExampleSelector state should notify all listeners about filterText change', + () { + state.addListener(() { + expect(state.filterText, 'test'); }); + state.setFilterText('test'); + }, + ); test( - 'ExampleSelector state should notify all listeners about categories change', - () { - final exampleState = ExampleState(ExampleRepository(client)); - final state = ExampleSelectorState(exampleState, playgroundState, []); - state.addListener(() { - expect(state.categories, []); - }); - state.setCategories([]); + 'ExampleSelector state should notify all listeners about categories change', + () { + state.addListener(() { + expect(state.categories, []); }); + state.setCategories([]); + }, + ); test( 'ExampleSelector state sortCategories should:' - '- update categories and notify all listeners,' - 'but should NOT:' - '- affect Example state categories', () { - final exampleState = ExampleState(ExampleRepository(client)); - final state = ExampleSelectorState( - exampleState, - playgroundState, - [], - ); + '- update categories and notify all listeners,' + 'but should NOT:' + '- affect Example state categories', () { state.addListener(() { expect(state.categories, []); expect(exampleState.sdkCategories, exampleState.sdkCategories); @@ -75,11 +100,10 @@ void main() { test( 'ExampleSelector state sortExamplesByType should:' - '- update categories,' - '- notify all listeners,' - 'but should NOT:' - '- affect Example state categories', () { - final exampleState = ExampleState(ExampleRepository(client)); + '- update categories,' + '- notify all listeners,' + 'but should NOT:' + '- affect Example state categories', () { final state = ExampleSelectorState( exampleState, playgroundState, @@ -94,13 +118,12 @@ void main() { test( 'ExampleSelector state sortExamplesByName should:' - '- update categories' - '- notify all listeners,' - 'but should NOT:' - '- wait for full name of example,' - '- be sensitive for register,' - '- affect Example state categories', () { - final exampleState = ExampleState(ExampleRepository(client)); + '- update categories' + '- notify all listeners,' + 'but should NOT:' + '- wait for full name of example,' + '- be sensitive for register,' + '- affect Example state categories', () { final state = ExampleSelectorState( exampleState, playgroundState, diff --git a/playground/frontend/test/pages/playground/states/example_selector_state_test.mocks.dart b/playground/frontend/test/pages/playground/states/example_selector_state_test.mocks.dart index c4ad1dba6fb2..a9009516d304 100644 --- a/playground/frontend/test/pages/playground/states/example_selector_state_test.mocks.dart +++ b/playground/frontend/test/pages/playground/states/example_selector_state_test.mocks.dart @@ -37,6 +37,7 @@ import 'package:playground/modules/examples/repositories/models/get_list_of_exam import 'package:playground/modules/examples/repositories/models/get_list_of_examples_response.dart' as _i2; +// ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values // ignore_for_file: avoid_setters_without_getters // ignore_for_file: comment_references @@ -114,6 +115,4 @@ class MockExampleClient extends _i1.Mock implements _i6.ExampleClient { returnValue: Future<_i5.OutputResponse>.value(_FakeOutputResponse_3())) as _i7.Future<_i5.OutputResponse>); - @override - String toString() => super.toString(); } diff --git a/playground/frontend/test/pages/playground/states/examples_state_test.dart b/playground/frontend/test/pages/playground/states/examples_state_test.dart new file mode 100644 index 000000000000..5416ff7be82c --- /dev/null +++ b/playground/frontend/test/pages/playground/states/examples_state_test.dart @@ -0,0 +1,219 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'package:playground/modules/examples/repositories/example_repository.dart'; +import 'package:playground/modules/sdk/models/sdk.dart'; +import 'package:playground/pages/playground/states/examples_state.dart'; + +import 'examples_state_test.mocks.dart'; +import 'mocks/categories_mock.dart'; +import 'mocks/example_mock.dart'; +import 'mocks/request_mock.dart'; + +final kDefaultExamplesMapMock = { + SDK.java: exampleWithAllAdditionsMock, + SDK.go: exampleWithAllAdditionsMock, + SDK.python: exampleWithAllAdditionsMock, + SDK.scio: exampleWithAllAdditionsMock, +}; + +@GenerateMocks([ExampleRepository]) +void main() { + late ExampleState state; + late MockExampleRepository mockRepo; + + setUp(() { + mockRepo = MockExampleRepository(); + state = ExampleState(mockRepo); + }); + + test('Initial value of defaultExamplesMap should be an empty map', () { + expect(state.defaultExamplesMap, {}); + }); + + test('Initial value of isSelectorOpened should be false', () { + expect(state.isSelectorOpened, false); + }); + + test( + 'Example state init should initiate loading of sdkCategories from server', + () async { + when(mockRepo.getListOfExamples(kGetListOfExamplesRequestMock)) + .thenAnswer((_) async => kGetListOfExamplesResponseMock.categories); + await state.init(); + expect(state.sdkCategories, sdkCategoriesFromServerMock); + }, + ); + + test( + 'Example state should notify all listeners about sdkCategories is set', + () { + state.addListener(() { + expect(state.sdkCategories, sdkCategoriesFromServerMock); + }); + state.setSdkCategories(sdkCategoriesFromServerMock); + }, + ); + + test( + 'Example state changeSelectorVisibility should change isSelectorOpened to !isSelectorOpened', + () { + state.changeSelectorVisibility(); + expect(state.isSelectorOpened, true); + state.changeSelectorVisibility(); + expect(state.isSelectorOpened, false); + }, + ); + + test( + 'Example state getCategories should get the categories list for each SDK', + () { + state.setSdkCategories(sdkCategoriesFromServerMock); + expect(state.getCategories(SDK.java), categoriesMock); + expect(state.getCategories(SDK.go), categoriesMock); + expect(state.getCategories(SDK.python), categoriesMock); + expect(state.getCategories(SDK.scio), categoriesMock); + }, + ); + + test( + 'Example state getExampleOutput should return output for example', + () async { + when(mockRepo.getExampleOutput(kGetExampleRequestMock)) + .thenAnswer((_) async => kOutputResponseMock.output); + expect( + await state.getExampleOutput('', SDK.java), + kOutputResponseMock.output, + ); + }, + ); + + test( + 'Example state getExampleSource should return source code for example', + () async { + when(mockRepo.getExampleSource(kGetExampleRequestMock)) + .thenAnswer((_) async => kOutputResponseMock.output); + expect( + await state.getExampleSource('', SDK.java), + kOutputResponseMock.output, + ); + }, + ); + + test( + 'Example state getExampleLogs should return logs for example', + () async { + when(mockRepo.getExampleLogs(kGetExampleRequestMock)) + .thenAnswer((_) async => kOutputResponseMock.output); + expect( + await state.getExampleLogs('', SDK.java), + kOutputResponseMock.output, + ); + }, + ); + + test( + 'Example state getExampleGraph should return output for example', + () async { + when(mockRepo.getExampleGraph(kGetExampleRequestMock)) + .thenAnswer((_) async => kOutputResponseMock.output); + expect( + await state.getExampleGraph('', SDK.java), + kOutputResponseMock.output, + ); + }, + ); + + group('loadExampleInfo tests', () { + test( + 'If example info is fetched (source is not empty),' + 'then loadExampleInfo should return example immediately', + () async { + expect( + await state.loadExampleInfo(exampleMock1, SDK.java), + exampleMock1, + ); + }, + ); + + test( + 'Example state loadExampleInfo should load source, output, logs, graph for given example', + () async { + // stubs + when(mockRepo.getExampleOutput(kRequestForExampleInfo)) + .thenAnswer((_) async => kOutputResponseMock.output); + when(mockRepo.getExampleSource(kRequestForExampleInfo)) + .thenAnswer((_) async => kOutputResponseMock.output); + when(mockRepo.getExampleLogs(kRequestForExampleInfo)) + .thenAnswer((_) async => kOutputResponseMock.output); + when(mockRepo.getExampleGraph(kRequestForExampleInfo)) + .thenAnswer((_) async => kOutputResponseMock.output); + + // test assertion + expect( + await state.loadExampleInfo(exampleWithoutSourceMock, SDK.java), + exampleWithAllAdditionsMock, + ); + }, + ); + }); + + group('loadDefaultExamples tests', () { + test( + 'If defaultExamplesMap is not empty, then loadDefaultExamples should not change it', + () async { + state.defaultExamplesMap = kDefaultExamplesMapMock; + await state.loadDefaultExamples(); + expect(state.defaultExamplesMap, kDefaultExamplesMapMock); + }, + ); + test( + 'Example state loadDefaultExamples should load default example' + 'with all additions for every Sdk', + () async { + // stubs + when(mockRepo.getDefaultExample(kRequestDefaultExampleForJava)) + .thenAnswer((_) async => exampleWithoutSourceMock); + when(mockRepo.getDefaultExample(kRequestDefaultExampleForGo)) + .thenAnswer((_) async => exampleWithoutSourceMock); + when(mockRepo.getDefaultExample(kRequestDefaultExampleForPython)) + .thenAnswer((_) async => exampleWithoutSourceMock); + when(mockRepo.getDefaultExample(kRequestDefaultExampleForScio)) + .thenAnswer((_) async => exampleWithoutSourceMock); + when(mockRepo.getExampleOutput(kRequestForExampleInfo)) + .thenAnswer((_) async => kOutputResponseMock.output); + when(mockRepo.getExampleSource(kRequestForExampleInfo)) + .thenAnswer((_) async => kOutputResponseMock.output); + when(mockRepo.getExampleLogs(kRequestForExampleInfo)) + .thenAnswer((_) async => kOutputResponseMock.output); + when(mockRepo.getExampleGraph(kRequestForExampleInfo)) + .thenAnswer((_) async => kOutputResponseMock.output); + + // test assertion + await state.loadDefaultExamples(); + expect( + state.defaultExamplesMap, + kDefaultExamplesMapMock, + ); + }, + ); + }); +} diff --git a/playground/frontend/test/pages/playground/states/examples_state_test.mocks.dart b/playground/frontend/test/pages/playground/states/examples_state_test.mocks.dart new file mode 100644 index 000000000000..832064e2527c --- /dev/null +++ b/playground/frontend/test/pages/playground/states/examples_state_test.mocks.dart @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Mocks generated by Mockito 5.0.16 from annotations +// in playground/test/pages/playground/states/examples_state_test.dart. +// Do not manually edit this file. + +import 'dart:async' as _i4; + +import 'package:mockito/mockito.dart' as _i1; +import 'package:playground/modules/examples/models/category_model.dart' as _i6; +import 'package:playground/modules/examples/models/example_model.dart' as _i2; +import 'package:playground/modules/examples/repositories/example_repository.dart' + as _i3; +import 'package:playground/modules/examples/repositories/models/get_example_request.dart' + as _i8; +import 'package:playground/modules/examples/repositories/models/get_list_of_examples_request.dart' + as _i7; +import 'package:playground/modules/sdk/models/sdk.dart' as _i5; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types + +class _FakeExampleModel_0 extends _i1.Fake implements _i2.ExampleModel {} + +/// A class which mocks [ExampleRepository]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockExampleRepository extends _i1.Mock implements _i3.ExampleRepository { + MockExampleRepository() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Future>> getListOfExamples( + _i7.GetListOfExamplesRequestWrapper? request) => + (super.noSuchMethod(Invocation.method(#getListOfExamples, [request]), + returnValue: Future>>.value( + <_i5.SDK, List<_i6.CategoryModel>>{})) + as _i4.Future>>); + @override + _i4.Future<_i2.ExampleModel> getDefaultExample( + _i8.GetExampleRequestWrapper? request) => + (super.noSuchMethod(Invocation.method(#getDefaultExample, [request]), + returnValue: + Future<_i2.ExampleModel>.value(_FakeExampleModel_0())) + as _i4.Future<_i2.ExampleModel>); + @override + _i4.Future getExampleSource(_i8.GetExampleRequestWrapper? request) => + (super.noSuchMethod(Invocation.method(#getExampleSource, [request]), + returnValue: Future.value('')) as _i4.Future); + @override + _i4.Future getExampleOutput(_i8.GetExampleRequestWrapper? request) => + (super.noSuchMethod(Invocation.method(#getExampleOutput, [request]), + returnValue: Future.value('')) as _i4.Future); + @override + _i4.Future getExampleLogs(_i8.GetExampleRequestWrapper? request) => + (super.noSuchMethod(Invocation.method(#getExampleLogs, [request]), + returnValue: Future.value('')) as _i4.Future); + @override + _i4.Future getExampleGraph(_i8.GetExampleRequestWrapper? request) => + (super.noSuchMethod(Invocation.method(#getExampleGraph, [request]), + returnValue: Future.value('')) as _i4.Future); + @override + _i4.Future<_i2.ExampleModel> getExample( + _i8.GetExampleRequestWrapper? request) => + (super.noSuchMethod(Invocation.method(#getExample, [request]), + returnValue: + Future<_i2.ExampleModel>.value(_FakeExampleModel_0())) + as _i4.Future<_i2.ExampleModel>); +} diff --git a/playground/frontend/test/pages/playground/states/mocks/categories_mock.dart b/playground/frontend/test/pages/playground/states/mocks/categories_mock.dart index ee86cabf5037..0079697013c0 100644 --- a/playground/frontend/test/pages/playground/states/mocks/categories_mock.dart +++ b/playground/frontend/test/pages/playground/states/mocks/categories_mock.dart @@ -18,6 +18,7 @@ import 'package:playground/modules/examples/models/category_model.dart'; import 'package:playground/modules/examples/models/example_model.dart'; +import 'package:playground/modules/sdk/models/sdk.dart'; import 'example_mock.dart'; @@ -35,3 +36,10 @@ final List unsortedExamples = [exampleMock1, exampleMock2]; final List examplesSortedByTypeMock = [exampleMock2]; final List examplesSortedByNameMock = [exampleMock1]; + +final sdkCategoriesFromServerMock = { + SDK.java: categoriesMock, + SDK.python: categoriesMock, + SDK.go: categoriesMock, + SDK.scio: categoriesMock, +}; diff --git a/playground/frontend/test/pages/playground/states/mocks/example_mock.dart b/playground/frontend/test/pages/playground/states/mocks/example_mock.dart index 8e5bc277a199..0be09e915f0f 100644 --- a/playground/frontend/test/pages/playground/states/mocks/example_mock.dart +++ b/playground/frontend/test/pages/playground/states/mocks/example_mock.dart @@ -33,3 +33,21 @@ final ExampleModel exampleMock2 = ExampleModel( description: 'description', path: 'SDK/Category/Name', ); + +final ExampleModel exampleWithoutSourceMock = ExampleModel( + name: 'Test example', + type: ExampleType.example, + description: 'description', + path: 'SDK/Category/Name', +); + +final ExampleModel exampleWithAllAdditionsMock = ExampleModel( + name: 'Test example', + type: ExampleType.example, + description: 'description', + path: 'SDK/Category/Name', + source: 'test outputs', + outputs: 'test outputs', + logs: 'test outputs', + graph: 'test outputs', +); diff --git a/playground/frontend/test/pages/playground/states/mocks/request_mock.dart b/playground/frontend/test/pages/playground/states/mocks/request_mock.dart new file mode 100644 index 000000000000..e6536897712b --- /dev/null +++ b/playground/frontend/test/pages/playground/states/mocks/request_mock.dart @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import 'package:playground/modules/editor/repository/code_repository/code_client/output_response.dart'; +import 'package:playground/modules/examples/repositories/models/get_example_code_response.dart'; +import 'package:playground/modules/examples/repositories/models/get_example_request.dart'; +import 'package:playground/modules/examples/repositories/models/get_example_response.dart'; +import 'package:playground/modules/examples/repositories/models/get_list_of_examples_request.dart'; +import 'package:playground/modules/examples/repositories/models/get_list_of_examples_response.dart'; +import 'package:playground/modules/sdk/models/sdk.dart'; + +import 'categories_mock.dart'; +import 'example_mock.dart'; + +final kGetListOfExamplesRequestMock = + GetListOfExamplesRequestWrapper(sdk: null, category: null); +final kGetListOfExamplesResponseMock = + GetListOfExampleResponse(sdkCategoriesFromServerMock); +final kGetExampleRequestMock = GetExampleRequestWrapper('', SDK.java); +final kGetExampleResponseMock = GetExampleResponse(exampleMock1); +final kGetExampleCodeResponseMock = GetExampleCodeResponse('test source'); +final kOutputResponseMock = OutputResponse('test outputs'); + +final kRequestForExampleInfo = + GetExampleRequestWrapper('SDK/Category/Name', SDK.java); +final kRequestDefaultExampleForJava = GetExampleRequestWrapper('', SDK.java); +final kRequestDefaultExampleForGo = GetExampleRequestWrapper('', SDK.go); +final kRequestDefaultExampleForPython = + GetExampleRequestWrapper('', SDK.python); +final kRequestDefaultExampleForScio = GetExampleRequestWrapper('', SDK.scio); diff --git a/playground/frontend/test/pages/playground/states/playground_state_test.dart b/playground/frontend/test/pages/playground/states/playground_state_test.dart index 6516a8ffa6dd..d49e69d30179 100644 --- a/playground/frontend/test/pages/playground/states/playground_state_test.dart +++ b/playground/frontend/test/pages/playground/states/playground_state_test.dart @@ -23,13 +23,74 @@ import 'package:playground/pages/playground/states/playground_state.dart'; import 'mocks/example_mock.dart'; void main() { - test('Playground State initial value should be java', () { - final state = PlaygroundState(); + late PlaygroundState state; + + setUp(() { + state = PlaygroundState(); + }); + + test('Initial value of SDK field should be java', () { expect(state.sdk, equals(SDK.java)); }); + test('Initial value of examplesTitle should be equal to kTitle', () { + expect(state.examplesTitle, kTitle); + }); + + test('Initial value of isCodeRunning should be false', () { + expect(state.isCodeRunning, false); + }); + + test('Initial value of pipelineOptions should be empty string', () { + expect(state.pipelineOptions, ''); + }); + + test('Initial value of source should be empty string', () { + expect(state.source, ''); + }); + + group('isExampleChanged Tests', () { + test( + 'If example source is changed, value of isExampleChanged should be true', + () { + state.setExample(exampleMock1); + state.selectedExample!.setSource('test'); + expect(state.isExampleChanged, true); + }, + ); + + test( + 'If pipelineOptions is changed, value of isExampleChanged should be true', + () { + state.setExample(exampleMock1); + state.setPipelineOptions('test options'); + expect(state.isExampleChanged, true); + }, + ); + }); + + test( + 'If selected example type is not test and SDK is java or python, graph should be available', + () { + state.setExample(exampleMock1); + expect(state.graphAvailable, true); + }, + ); + + test( + 'Playground state setExample should update source and example and notify all listeners', + () { + final state = PlaygroundState(sdk: SDK.go); + state.addListener(() { + expect(state.sdk, SDK.go); + expect(state.source, exampleMock1.source); + expect(state.selectedExample, exampleMock1); + }); + state.setExample(exampleMock1); + }, + ); + test('Playground state should notify all listeners about sdk change', () { - final state = PlaygroundState(); state.addListener(() { expect(state.sdk, SDK.go); }); @@ -48,14 +109,20 @@ void main() { }); test( - 'Playground state setExample should update source and example and notify all listeners', - () { - final state = PlaygroundState(sdk: SDK.go); - state.addListener(() { - expect(state.sdk, SDK.go); - expect(state.source, exampleMock1.source); - expect(state.selectedExample, exampleMock1); - }); - state.setExample(exampleMock1); - }); + 'If Playground state result is empty, then resetError should break the execution', + () { + state.resetError(); + expect(state.result, null); + }, + ); + + test( + 'Playground state should notify all listeners about pipeline options change', + () { + state.addListener(() { + expect(state.pipelineOptions, 'test options'); + }); + state.setPipelineOptions('test options'); + }, + ); }