diff --git a/playground/backend/internal/api/v1/api.pb.go b/playground/backend/internal/api/v1/api.pb.go index 67a7ff6c7afc..dcafcabe2f97 100644 --- a/playground/backend/internal/api/v1/api.pb.go +++ b/playground/backend/internal/api/v1/api.pb.go @@ -17,8 +17,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc-gen-go v1.25.0-devel +// protoc v3.19.1 // source: api/v1/api.proto package playground diff --git a/playground/frontend/analysis_options.yaml b/playground/frontend/analysis_options.yaml index a74dda8af42c..85c482936ac9 100644 --- a/playground/frontend/analysis_options.yaml +++ b/playground/frontend/analysis_options.yaml @@ -28,7 +28,7 @@ include: package:flutter_lints/flutter.yaml # exclude generated files analyzer: - exclude: [lib/api/**, test/**.mocks.dart, lib/**.g.dart] + exclude: [ lib/api/**, test/**.mocks.dart, lib/**.g.dart, build/** ] linter: # The lint rules applied to this project can be customized in the @@ -43,6 +43,7 @@ linter: # `// ignore_for_file: name_of_lint` syntax on the line or in the file # producing the lint. rules: + eol_at_end_of_file: true avoid_web_libraries_in_flutter: false # avoid_print: false # Uncomment to disable the `avoid_print` rule prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule diff --git a/playground/frontend/lib/api/v1/api.pb.dart b/playground/frontend/lib/api/v1/api.pb.dart index 2aef7d9b8310..9a96e7d93a71 100644 --- a/playground/frontend/lib/api/v1/api.pb.dart +++ b/playground/frontend/lib/api/v1/api.pb.dart @@ -15,6 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + /// // Generated code. Do not modify. // source: api/v1/api.proto diff --git a/playground/frontend/lib/api/v1/api.pbenum.dart b/playground/frontend/lib/api/v1/api.pbenum.dart index 83a7729589de..c4aa4bd2e887 100644 --- a/playground/frontend/lib/api/v1/api.pbenum.dart +++ b/playground/frontend/lib/api/v1/api.pbenum.dart @@ -15,6 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + /// // Generated code. Do not modify. // source: api/v1/api.proto diff --git a/playground/frontend/lib/api/v1/api.pbjson.dart b/playground/frontend/lib/api/v1/api.pbjson.dart index 0e0209c45223..8b0e01f7917e 100644 --- a/playground/frontend/lib/api/v1/api.pbjson.dart +++ b/playground/frontend/lib/api/v1/api.pbjson.dart @@ -15,6 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + /// // Generated code. Do not modify. // source: api/v1/api.proto diff --git a/playground/frontend/lib/modules/editor/components/editor_textarea.dart b/playground/frontend/lib/modules/editor/components/editor_textarea.dart index 670aa16f727d..7cdc7df89638 100644 --- a/playground/frontend/lib/modules/editor/components/editor_textarea.dart +++ b/playground/frontend/lib/modules/editor/components/editor_textarea.dart @@ -60,7 +60,7 @@ class _EditorTextAreaState extends State { void didChangeDependencies() { final themeProvider = Provider.of(context, listen: true); _codeController = CodeController( - text: _codeController?.text ?? widget.example?.sources[widget.sdk] ?? '', + text: _codeController?.text ?? widget.example?.source ?? '', language: _getLanguageFromSdk(), theme: themeProvider.isDarkMode ? kDarkCodeTheme : kLightCodeTheme, onChange: (newSource) => widget.onSourceChange(newSource), diff --git a/playground/frontend/lib/modules/examples/components/example_list/category_expansion_panel.dart b/playground/frontend/lib/modules/examples/components/example_list/category_expansion_panel.dart index 441fd9cf961c..f5e51a553a21 100644 --- a/playground/frontend/lib/modules/examples/components/example_list/category_expansion_panel.dart +++ b/playground/frontend/lib/modules/examples/components/example_list/category_expansion_panel.dart @@ -15,6 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import 'dart:math' as math; import 'package:expansion_widget/expansion_widget.dart'; diff --git a/playground/frontend/lib/modules/examples/components/example_list/expansion_panel_item.dart b/playground/frontend/lib/modules/examples/components/example_list/expansion_panel_item.dart index 2ae056070aab..98baeef19823 100644 --- a/playground/frontend/lib/modules/examples/components/example_list/expansion_panel_item.dart +++ b/playground/frontend/lib/modules/examples/components/example_list/expansion_panel_item.dart @@ -19,6 +19,7 @@ import 'package:flutter/material.dart'; import 'package:playground/constants/sizes.dart'; import 'package:playground/modules/examples/models/example_model.dart'; +import 'package:playground/pages/playground/states/examples_state.dart'; import 'package:playground/pages/playground/states/playground_state.dart'; import 'package:provider/provider.dart'; @@ -29,13 +30,15 @@ class ExpansionPanelItem extends StatelessWidget { @override Widget build(BuildContext context) { - return Consumer( - builder: (context, state, child) => MouseRegion( + return Consumer2( + builder: (context, playgroundState, exampleState, child) => MouseRegion( cursor: SystemMouseCursors.click, child: GestureDetector( - onTap: () { - if (state.selectedExample != example) { - state.setExample(example); + onTap: () async { + if (playgroundState.selectedExample != example) { + final exampleWithInfo = + await exampleState.loadExampleInfo(example); + playgroundState.setExample(exampleWithInfo); } }, child: Container( diff --git a/playground/frontend/lib/modules/examples/components/search_field/search_field.dart b/playground/frontend/lib/modules/examples/components/search_field/search_field.dart index 1889b53db120..a700ef74f4c3 100644 --- a/playground/frontend/lib/modules/examples/components/search_field/search_field.dart +++ b/playground/frontend/lib/modules/examples/components/search_field/search_field.dart @@ -75,14 +75,9 @@ class SearchField extends StatelessWidget { cursorColor: ThemeColors.of(context).lightGreyColor, cursorWidth: kCursorSize, textAlignVertical: TextAlignVertical.center, - onFieldSubmitted: (String filterText) { - state.setFilterText(filterText); - state.sortCategories(); - }, - onChanged: (String filterText) { - state.setFilterText(filterText); - state.sortCategories(); - }, + onFieldSubmitted: (String filterText) => + _onChange(state, filterText), + onChanged: (String filterText) => _onChange(state, filterText), maxLines: kMinLines, minLines: kMaxLines, ), @@ -90,4 +85,9 @@ class SearchField extends StatelessWidget { ), ); } + + _onChange(ExampleSelectorState state, String filterText) { + state.setFilterText(filterText); + state.sortCategories(); + } } diff --git a/playground/frontend/lib/modules/examples/example_selector.dart b/playground/frontend/lib/modules/examples/example_selector.dart index a9de0b7b6b2a..259b7c3c68fc 100644 --- a/playground/frontend/lib/modules/examples/example_selector.dart +++ b/playground/frontend/lib/modules/examples/example_selector.dart @@ -20,7 +20,6 @@ import 'package:flutter/material.dart'; import 'package:playground/config/theme.dart'; import 'package:playground/constants/sizes.dart'; import 'package:playground/modules/examples/components/examples_components.dart'; -import 'package:playground/modules/examples/models/category_model.dart'; import 'package:playground/modules/examples/models/selector_size_model.dart'; import 'package:playground/pages/playground/states/example_selector_state.dart'; import 'package:playground/pages/playground/states/examples_state.dart'; @@ -37,13 +36,11 @@ const double kLgContainerWidth = 400.0; class ExampleSelector extends StatefulWidget { final Function changeSelectorVisibility; final bool isSelectorOpened; - final List categories; const ExampleSelector({ Key? key, required this.changeSelectorVisibility, required this.isSelectorOpened, - required this.categories, }) : super(key: key); @override @@ -123,14 +120,14 @@ class _ExampleSelectorState extends State return OverlayEntry( builder: (context) { - return Consumer( - builder: (context, state, child) => Stack( + return Consumer2( + builder: (context, exampleState, playgroundState, child) => Stack( children: [ GestureDetector( onTap: () { animationController.reverse(); examplesDropdown?.remove(); - state.changeSelectorVisibility(); + exampleState.changeSelectorVisibility(); }, child: Container( color: Colors.transparent, @@ -140,8 +137,9 @@ class _ExampleSelectorState extends State ), ChangeNotifierProvider( create: (context) => ExampleSelectorState( - state, - state.categories!, + exampleState, + playgroundState, + exampleState.getCategories(playgroundState.sdk)!, ), builder: (context, _) => Positioned( left: posModel.xAlignment, diff --git a/playground/frontend/lib/modules/examples/models/category_model.dart b/playground/frontend/lib/modules/examples/models/category_model.dart index 2c4b0f1a3401..da9d0e4e8001 100644 --- a/playground/frontend/lib/modules/examples/models/category_model.dart +++ b/playground/frontend/lib/modules/examples/models/category_model.dart @@ -22,5 +22,5 @@ class CategoryModel { final String name; final List examples; - const CategoryModel(this.name, this.examples); + const CategoryModel({required this.name, required this.examples}); } diff --git a/playground/frontend/lib/modules/examples/models/example_model.dart b/playground/frontend/lib/modules/examples/models/example_model.dart index 17e6f584982c..e39124b566d5 100644 --- a/playground/frontend/lib/modules/examples/models/example_model.dart +++ b/playground/frontend/lib/modules/examples/models/example_model.dart @@ -16,8 +16,6 @@ * limitations under the License. */ -import 'package:playground/modules/sdk/models/sdk.dart'; - enum ExampleType { all, example, @@ -41,9 +39,27 @@ extension ExampleTypeToString on ExampleType { } class ExampleModel { - final Map sources; final ExampleType type; final String name; + final String path; + final String description; + String? source; + String? outputs; + + ExampleModel({ + required this.name, + required this.path, + required this.description, + required this.type, + this.source, + this.outputs, + }); - const ExampleModel(this.sources, this.name, this.type); + setSource(String source) { + this.source = source; + } + + setOutputs(String outputs) { + this.outputs = outputs; + } } diff --git a/playground/frontend/lib/modules/examples/models/outputs_model.dart b/playground/frontend/lib/modules/examples/models/outputs_model.dart new file mode 100644 index 000000000000..a9b1bfa355b9 --- /dev/null +++ b/playground/frontend/lib/modules/examples/models/outputs_model.dart @@ -0,0 +1,25 @@ +/* + * 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. + */ + +class OutputsModel { + final String output; + final String graph; + final String log; + + OutputsModel(this.output, this.graph, this.log); +} diff --git a/playground/frontend/lib/modules/examples/repositories/example_client/example_client.dart b/playground/frontend/lib/modules/examples/repositories/example_client/example_client.dart new file mode 100644 index 000000000000..077024f77311 --- /dev/null +++ b/playground/frontend/lib/modules/examples/repositories/example_client/example_client.dart @@ -0,0 +1,33 @@ +/* + * 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_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'; + +abstract class ExampleClient { + Future getListOfExamples( + GetListOfExamplesRequestWrapper request, + ); + + Future getExample(GetExampleRequestWrapper request); + + Future getExampleOutput(GetExampleRequestWrapper request); +} diff --git a/playground/frontend/lib/modules/examples/repositories/example_client/grpc_example_client.dart b/playground/frontend/lib/modules/examples/repositories/example_client/grpc_example_client.dart new file mode 100644 index 000000000000..031d5da6b215 --- /dev/null +++ b/playground/frontend/lib/modules/examples/repositories/example_client/grpc_example_client.dart @@ -0,0 +1,171 @@ +/* + * 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:grpc/grpc_web.dart'; +import 'package:playground/api/v1/api.pbgrpc.dart' as grpc; +import 'package:playground/config.g.dart'; +import 'package:playground/modules/editor/repository/code_repository/code_client/output_response.dart'; +import 'package:playground/modules/examples/models/category_model.dart'; +import 'package:playground/modules/examples/models/example_model.dart'; +import 'package:playground/modules/examples/repositories/example_client/example_client.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'; + +class GrpcExampleClient implements ExampleClient { + late final GrpcWebClientChannel _channel; + late final grpc.PlaygroundServiceClient _client; + + GrpcExampleClient() { + _channel = GrpcWebClientChannel.xhr( + Uri.parse(kApiClientURL), + ); + _client = grpc.PlaygroundServiceClient(_channel); + } + + @override + Future getListOfExamples( + GetListOfExamplesRequestWrapper request, + ) { + return _runSafely( + () => _client + .getPrecompiledObjects( + _getListOfExamplesRequestToGrpcRequest(request)) + .then((response) => GetListOfExampleResponse( + _toClientCategories(response.sdkCategories))), + ); + } + + @override + Future getExample(GetExampleRequestWrapper request) { + return _runSafely( + () => _client + .getPrecompiledObjectCode(_getExampleRequestToGrpcRequest(request)) + .then((response) => GetExampleResponse(response.code)), + ); + } + + @override + Future getExampleOutput(GetExampleRequestWrapper request) { + return _runSafely( + () => _client + .getPrecompiledObjectOutput(_getExampleRequestToGrpcRequest(request)) + .then((response) => OutputResponse(response.output)), + ); + } + + Future _runSafely(Future Function() invoke) { + try { + return invoke(); + } on GrpcError catch (error) { + throw Exception(error.message); + } + } + + grpc.GetPrecompiledObjectsRequest _getListOfExamplesRequestToGrpcRequest( + GetListOfExamplesRequestWrapper request, + ) { + return grpc.GetPrecompiledObjectsRequest() + ..category = request.category ?? '' + ..sdk = request.sdk == null + ? grpc.Sdk.SDK_UNSPECIFIED + : _getGrpcSdk(request.sdk!); + } + + grpc.GetPrecompiledObjectRequest _getExampleRequestToGrpcRequest( + GetExampleRequestWrapper request, + ) { + return grpc.GetPrecompiledObjectRequest()..cloudPath = request.path; + } + + grpc.Sdk _getGrpcSdk(SDK sdk) { + switch (sdk) { + case SDK.java: + return grpc.Sdk.SDK_JAVA; + case SDK.go: + return grpc.Sdk.SDK_GO; + case SDK.python: + return grpc.Sdk.SDK_PYTHON; + case SDK.scio: + return grpc.Sdk.SDK_SCIO; + } + } + + SDK _getAppSdk(grpc.Sdk sdk) { + switch (sdk) { + case grpc.Sdk.SDK_JAVA: + return SDK.java; + case grpc.Sdk.SDK_GO: + return SDK.go; + case grpc.Sdk.SDK_PYTHON: + return SDK.python; + case grpc.Sdk.SDK_SCIO: + return SDK.scio; + default: + return SDK.java; + } + } + + ExampleType _exampleTypeFromString(grpc.PrecompiledObjectType type) { + switch (type) { + case grpc.PrecompiledObjectType.PRECOMPILED_OBJECT_TYPE_EXAMPLE: + return ExampleType.example; + case grpc.PrecompiledObjectType.PRECOMPILED_OBJECT_TYPE_KATA: + return ExampleType.kata; + case grpc.PrecompiledObjectType.PRECOMPILED_OBJECT_TYPE_UNIT_TEST: + return ExampleType.test; + case grpc.PrecompiledObjectType.PRECOMPILED_OBJECT_TYPE_UNSPECIFIED: + return ExampleType.all; + default: + return ExampleType.example; + } + } + + Map> _toClientCategories( + List response, + ) { + Map> sdkCategoriesMap = {}; + List>> entries = []; + for (var sdkMap in response) { + SDK sdk = _getAppSdk(sdkMap.sdk); + List categoriesForSdk = []; + for (var category in sdkMap.categories) { + List examples = category.precompiledObjects + .map((e) => ExampleModel( + name: e.name, + description: e.description, + type: _exampleTypeFromString(e.type), + path: e.cloudPath, + )) + .toList(); + categoriesForSdk.add(CategoryModel( + name: category.categoryName, + examples: examples, + )); + } + entries.add(MapEntry( + sdk, + categoriesForSdk, + )); + } + sdkCategoriesMap.addEntries(entries); + return sdkCategoriesMap; + } +} diff --git a/playground/frontend/lib/modules/examples/repositories/example_repository.dart b/playground/frontend/lib/modules/examples/repositories/example_repository.dart index 7fdc641d885d..fb003e5e64a4 100644 --- a/playground/frontend/lib/modules/examples/repositories/example_repository.dart +++ b/playground/frontend/lib/modules/examples/repositories/example_repository.dart @@ -17,103 +17,34 @@ */ import 'package:playground/modules/examples/models/category_model.dart'; -import 'package:playground/modules/examples/models/example_model.dart'; +import 'package:playground/modules/examples/repositories/example_client/example_client.dart'; +import 'package:playground/modules/examples/repositories/models/get_example_request.dart'; +import 'package:playground/modules/examples/repositories/models/get_list_of_examples_request.dart'; import 'package:playground/modules/sdk/models/sdk.dart'; -const javaHelloWorld = '''class HelloWorld { - public static void main(String[] args) { - System.out.println("Hello World!"); - } -}'''; - -const pythonHelloWorld = 'print(‘Hello World’)'; - -const goHelloWorld = '''package main - -import "fmt" +class ExampleRepository { + late final ExampleClient _client; -// this is a comment + ExampleRepository(ExampleClient client) { + _client = client; + } -func main() { - fmt.Println("Hello World") -}'''; + Future>> getListOfExamples( + GetListOfExamplesRequestWrapper request, + ) async { + final result = await _client.getListOfExamples(request); + return result.categories; + } -const scioHelloWorld = ''' -object Hello { - def main(args: Array[String]) = { - println("Hello, world") - } -}'''; + Future getExampleSource(GetExampleRequestWrapper request) async { + final result = await _client.getExample(request); + return result.code; + } -class ExampleRepository { - List? getCategories() { - return const [ - CategoryModel('Side Inputs', [ - ExampleModel( - { - SDK.java: javaHelloWorld, - SDK.go: goHelloWorld, - SDK.python: pythonHelloWorld, - SDK.scio: scioHelloWorld, - }, - 'HelloWorld', - ExampleType.example, - ), - ExampleModel( - { - SDK.java: 'JAVA Source code 1', - SDK.go: 'GO Source code 1', - SDK.python: 'PYTHON Source code 1', - SDK.scio: 'SCIO Source code 1', - }, - 'KATA Source code 1', - ExampleType.kata, - ), - ]), - CategoryModel('Side Outputs', [ - ExampleModel( - { - SDK.java: 'JAVA Source code 2', - SDK.go: 'GO Source code 2', - SDK.python: 'PYTHON Source code 2', - SDK.scio: 'SCIO Source code 2', - }, - 'UNIT TEST Source code 2', - ExampleType.test, - ), - ExampleModel( - { - SDK.java: 'JAVA Source code 3', - SDK.go: 'GO Source code 3', - SDK.python: 'PYTHON Source code 3', - SDK.scio: 'SCIO Source code 3', - }, - 'EXAMPLE Source code 3', - ExampleType.example, - ), - ]), - CategoryModel('I/O', [ - ExampleModel( - { - SDK.java: 'JAVA Source code 4', - SDK.go: 'GO Source code 4', - SDK.python: 'PYTHON Source code 4', - SDK.scio: 'SCIO Source code 4', - }, - 'KATA Source code 4', - ExampleType.kata, - ), - ExampleModel( - { - SDK.java: 'JAVA Source code 5', - SDK.go: 'GO Source code 5', - SDK.python: 'PYTHON Source code 5', - SDK.scio: 'SCIO Source code 5', - }, - 'UNIT TEST Source code 5', - ExampleType.test, - ), - ]), - ]; + Future getExampleOutput( + GetExampleRequestWrapper request, + ) async { + final result = await _client.getExampleOutput(request); + return result.output; } } 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 new file mode 100644 index 000000000000..01ff465149d7 --- /dev/null +++ b/playground/frontend/lib/modules/examples/repositories/models/get_example_request.dart @@ -0,0 +1,23 @@ +/* + * 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. + */ + +class GetExampleRequestWrapper { + final String path; + + GetExampleRequestWrapper(this.path); +} diff --git a/playground/frontend/lib/modules/examples/repositories/models/get_example_response.dart b/playground/frontend/lib/modules/examples/repositories/models/get_example_response.dart new file mode 100644 index 000000000000..a8090a19908d --- /dev/null +++ b/playground/frontend/lib/modules/examples/repositories/models/get_example_response.dart @@ -0,0 +1,23 @@ +/* + * 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. + */ + +class GetExampleResponse { + final String code; + + GetExampleResponse(this.code); +} 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 new file mode 100644 index 000000000000..395c5d0cf91a --- /dev/null +++ b/playground/frontend/lib/modules/examples/repositories/models/get_list_of_examples_request.dart @@ -0,0 +1,26 @@ +/* + * 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/sdk/models/sdk.dart'; + +class GetListOfExamplesRequestWrapper { + final SDK? sdk; + final String? category; + + GetListOfExamplesRequestWrapper({required this.sdk, required this.category}); +} diff --git a/playground/frontend/lib/modules/examples/repositories/models/get_list_of_examples_response.dart b/playground/frontend/lib/modules/examples/repositories/models/get_list_of_examples_response.dart new file mode 100644 index 000000000000..609c61df3ad0 --- /dev/null +++ b/playground/frontend/lib/modules/examples/repositories/models/get_list_of_examples_response.dart @@ -0,0 +1,26 @@ +/* + * 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/examples/models/category_model.dart'; +import 'package:playground/modules/sdk/models/sdk.dart'; + +class GetListOfExampleResponse { + final Map> categories; + + GetListOfExampleResponse(this.categories); +} diff --git a/playground/frontend/lib/modules/output/components/output_header/output_placements.dart b/playground/frontend/lib/modules/output/components/output_header/output_placements.dart index c55a66729b29..67d127d7c262 100644 --- a/playground/frontend/lib/modules/output/components/output_header/output_placements.dart +++ b/playground/frontend/lib/modules/output/components/output_header/output_placements.dart @@ -37,7 +37,7 @@ class OutputPlacements extends StatelessWidget { children: OutputPlacement.values .map( (placement) => Semantics( - label: '$kOutputPlacementSemantic ${placement.name}', + label: '$kOutputPlacementSemantic ${placement.name}', child: IconButton( splashRadius: kIconButtonSplashRadius, icon: SvgPicture.asset( diff --git a/playground/frontend/lib/modules/sdk/components/sdk_selector.dart b/playground/frontend/lib/modules/sdk/components/sdk_selector.dart index 6f034cef8d92..9fbd18850427 100644 --- a/playground/frontend/lib/modules/sdk/components/sdk_selector.dart +++ b/playground/frontend/lib/modules/sdk/components/sdk_selector.dart @@ -19,10 +19,14 @@ import 'package:flutter/material.dart'; import 'package:playground/components/dropdown_button/dropdown_button.dart'; import 'package:playground/constants/sizes.dart'; +import 'package:playground/modules/examples/models/example_model.dart'; import 'package:playground/modules/sdk/components/sdk_selector_row.dart'; import 'package:playground/modules/sdk/models/sdk.dart'; +import 'package:playground/pages/playground/states/examples_state.dart'; +import 'package:provider/provider.dart'; typedef SetSdk = void Function(SDK sdk); +typedef SetExample = void Function(ExampleModel example); const kSdkSelectorLabel = 'Select SDK Dropdown'; @@ -32,9 +36,14 @@ const double kHeight = 172; class SDKSelector extends StatelessWidget { final SDK sdk; final SetSdk setSdk; + final SetExample setExample; - const SDKSelector({Key? key, required this.sdk, required this.setSdk}) - : super(key: key); + const SDKSelector({ + Key? key, + required this.sdk, + required this.setSdk, + required this.setExample, + }) : super(key: key); @override Widget build(BuildContext context) { @@ -51,12 +60,15 @@ class SDKSelector extends StatelessWidget { ...SDK.values.map((SDK value) { return SizedBox( width: double.infinity, - child: SdkSelectorRow( - sdk: value, - onSelect: () { - close(); - setSdk(value); - }, + child: Consumer( + builder: (context, state, child) => SdkSelectorRow( + sdk: value, + onSelect: () { + close(); + setSdk(value); + setExample(state.defaultExamplesMap![value]!); + }, + ), ), ); }).toList() diff --git a/playground/frontend/lib/pages/playground/components/playground_page_providers.dart b/playground/frontend/lib/pages/playground/components/playground_page_providers.dart index 612e12894f20..464c9ef712f6 100644 --- a/playground/frontend/lib/pages/playground/components/playground_page_providers.dart +++ b/playground/frontend/lib/pages/playground/components/playground_page_providers.dart @@ -19,6 +19,7 @@ import 'package:flutter/material.dart'; import 'package:playground/modules/editor/repository/code_repository/code_client/grpc_code_client.dart'; import 'package:playground/modules/editor/repository/code_repository/code_repository.dart'; +import 'package:playground/modules/examples/repositories/example_client/grpc_example_client.dart'; import 'package:playground/modules/examples/repositories/example_repository.dart'; import 'package:playground/modules/output/models/output_placement_state.dart'; import 'package:playground/pages/playground/states/examples_state.dart'; @@ -26,6 +27,8 @@ import 'package:playground/pages/playground/states/playground_state.dart'; import 'package:provider/provider.dart'; final CodeRepository kCodeRepository = CodeRepository(GrpcCodeClient()); +final ExampleRepository kExampleRepository = + ExampleRepository(GrpcExampleClient()); class PlaygroundPageProviders extends StatelessWidget { final Widget child; @@ -40,7 +43,7 @@ class PlaygroundPageProviders extends StatelessWidget { return MultiProvider( providers: [ ChangeNotifierProvider( - create: (context) => ExampleState(ExampleRepository()), + create: (context) => ExampleState(kExampleRepository)..init(), ), ChangeNotifierProxyProvider( create: (context) => PlaygroundState(codeRepository: kCodeRepository), @@ -48,12 +51,15 @@ class PlaygroundPageProviders extends StatelessWidget { if (playground == null) { return PlaygroundState(codeRepository: kCodeRepository); } - if ((exampleState.categories?.isNotEmpty ?? false) && + + if (exampleState.sdkCategories != null && playground.selectedExample == null) { + final defaultExample = + exampleState.defaultExamplesMap![playground.sdk]!; return PlaygroundState( codeRepository: kCodeRepository, sdk: playground.sdk, - selectedExample: exampleState.categories?.first.examples.first, + selectedExample: defaultExample, ); } return playground; diff --git a/playground/frontend/lib/pages/playground/playground_page.dart b/playground/frontend/lib/pages/playground/playground_page.dart index ab20a0f0f796..03730d6df0e7 100644 --- a/playground/frontend/lib/pages/playground/playground_page.dart +++ b/playground/frontend/lib/pages/playground/playground_page.dart @@ -52,13 +52,17 @@ class PlaygroundPage extends StatelessWidget { Consumer( builder: (context, state, child) { return ExampleSelector( - changeSelectorVisibility: state.changeSelectorVisibility, + changeSelectorVisibility: + state.changeSelectorVisibility, isSelectorOpened: state.isSelectorOpened, - categories: state.categories!, ); }, ), - SDKSelector(sdk: state.sdk, setSdk: state.setSdk), + SDKSelector( + sdk: state.sdk, + setSdk: state.setSdk, + setExample: state.setExample, + ), const NewExampleAction(), ResetAction(reset: state.reset), ], diff --git a/playground/frontend/lib/pages/playground/states/example_selector_state.dart b/playground/frontend/lib/pages/playground/states/example_selector_state.dart index c4718e33215d..4e034535f366 100644 --- a/playground/frontend/lib/pages/playground/states/example_selector_state.dart +++ b/playground/frontend/lib/pages/playground/states/example_selector_state.dart @@ -19,17 +19,20 @@ import 'package:flutter/material.dart'; import 'package:playground/modules/examples/models/category_model.dart'; import 'package:playground/modules/examples/models/example_model.dart'; +import 'package:playground/pages/playground/states/playground_state.dart'; import 'examples_state.dart'; class ExampleSelectorState with ChangeNotifier { final ExampleState _exampleState; + final PlaygroundState _playgroundState; ExampleType _selectedFilterType; String _filterText; List categories; ExampleSelectorState( this._exampleState, + this._playgroundState, this.categories, [ this._selectedFilterType = ExampleType.all, this._filterText = '', @@ -55,10 +58,11 @@ class ExampleSelectorState with ChangeNotifier { } sortCategories() { - final categories = _exampleState.categories!; + final categories = _exampleState.getCategories(_playgroundState.sdk)!; final sortedCategories = categories .map((category) => CategoryModel( - category.name, _sortCategoryExamples(category.examples))) + name: category.name, + examples: _sortCategoryExamples(category.examples))) .where((category) => category.examples.isNotEmpty) .toList(); setCategories(sortedCategories); diff --git a/playground/frontend/lib/pages/playground/states/examples_state.dart b/playground/frontend/lib/pages/playground/states/examples_state.dart index 4e3641c1d3ab..796058808c58 100644 --- a/playground/frontend/lib/pages/playground/states/examples_state.dart +++ b/playground/frontend/lib/pages/playground/states/examples_state.dart @@ -18,19 +18,55 @@ import 'package:flutter/material.dart'; import 'package:playground/modules/examples/models/category_model.dart'; +import 'package:playground/modules/examples/models/example_model.dart'; import 'package:playground/modules/examples/repositories/example_repository.dart'; +import 'package:playground/modules/examples/repositories/models/get_example_request.dart'; +import 'package:playground/modules/examples/repositories/models/get_list_of_examples_request.dart'; +import 'package:playground/modules/sdk/models/sdk.dart'; class ExampleState with ChangeNotifier { final ExampleRepository _exampleRepository; - List? categories; + Map>? sdkCategories; + Map? defaultExamplesMap; bool isSelectorOpened = false; - ExampleState(this._exampleRepository) { + ExampleState(this._exampleRepository); + + init() { _loadCategories(); } - _loadCategories() { - categories = _exampleRepository.getCategories() ?? []; + List? getCategories(SDK sdk) { + return sdkCategories?[sdk] ?? []; + } + + Future getExampleOutput(String id) async { + String output = await _exampleRepository.getExampleOutput( + GetExampleRequestWrapper(id), + ); + return output; + } + + Future getExampleSource(String id) async { + String source = await _exampleRepository.getExampleSource( + GetExampleRequestWrapper(id), + ); + return source; + } + + Future loadExampleInfo(ExampleModel example) async { + String source = await getExampleSource(example.path); + example.setSource(source); + final outputs = await getExampleOutput(example.path); + example.setOutputs(outputs); + return example; + } + + _loadCategories() async { + sdkCategories = await _exampleRepository.getListOfExamples( + GetListOfExamplesRequestWrapper(sdk: null, category: null), + ); + await _loadDefaultExamples(sdkCategories); notifyListeners(); } @@ -38,4 +74,19 @@ class ExampleState with ChangeNotifier { isSelectorOpened = !isSelectorOpened; notifyListeners(); } + + _loadDefaultExamples(sdkCategories) async { + defaultExamplesMap = {}; + List> entries = []; + for (SDK sdk in SDK.values) { + ExampleModel? defaultExample = sdkCategories![sdk]?.first.examples.first; + if (defaultExample != null) { + // load source and output async + loadExampleInfo(defaultExample); + entries.add(MapEntry(sdk, defaultExample)); + } + } + defaultExamplesMap?.addEntries(entries); + notifyListeners(); + } } diff --git a/playground/frontend/lib/pages/playground/states/playground_state.dart b/playground/frontend/lib/pages/playground/states/playground_state.dart index d435da8930bc..99a06f1732a2 100644 --- a/playground/frontend/lib/pages/playground/states/playground_state.dart +++ b/playground/frontend/lib/pages/playground/states/playground_state.dart @@ -36,11 +36,6 @@ class PlaygroundState with ChangeNotifier { RunCodeResult? _result; DateTime? resetKey; - String get examplesTitle { - final name = _selectedExample?.name ?? ''; - return name.substring(0, min(kTitleLength, name.length)); - } - PlaygroundState({ SDK sdk = SDK.java, ExampleModel? selectedExample, @@ -48,10 +43,15 @@ class PlaygroundState with ChangeNotifier { }) { _selectedExample = selectedExample; _sdk = sdk; - _source = _selectedExample?.sources[_sdk] ?? ''; + _source = _selectedExample?.source ?? ''; _codeRepository = codeRepository; } + String get examplesTitle { + final name = _selectedExample?.name ?? kTitle; + return name.substring(0, min(kTitleLength, name.length)); + } + ExampleModel? get selectedExample => _selectedExample; SDK get sdk => _sdk; @@ -64,7 +64,7 @@ class PlaygroundState with ChangeNotifier { setExample(ExampleModel example) { _selectedExample = example; - _source = example.sources[_sdk] ?? ''; + _source = example.source ?? ''; notifyListeners(); } @@ -83,7 +83,7 @@ class PlaygroundState with ChangeNotifier { } reset() { - _source = _selectedExample?.sources[_sdk] ?? ''; + _source = _selectedExample?.source ?? ''; resetKey = DateTime.now(); notifyListeners(); } @@ -97,11 +97,20 @@ class PlaygroundState with ChangeNotifier { } void runCode() { - _codeRepository - ?.runCode(RunCodeRequestWrapper(code: source, sdk: sdk)) - .listen((event) { - _result = event; + if (_selectedExample?.source == source && + _selectedExample?.outputs != null) { + _result = RunCodeResult( + status: RunCodeStatus.finished, + output: _selectedExample!.outputs ?? 'anti-precompiled output', + ); notifyListeners(); - }); + } else { + _codeRepository + ?.runCode(RunCodeRequestWrapper(code: source, sdk: sdk)) + .listen((event) { + _result = event; + notifyListeners(); + }); + } } } diff --git a/playground/frontend/pubspec.lock b/playground/frontend/pubspec.lock index 5a116d5d1bc4..937e9367ec02 100644 --- a/playground/frontend/pubspec.lock +++ b/playground/frontend/pubspec.lock @@ -344,7 +344,7 @@ packages: name: json_annotation url: "https://pub.dartlang.org" source: hosted - version: "4.2.0" + version: "4.3.0" linked_scroll_controller: dependency: transitive description: 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 4cf7302e111b..21259a5fcabf 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 @@ -17,86 +17,99 @@ */ import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; import 'package:playground/modules/examples/models/example_model.dart'; +import 'package:playground/modules/examples/repositories/example_client/example_client.dart'; import 'package:playground/modules/examples/repositories/example_repository.dart'; import 'package:playground/pages/playground/states/example_selector_state.dart'; import 'package:playground/pages/playground/states/examples_state.dart'; +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() { test( 'ExampleSelector state should notify all listeners about filter type change', () { - final exampleState = ExampleState(ExampleRepository()); - final state = ExampleSelectorState(exampleState, []); + final exampleState = ExampleState(ExampleRepository(client)); + final state = ExampleSelectorState(exampleState, playgroundState, []); state.addListener(() { expect(state.selectedFilterType, ExampleType.example); }); - state.setSelectedFilterType(ExampleType.example); - }); + state.setSelectedFilterType(ExampleType.example); + }); test( 'ExampleSelector state should notify all listeners about categories change', - () { - final exampleState = ExampleState(ExampleRepository()); - final state = ExampleSelectorState(exampleState, []); - state.addListener(() { - expect(state.categories, []); - }); - state.setCategories([]); - }); + () { + final exampleState = ExampleState(ExampleRepository(client)); + final state = ExampleSelectorState(exampleState, playgroundState, []); + state.addListener(() { + expect(state.categories, []); + }); + state.setCategories([]); + }); test( 'ExampleSelector state sortCategories should:' - '- update categories and notify all listeners,' - 'but should NOT:' - '- wait for full name of example,' - '- be sensitive for register,' - '- affect Example state categories', () { - final exampleState = ExampleState(ExampleRepository()); + '- update categories and notify all listeners,' + 'but should NOT:' + '- affect Example state categories', () { + final exampleState = ExampleState(ExampleRepository(client)); final state = ExampleSelectorState( exampleState, - exampleState.categories!, - ExampleType.example, - 'hLo' + playgroundState, + [], ); state.addListener(() { expect(state.categories, []); - expect(exampleState.categories, exampleState.categories); + expect(exampleState.sdkCategories, exampleState.sdkCategories); }); state.sortCategories(); }); test( 'ExampleSelector state sortExamplesByType should:' - '- update categories,' - '- notify all listeners,' - 'but should NOT:' - '- affect Example state categories', () { - final exampleState = ExampleState(ExampleRepository()); - final state = ExampleSelectorState(exampleState, exampleState.categories!); + '- update categories,' + '- notify all listeners,' + 'but should NOT:' + '- affect Example state categories', () { + final exampleState = ExampleState(ExampleRepository(client)); + final state = ExampleSelectorState( + exampleState, + playgroundState, + categoriesMock, + ); state.addListener(() { expect(state.categories, examplesSortedByTypeMock); - expect(exampleState.categories, exampleState.categories); + expect(exampleState.sdkCategories, exampleState.sdkCategories); }); state.sortExamplesByType(unsortedExamples, ExampleType.kata); }); 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()); - final state = ExampleSelectorState(exampleState, exampleState.categories!); + '- 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)); + final state = ExampleSelectorState( + exampleState, + playgroundState, + categoriesMock, + ); state.addListener(() { expect(state.categories, examplesSortedByNameMock); - expect(exampleState.categories, exampleState.categories); + expect(exampleState.sdkCategories, exampleState.sdkCategories); }); - state.sortExamplesByName(unsortedExamples, 'eLLoWoRl'); + state.sortExamplesByName(unsortedExamples, 'X1'); }); } 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 new file mode 100644 index 000000000000..204637e57e30 --- /dev/null +++ b/playground/frontend/test/pages/playground/states/example_selector_state_test.mocks.dart @@ -0,0 +1,89 @@ +/* + * 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/example_selector_state_test.dart. +// Do not manually edit this file. + +import 'dart:async' as _i6; + +import 'package:mockito/mockito.dart' as _i1; +import 'package:playground/modules/editor/repository/code_repository/code_client/output_response.dart' + as _i4; +import 'package:playground/modules/examples/repositories/example_client/example_client.dart' + as _i5; +import 'package:playground/modules/examples/repositories/models/get_example_request.dart' + as _i8; +import 'package:playground/modules/examples/repositories/models/get_example_response.dart' + as _i3; +import 'package:playground/modules/examples/repositories/models/get_list_of_examples_request.dart' + as _i7; +import 'package:playground/modules/examples/repositories/models/get_list_of_examples_response.dart' + as _i2; + +// 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 _FakeGetExampleResponse_1 extends _i1.Fake + implements _i3.GetExampleResponse {} + +class _FakeOutputResponse_2 extends _i1.Fake implements _i4.OutputResponse {} + +/// A class which mocks [ExampleClient]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockExampleClient extends _i1.Mock implements _i5.ExampleClient { + MockExampleClient() { + _i1.throwOnMissingStub(this); + } + + @override + _i6.Future<_i2.GetListOfExampleResponse> getListOfExamples( + _i7.GetListOfExamplesRequestWrapper? request) => + (super.noSuchMethod(Invocation.method(#getListOfExamples, [request]), + returnValue: Future<_i2.GetListOfExampleResponse>.value( + _FakeGetListOfExampleResponse_0())) + as _i6.Future<_i2.GetListOfExampleResponse>); + + @override + _i6.Future<_i3.GetExampleResponse> getExample( + _i8.GetExampleRequestWrapper? request) => + (super.noSuchMethod(Invocation.method(#getExample, [request]), + returnValue: Future<_i3.GetExampleResponse>.value( + _FakeGetExampleResponse_1())) + as _i6.Future<_i3.GetExampleResponse>); + + @override + _i6.Future<_i4.OutputResponse> getExampleOutput( + _i8.GetExampleRequestWrapper? request) => + (super.noSuchMethod(Invocation.method(#getExampleOutput, [request]), + returnValue: + Future<_i4.OutputResponse>.value(_FakeOutputResponse_2())) + as _i6.Future<_i4.OutputResponse>); + + @override + String toString() => super.toString(); +} 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 f3a5b3456cd6..ee86cabf5037 100644 --- a/playground/frontend/test/pages/playground/states/mocks/categories_mock.dart +++ b/playground/frontend/test/pages/playground/states/mocks/categories_mock.dart @@ -18,143 +18,20 @@ 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'; -const javaHelloWorld = '''class HelloWorld { - public static void main(String[] args) { - System.out.println("Hello World!"); - } -}'''; +import 'example_mock.dart'; -const pythonHelloWorld = 'print(‘Hello World’)'; - -const goHelloWorld = '''package main - -import "fmt" - -// this is a comment - -func main() { - fmt.Println("Hello World") -}'''; - -const scioHelloWorld = ''' -object Hello { - def main(args: Array[String]) = { - println("Hello, world") - } -}'''; - -const List sortedCategories = [ - CategoryModel('Side Inputs', [ - ExampleModel( - { - SDK.java: javaHelloWorld, - SDK.go: goHelloWorld, - SDK.python: pythonHelloWorld, - SDK.scio: scioHelloWorld, - }, - 'HelloWorld', - ExampleType.example, - ), - ]) +final categoriesMock = [ + CategoryModel(name: 'Sorted', examples: [exampleMock1]), + CategoryModel(name: 'Unsorted', examples: [exampleMock2]), ]; -const List unsortedExamples = [ - ExampleModel( - { - SDK.java: javaHelloWorld, - SDK.go: goHelloWorld, - SDK.python: pythonHelloWorld, - SDK.scio: scioHelloWorld, - }, - 'HelloWorld', - ExampleType.example, - ), - ExampleModel( - { - SDK.java: 'JAVA Source code 1', - SDK.go: 'GO Source code 1', - SDK.python: 'PYTHON Source code 1', - SDK.scio: 'SCIO Source code 1', - }, - 'KATA Source code 1', - ExampleType.kata, - ), - ExampleModel( - { - SDK.java: 'JAVA Source code 2', - SDK.go: 'GO Source code 2', - SDK.python: 'PYTHON Source code 2', - SDK.scio: 'SCIO Source code 2', - }, - 'UNIT TEST Source code 2', - ExampleType.test, - ), - ExampleModel( - { - SDK.java: 'JAVA Source code 3', - SDK.go: 'GO Source code 3', - SDK.python: 'PYTHON Source code 3', - SDK.scio: 'SCIO Source code 3', - }, - 'EXAMPLE Source code 3', - ExampleType.example, - ), - ExampleModel( - { - SDK.java: 'JAVA Source code 4', - SDK.go: 'GO Source code 4', - SDK.python: 'PYTHON Source code 4', - SDK.scio: 'SCIO Source code 4', - }, - 'KATA Source code 4', - ExampleType.kata, - ), - ExampleModel( - { - SDK.java: 'JAVA Source code 5', - SDK.go: 'GO Source code 5', - SDK.python: 'PYTHON Source code 5', - SDK.scio: 'SCIO Source code 5', - }, - 'UNIT TEST Source code 5', - ExampleType.test, - ), +final List sortedCategories = [ + CategoryModel(name: 'Sorted', examples: [exampleMock1]), ]; -const List examplesSortedByTypeMock = [ - ExampleModel( - { - SDK.java: 'JAVA Source code 1', - SDK.go: 'GO Source code 1', - SDK.python: 'PYTHON Source code 1', - SDK.scio: 'SCIO Source code 1', - }, - 'KATA Source code 1', - ExampleType.kata, - ), - ExampleModel( - { - SDK.java: 'JAVA Source code 4', - SDK.go: 'GO Source code 4', - SDK.python: 'PYTHON Source code 4', - SDK.scio: 'SCIO Source code 4', - }, - 'KATA Source code 4', - ExampleType.kata, - ), -]; +final List unsortedExamples = [exampleMock1, exampleMock2]; -const List examplesSortedByNameMock = [ - ExampleModel( - { - SDK.java: javaHelloWorld, - SDK.go: goHelloWorld, - SDK.python: pythonHelloWorld, - SDK.scio: scioHelloWorld, - }, - 'HelloWorld', - ExampleType.example, - ), -]; +final List examplesSortedByTypeMock = [exampleMock2]; + +final List examplesSortedByNameMock = [exampleMock1]; 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 8eb808574a48..8e5bc277a199 100644 --- a/playground/frontend/test/pages/playground/states/mocks/example_mock.dart +++ b/playground/frontend/test/pages/playground/states/mocks/example_mock.dart @@ -17,22 +17,19 @@ */ import 'package:playground/modules/examples/models/example_model.dart'; -import 'package:playground/modules/sdk/models/sdk.dart'; -const javaExample = 'java example'; - -const pythonExample = 'python example'; - -const goExample = 'go example'; - -const sdkMap = { - SDK.java: javaExample, - SDK.go: goExample, - SDK.python: pythonExample, -}; +final ExampleModel exampleMock1 = ExampleModel( + source: 'ex1', + name: 'Example', + type: ExampleType.example, + description: 'description', + path: 'SDK/Category/Name', +); -const ExampleModel exampleMock = ExampleModel( - sdkMap, - 'Example', - ExampleType.example, +final ExampleModel exampleMock2 = ExampleModel( + source: 'ex2', + name: 'Kata', + type: ExampleType.kata, + description: 'description', + path: 'SDK/Category/Name', ); 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 95909e14cead..6516a8ffa6dd 100644 --- a/playground/frontend/test/pages/playground/states/playground_state_test.dart +++ b/playground/frontend/test/pages/playground/states/playground_state_test.dart @@ -39,10 +39,10 @@ void main() { test( 'Playground state reset should reset source to example notify all listeners', () { - final state = PlaygroundState(sdk: SDK.go, selectedExample: exampleMock); + final state = PlaygroundState(sdk: SDK.go, selectedExample: exampleMock1); state.setSource('source'); state.addListener(() { - expect(state.source, goExample); + expect(state.source, exampleMock1.source); }); state.reset(); }); @@ -53,9 +53,9 @@ void main() { final state = PlaygroundState(sdk: SDK.go); state.addListener(() { expect(state.sdk, SDK.go); - expect(state.source, exampleMock.sources[SDK.go]); - expect(state.selectedExample, exampleMock); + expect(state.source, exampleMock1.source); + expect(state.selectedExample, exampleMock1); }); - state.setExample(exampleMock); + state.setExample(exampleMock1); }); }