This is an automated email from the ASF dual-hosted git repository. damccorm pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/beam.git
The following commit(s) were added to refs/heads/master by this push: new 1c4e4241c2a [Playground][Frontend] Run timer fix; CodeRunner and OutputType extraction. (#24871) 1c4e4241c2a is described below commit 1c4e4241c2a4571c7d6c9f293133b114a9e00844 Author: Darkhan Nausharipov <31556582+naushari...@users.noreply.github.com> AuthorDate: Thu Jan 19 19:59:31 2023 +0600 [Playground][Frontend] Run timer fix; CodeRunner and OutputType extraction. (#24871) * timer fix rough draft (#24617) * comments (#24617) * comments (1) (#24617) * cancel run on reset (#24617) * regenerated mocks (#24617) * runStopDate (#24617) * OutputFilterTypeController (#24617) * resetErrorMessageText (#24617) Co-authored-by: alexeyinkin <l...@inkin.ru> * resetErrorMessageText (#24617) Co-authored-by: alexeyinkin <l...@inkin.ru> * comments (#24617) * missing license (#24617) * a commit for re-running rat check on github * deleted comment "a commit for re-running rat check on github" * fixes after merge with master (#24617) * merge fixes (#24617) * regenerated yaml files (#24617) * snippetEditingControllerGetter refinement (#24617) Co-authored-by: darkhan.nausharipov <darkhan.naushari...@kzn.akvelon.com> Co-authored-by: alexeyinkin <l...@inkin.ru> --- .../shortcuts/constants/global_shortcuts.dart | 2 +- .../widgets/close_listener.dart | 4 +- .../widgets/editor_textarea_wrapper.dart | 7 +- playground/frontend/lib/utils/analytics_utils.dart | 2 +- .../playground_components/assets/symbols/go.g.yaml | 89 ++++- .../assets/symbols/java.g.yaml | 415 +++++++++++++++++++-- .../assets/symbols/python.g.yaml | 36 +- .../lib/src/controllers/code_runner.dart | 165 ++++++++ .../output_filter_type_controller.dart} | 24 +- .../lib/src/controllers/playground_controller.dart | 210 ++--------- .../lib/src/models/outputs.dart | 1 - .../lib/src/widgets/output/output_area.dart | 62 +-- .../lib/src/widgets/output/output_tab.dart | 10 +- .../lib/src/widgets/output/output_tabs.dart | 5 +- .../src/widgets/output/result_filter_bubble.dart | 6 +- .../src/widgets/output/result_filter_popover.dart | 2 +- .../lib/src/widgets/periodic_builder.dart} | 42 ++- .../lib/src/widgets/run_button.dart | 142 ++++--- .../lib/src/widgets/run_or_cancel_button.dart | 8 +- .../examples_loader_test.mocks.dart | 301 +++++++-------- .../controllers/playground_controller_test.dart | 19 +- 21 files changed, 1006 insertions(+), 546 deletions(-) diff --git a/playground/frontend/lib/modules/shortcuts/constants/global_shortcuts.dart b/playground/frontend/lib/modules/shortcuts/constants/global_shortcuts.dart index 03797eaff3a..00687271773 100644 --- a/playground/frontend/lib/modules/shortcuts/constants/global_shortcuts.dart +++ b/playground/frontend/lib/modules/shortcuts/constants/global_shortcuts.dart @@ -40,7 +40,7 @@ final kClearOutputShortcut = BeamShortcut( onInvoke: (_) => Provider.of<PlaygroundController>( context, listen: false, - ).clearOutput(), + ).codeRunner.clearResult(), ), ); diff --git a/playground/frontend/lib/pages/standalone_playground/widgets/close_listener.dart b/playground/frontend/lib/pages/standalone_playground/widgets/close_listener.dart index ba2a19a7ae2..0a370f1334c 100644 --- a/playground/frontend/lib/pages/standalone_playground/widgets/close_listener.dart +++ b/playground/frontend/lib/pages/standalone_playground/widgets/close_listener.dart @@ -36,7 +36,9 @@ class _CloseListenerState extends State<CloseListener> { void initState() { WidgetsBinding.instance.addPostFrameCallback((timeStamp) { html.window.onBeforeUnload.listen((event) async { - Provider.of<PlaygroundController>(context, listen: false).cancelRun(); + Provider.of<PlaygroundController>(context, listen: false) + .codeRunner + .cancelRun(); }); }); super.initState(); diff --git a/playground/frontend/lib/pages/standalone_playground/widgets/editor_textarea_wrapper.dart b/playground/frontend/lib/pages/standalone_playground/widgets/editor_textarea_wrapper.dart index 86b6a5045d6..552064498ea 100644 --- a/playground/frontend/lib/pages/standalone_playground/widgets/editor_textarea_wrapper.dart +++ b/playground/frontend/lib/pages/standalone_playground/widgets/editor_textarea_wrapper.dart @@ -35,7 +35,8 @@ class CodeTextAreaWrapper extends StatelessWidget { @override Widget build(BuildContext context) { - if (playgroundController.result?.errorMessage?.isNotEmpty ?? false) { + if (playgroundController.codeRunner.result?.errorMessage?.isNotEmpty ?? + false) { WidgetsBinding.instance.addPostFrameCallback((_) { _handleError(context, playgroundController); }); @@ -83,11 +84,11 @@ class CodeTextAreaWrapper extends StatelessWidget { void _handleError(BuildContext context, PlaygroundController controller) { PlaygroundComponents.toastNotifier.add( Toast( - description: controller.result?.errorMessage ?? '', + description: controller.codeRunner.result?.errorMessage ?? '', title: AppLocalizations.of(context)!.runCode, type: ToastType.error, ), ); - controller.resetError(); + controller.resetErrorMessageText(); } } diff --git a/playground/frontend/lib/utils/analytics_utils.dart b/playground/frontend/lib/utils/analytics_utils.dart index 786b54ff382..b5c2ba0dc35 100644 --- a/playground/frontend/lib/utils/analytics_utils.dart +++ b/playground/frontend/lib/utils/analytics_utils.dart @@ -20,7 +20,7 @@ import 'package:playground_components/playground_components.dart'; String getAnalyticsExampleName(PlaygroundController controller) { final customCodeName = 'Custom code, sdk ${controller.sdk?.title}'; - if (controller.isExampleChanged) { + if (controller.codeRunner.isExampleChanged) { return customCodeName; } return controller.selectedExample?.path ?? customCodeName; diff --git a/playground/frontend/playground_components/assets/symbols/go.g.yaml b/playground/frontend/playground_components/assets/symbols/go.g.yaml index 4df541c1a86..cf3b2a0c9c9 100644 --- a/playground/frontend/playground_components/assets/symbols/go.g.yaml +++ b/playground/frontend/playground_components/assets/symbols/go.g.yaml @@ -242,6 +242,7 @@ - Fatalf - Fatalln - FetchSize + - FieldIndexByTag - File - Flatten - FreeDiskSpace @@ -348,6 +349,7 @@ - ImpulseValue - InboundTagToNode - Include + - InferFieldNames - Info - Infof - Infoln @@ -751,6 +753,7 @@ - SkipK - SkipPtr - SkipW + - SklearnModel - Smallest - SmallestPerKey - Source @@ -887,11 +890,18 @@ - Warnf - Warnln - WindowInto + - WithArgs - WithContext - WithContextf - WithExpansionAddr + - WithExtraPackages - WithIndexes - WithQueryLocation + - WithReadBucketAuto + - WithReadBundleSize + - WithReadFilter + - WithWriteBatchSize + - WithWriteOrdered - Wrap - WrapIterable - WrapMethods @@ -1401,6 +1411,10 @@ CancelJobResponse: - String properties: - State +Checkpoint: + properties: + - Reapply + - SR Class: methods: - String @@ -1668,7 +1682,6 @@ DataSink: - UID DataSource: methods: - - Checkpoint - Down - FinishBundle - ID @@ -1749,6 +1762,25 @@ Discard: - Up properties: - UID +DiscoverSchemaTransformRequest: + methods: + - Descriptor + - ProtoMessage + - ProtoReflect + - Reset + - String +DiscoverSchemaTransformResponse: + methods: + - Descriptor + - GetError + - GetSchemaTransformConfigs + - ProtoMessage + - ProtoReflect + - Reset + - String + properties: + - Error + - SchemaTransformConfigs DisplayData: methods: - Descriptor @@ -2173,6 +2205,7 @@ ExpansionResponse: - Transform ExpansionServiceClient: methods: + - DiscoverSchemaTransform - Expand ExpansionServiceRunner: methods: @@ -2182,6 +2215,7 @@ ExpansionServiceRunner: - String ExpansionServiceServer: methods: + - DiscoverSchemaTransform - Expand ExternalConfigurationPayload: methods: @@ -3195,6 +3229,7 @@ JobOptions: - Region - RetainDocker - ServiceAccountEmail + - Streaming - Subnetwork - TeardownPolicy - TempLocation @@ -3203,7 +3238,6 @@ JobOptions: - Update - Worker - WorkerHarnessThreads - - WorkerJar - WorkerRegion - WorkerZone - Zone @@ -3381,6 +3415,7 @@ LockRTracker: - GetRestriction - IsBounded - IsDone + - String - TryClaim - TrySplit properties: @@ -4237,6 +4272,10 @@ PlanSnapshot: Port: properties: - URL +PredictionResult: + properties: + - Example + - Inference PrepareJobRequest: methods: - Descriptor @@ -4694,6 +4733,11 @@ ReadModifyWriteStateSpec: - String properties: - CoderId +ReadOption: + properties: + - BucketAuto + - BundleSize + - Filter ReadOptions: properties: - IDAttribute @@ -4947,6 +4991,34 @@ SchemaProvider: - BuildDecoder - BuildEncoder - FromLogicalType +SchemaTransformConfig: + methods: + - Descriptor + - GetConfigSchema + - GetInputPcollectionNames + - GetOutputPcollectionNames + - ProtoMessage + - ProtoReflect + - Reset + - String + properties: + - ConfigSchema + - InputPcollectionNames + - OutputPcollectionNames +SchemaTransformPayload: + methods: + - Descriptor + - GetConfigurationRow + - GetConfigurationSchema + - GetIdentifier + - ProtoMessage + - ProtoReflect + - Reset + - String + properties: + - ConfigurationRow + - ConfigurationSchema + - Identifier Scope: methods: - ID @@ -5153,6 +5225,7 @@ SplitResult: - RI - RS - TId + - Unsuccessful SplittableDoFn: methods: - CreateInitialRestrictionFn @@ -6016,6 +6089,7 @@ Tracker: - GetRestriction - IsBounded - IsDone + - String - TryClaim - TrySplit Transaction: @@ -6304,7 +6378,6 @@ TypeMismatchError: - Error properties: - Got -U: {} UnimplementedArtifactRetrievalServiceServer: methods: - GetArtifact @@ -6334,6 +6407,7 @@ UnimplementedBeamFnWorkerStatusServer: - WorkerStatus UnimplementedExpansionServiceServer: methods: + - DiscoverSchemaTransform - Expand UnimplementedJobServiceServer: methods: @@ -6397,7 +6471,6 @@ UserFn: UserStateAdapter: methods: - NewStateProvider -V: {} Value: methods: - Clear @@ -6409,7 +6482,6 @@ Value: - Write properties: - Key -W: {} WallTimeWatermarkEstimator: methods: - CurrentWatermark @@ -6560,9 +6632,10 @@ WriteFilesPayload: - SideInputs - Sink - WindowedWrites +WriteOption: + properties: + - BatchSize + - Ordered Writer: methods: - SaveData -X: {} -"Y": {} -Z: {} diff --git a/playground/frontend/playground_components/assets/symbols/java.g.yaml b/playground/frontend/playground_components/assets/symbols/java.g.yaml index 1fe009d4367..345e11071b9 100644 --- a/playground/frontend/playground_components/assets/symbols/java.g.yaml +++ b/playground/frontend/playground_components/assets/symbols/java.g.yaml @@ -474,6 +474,7 @@ AvroIO: - withSchema - withShardNameTemplate - withSuffix + - withSyncInterval - withTempDirectory - withUsesReshuffle - withWindowedWrites @@ -683,9 +684,11 @@ BatchContextImpl: methods: - addProperties - addTags + - asMap - createDataset - datasetExists - discardDataset + - get - getArguments - getDataset - getFailureCollector @@ -703,6 +706,8 @@ BatchContextImpl: - getPluginProperties - getServiceURL - getStageName + - has + - iterator - loadPluginClass - newPluginInstance - provide @@ -711,6 +716,10 @@ BatchContextImpl: - removeMetadata - removeProperties - removeTags + - set + properties: + - DEFAULT_SCHEMA_FIELD_NAME + - DEFAULT_SCHEMA_RECORD_NAME BatchSinkContextImpl: methods: - addOutput @@ -1328,11 +1337,13 @@ BeamSqlPipelineOptionsRegistrar: - getPipelineOptions BeamSqlRelUtils: methods: + - explainLazily - getBeamRelInput - getErrorRowSchema - getInput - getNodeStats - toPCollection + - toString properties: - ERROR - ROW @@ -1600,7 +1611,6 @@ BigQueryDirectReadSchemaTransformProvider: - buildTransform - builder - expand - - getBigQueryServices - getQuery - getRowRestriction - getSelectedFields @@ -1791,6 +1801,27 @@ BigQueryStorageTableSource: - create - getEstimatedSizeBytes - populateDisplayData +BigQueryStorageWriteApiSchemaTransformProvider: + methods: + - build + - buildTransform + - builder + - expand + - getCreateDisposition + - getTable + - getTriggeringFrequencySeconds + - getUseAtLeastOnceSemantics + - getWriteDisposition + - identifier + - inputCollectionNames + - outputCollectionNames + - setBigQueryServices + - setCreateDisposition + - setTable + - setTriggeringFrequencySeconds + - setUseAtLeastOnceSemantics + - setWriteDisposition + - validate BigQueryTableProvider: methods: - buildBeamSqlTable @@ -1935,6 +1966,7 @@ BlockBasedSource: - getCurrentRecord - getFractionConsumed - getFractionOfBlockConsumed + - isAtSplitPoint - readNextBlock - readNextRecord BlockingCommitterImpl: @@ -2533,6 +2565,8 @@ CdapIO: - withKeyClass - withLocksDirPath - withPluginConfig + - withPullFrequencySec + - withStartOffset - withValueClass - write ChangeStreamDao: @@ -3584,10 +3618,34 @@ DebeziumIO: - withFormatFunction - withHostName - withMaxNumberOfRecords + - withMaxTimeToRun - withPassword - withPort - withSourceConnector - withUsername +DebeziumReadSchemaTransformProvider: + methods: + - build + - buildTransform + - builder + - expand + - getDatabase + - getDebeziumConnectionProperties + - getHost + - getPassword + - getPort + - getTable + - getUsername + - identifier + - inputCollectionNames + - outputCollectionNames + - setDatabase + - setDebeziumConnectionProperties + - setHost + - setPassword + - setPort + - setTable + - setUsername DebeziumTransformRegistrar: methods: - buildExternal @@ -3631,6 +3689,7 @@ DefaultBlobstoreClientBuilderFactory: - createBuilder DefaultFilenamePolicy: methods: + - constructName - decode - encode - equals @@ -3996,6 +4055,7 @@ DoFnSignatures: - usesBagState - usesBundleFinalizer - usesMapState + - usesMultimapState - usesOrderedListState - usesSetState - usesState @@ -4863,6 +4923,48 @@ FileSystems: - filteredExistingSrcs - resultDestinations - resultSources +FileWriteSchemaTransformConfiguration: + methods: + - build + - builder + - csvConfigurationBuilder + - getCharset + - getCompression + - getCompressionCodecName + - getCsvConfiguration + - getCsvFormat + - getFilenamePrefix + - getFilenameSuffix + - getFormat + - getNumShards + - getParquetConfiguration + - getPreamble + - getRootElement + - getRowGroupSize + - getShardNameTemplate + - getXmlConfiguration + - parquetConfigurationBuilder + - setCharset + - setCompression + - setCompressionCodecName + - setCsvConfiguration + - setCsvFormat + - setFilenamePrefix + - setFilenameSuffix + - setFormat + - setNumShards + - setParquetConfiguration + - setPreamble + - setRootElement + - setRowGroupSize + - setShardNameTemplate + - setXmlConfiguration + - xmlConfigurationBuilder +FileWriteSchemaTransformFormatProviders: + methods: + - buildTransform + - identifier + - loadProviders FillGaps: methods: - expand @@ -5113,6 +5215,7 @@ FnApiStateAccessor: - bindCombining - bindCombiningWithContext - bindMap + - bindMultimap - bindOrderedList - bindSet - bindValue @@ -5495,6 +5598,7 @@ GroupIntoBatches: methods: - apply - create + - createDefault - expand - getBatchSize - getBatchSizeBytes @@ -5509,8 +5613,11 @@ GroupIntoBatches: - onWindowExpiration - onWindowTimer - processElement + - toString + - withByteSize - withMaxBufferingDuration - withShardedKey + - withSize GrowableOffsetRangeTracker: methods: - getProgress @@ -6212,6 +6319,36 @@ JdbcIO: - withWriteResults - write - writeVoid +JdbcReadSchemaTransformProvider: + methods: + - build + - buildTransform + - builder + - expand + - getConnectionInitSql + - getConnectionProperties + - getDriverClassName + - getFetchSize + - getJdbcUrl + - getLocation + - getOutputParallelization + - getPassword + - getReadQuery + - getUsername + - identifier + - inputCollectionNames + - outputCollectionNames + - setConnectionInitSql + - setConnectionProperties + - setDriverClassName + - setFetchSize + - setJdbcUrl + - setLocation + - setOutputParallelization + - setPassword + - setReadQuery + - setUsername + - validate JdbcSchemaIOProvider: methods: - buildReader @@ -6226,6 +6363,34 @@ JdbcSchemaIOProvider: JdbcWriteResult: methods: - create +JdbcWriteSchemaTransformProvider: + methods: + - build + - buildTransform + - builder + - expand + - getAutosharding + - getConnectionInitSql + - getConnectionProperties + - getDriverClassName + - getJdbcUrl + - getLocation + - getPassword + - getUsername + - getWriteStatement + - identifier + - inputCollectionNames + - outputCollectionNames + - setAutosharding + - setConnectionInitSql + - setConnectionProperties + - setDriverClassName + - setJdbcUrl + - setLocation + - setPassword + - setUsername + - setWriteStatement + - validate JmsIO: methods: - advance @@ -6370,6 +6535,7 @@ JsonToRow: JsonUtils: methods: - apply + - beamSchemaFromJsonSchema - getJsonBytesToRowFunction - getJsonStringToRowFunction - getRowToJsonBytesFunction @@ -6400,6 +6566,12 @@ KafkaCommitOffset: methods: - expand - processElement +KafkaConnectUtils: + methods: + - beamRowFromSourceRecordFn + - beamSchemaFromKafkaConnectSchema + - beamSchemaTypeFromKafkaType + - mapSourceRecord KafkaIO: methods: - apply @@ -6490,58 +6662,58 @@ KafkaIO: - URN - URN_WITHOUT_METADATA - URN_WITH_METADATA -KafkaRecord: - methods: - - equals - - getHeaders - - getKV - - getOffset - - getPartition - - getTimestamp - - getTimestampType - - getTopic - - hashCode -KafkaRecordCoder: - methods: - - consistentWithEquals - - decode - - encode - - getCoderArguments - - isRegisterByteSizeObserverCheap - - of - - structuralValue - - verifyDeterministic -KafkaSchemaTransformReadConfiguration: +KafkaReadSchemaTransformConfiguration: methods: - build - builder - getAutoOffsetResetConfig - - getAvroSchema - getBootstrapServers - getConfluentSchemaRegistrySubject - getConfluentSchemaRegistryUrl - getConsumerConfigUpdates - getDataFormat + - getSchema - getTopic - setAutoOffsetResetConfig - - setAvroSchema - setBootstrapServers - setConfluentSchemaRegistrySubject - setConfluentSchemaRegistryUrl - setConsumerConfigUpdates - setDataFormat + - setSchema - setTopic - validate properties: - VALID_DATA_FORMATS - VALID_START_OFFSET_VALUES -KafkaSchemaTransformReadProvider: +KafkaReadSchemaTransformProvider: methods: - buildTransform - expand - identifier - inputCollectionNames - outputCollectionNames +KafkaRecord: + methods: + - equals + - getHeaders + - getKV + - getOffset + - getPartition + - getTimestamp + - getTimestampType + - getTopic + - hashCode +KafkaRecordCoder: + methods: + - consistentWithEquals + - decode + - encode + - getCoderArguments + - isRegisterByteSizeObserverCheap + - of + - structuralValue + - verifyDeterministic KafkaSourceConsumerFn: methods: - checkDone @@ -6566,7 +6738,7 @@ KafkaSourceConsumerFn: - fetchedRecords - history - maxRecords - - minutesToRun + - milisToRun - offset KafkaSourceDescriptor: methods: @@ -6576,6 +6748,25 @@ KafkaTableProvider: methods: - buildBeamSqlTable - getTableType +KafkaWriteSchemaTransformProvider: + methods: + - build + - buildTransform + - builder + - expand + - getBootstrapServers + - getFormat + - getProducerConfigUpdates + - getTopic + - identifier + - inputCollectionNames + - outputCollectionNames + - setBootstrapServers + - setFormat + - setProducerConfigUpdates + - setTopic + properties: + - SUPPORTED_FORMATS KeyPairUtils: methods: - preparePrivateKey @@ -6905,9 +7096,7 @@ MapperFactory: methods: - changeStreamRecordMapper - partitionMetadataMapper -MappingUtils: - methods: - - registerStreamingPlugin +MappingUtils: {} MatchResult: methods: - build @@ -7422,6 +7611,7 @@ Neo4jIO: - readAll - setup - startBundle + - tearDown - withBatchSize - withCoder - withConfig @@ -8070,6 +8260,7 @@ ParDo: - dispatchBag - dispatchCombining - dispatchMap + - dispatchMultimap - dispatchOrderedList - dispatchSet - dispatchValue @@ -8422,10 +8613,14 @@ Plugin: - getContext - getFormatClass - getFormatProviderClass + - getGetOffsetFn + - getGetReceiverArgsFromConfigFn - getHadoopConfiguration - getPluginClass - getPluginConfig - getPluginType + - getReceiverBuilder + - getReceiverClass - initContext - initPluginType - isUnbounded @@ -8433,8 +8628,11 @@ Plugin: - setContext - setFormatClass - setFormatProviderClass + - setGetOffsetFn + - setGetReceiverArgsFromConfigFn - setPluginClass - setPluginType + - setReceiverClass - withConfig - withHadoopConfiguration PluginConfigInstantiationUtils: {} @@ -8684,9 +8882,12 @@ PubsubClient: - ackDeadlineSeconds - ackId - acknowledge + - apply - createRandomSubscription + - createSchema - createSubscription - createTopic + - deleteSchema - deleteSubscription - deleteTopic - equals @@ -8694,6 +8895,9 @@ PubsubClient: - getId - getName - getPath + - getProjectId + - getSchema + - getSchemaPath - hashCode - isEOF - listSubscriptions @@ -8707,6 +8911,8 @@ PubsubClient: - pull - recordId - requestTimeMsSinceEpoch + - schemaPathFromId + - schemaPathFromPath - subscriptionPathFromName - subscriptionPathFromPath - timestampMsSinceEpoch @@ -8726,11 +8932,15 @@ PubsubGrpcClient: - ackDeadlineSeconds - acknowledge - close + - createSchema - createSubscription - createTopic + - deleteSchema - deleteSubscription - deleteTopic - getKind + - getSchema + - getSchemaPath - isEOF - listSubscriptions - listTopics @@ -8796,11 +9006,15 @@ PubsubJsonClient: - ackDeadlineSeconds - acknowledge - close + - createSchema - createSubscription - createTopic + - deleteSchema - deleteSubscription - deleteTopic - getKind + - getSchema + - getSchemaPath - isEOF - listSubscriptions - listTopics @@ -8817,6 +9031,26 @@ PubsubLiteIO: - expand - read - write +PubsubLiteReadSchemaTransformProvider: + methods: + - build + - buildTransform + - builder + - expand + - from + - getDataFormat + - getLocation + - getProject + - getSchema + - getSubscriptionName + - identifier + - inputCollectionNames + - outputCollectionNames + - setDataFormat + - setLocation + - setProject + - setSchema + - setSubscriptionName PubsubLiteSink: methods: - finishBundle @@ -8826,6 +9060,25 @@ PubsubLiteTableProvider: methods: - buildBeamSqlTable - getTableType +PubsubLiteWriteSchemaTransformProvider: + methods: + - build + - buildTransform + - builder + - expand + - getFormat + - getLocation + - getProject + - getTopicName + - identifier + - inputCollectionNames + - outputCollectionNames + - setFormat + - setLocation + - setProject + - setTopicName + properties: + - SUPPORTED_FORMATS PubsubMessage: methods: - equals @@ -8913,17 +9166,6 @@ PubsubSchemaTransformReadProvider: - inputCollectionNames - outputCollectionNames - validate -PubsubSchemaTransformWriteConfiguration: - methods: - - build - - getFormat - - getIdAttribute - - getTimestampAttribute - - getTopic - - setFormat - - setIdAttribute - - setTimestampAttribute - - setTopic PubsubTableProvider: methods: - getSchemaIOProvider @@ -8935,14 +9177,19 @@ PubsubTestClient: - advance - close - createFactoryForCreateSubscription + - createFactoryForGetSchema - createFactoryForPublish - createFactoryForPull - createFactoryForPullAndPublish + - createSchema - createSubscription - createTopic + - deleteSchema - deleteSubscription - deleteTopic - getKind + - getSchema + - getSchemaPath - isEOF - listSubscriptions - listTopics @@ -9006,6 +9253,40 @@ PubsubUnboundedSource: - validate properties: - outer +PubsubWriteSchemaTransformConfiguration: + methods: + - build + - builder + - getAttributesFieldName + - getFormat + - getIdAttribute + - getPayloadFieldName + - getSource + - getTarget + - getTimestampAttributeKey + - getTimestampFieldName + - getTopic + - setAttributesFieldName + - setFormat + - setIdAttribute + - setPayloadFieldName + - setSource + - setTarget + - setTimestampAttributeKey + - setTimestampFieldName + - setTopic + - sourceConfigurationBuilder + - targetConfigurationBuilder + properties: + - DEFAULT_TIMESTAMP_ATTRIBUTE +PubsubWriteSchemaTransformProvider: + methods: + - buildTransform + - expand + - identifier + - inputCollectionNames + - outputCollectionNames + - process PulsarIO: methods: - expand @@ -9330,6 +9611,8 @@ ReadAllViaFileBasedSource: - apply - expand - process + properties: + - DEFAULT_USES_RESHUFFLE ReadBuilder: methods: - buildExternal @@ -10180,6 +10463,7 @@ Schema: - setOptions - setType - setUUID + - sorted - toBuilder - toSchema - toString @@ -10542,7 +10826,9 @@ SingleStoreIO: - process - processElement - read + - readRows - readWithPartitions + - readWithPartitionsRows - run - splitRange - withBatchSize @@ -10558,6 +10844,49 @@ SingleStoreIO: - withUserDataMapper - withUsername - write + - writeRows +SingleStoreSchemaTransformReadConfiguration: + methods: + - build + - builder + - getDataSourceConfiguration + - getOutputParallelization + - getQuery + - getTable + - getWithPartitions + - setDataSourceConfiguration + - setOutputParallelization + - setQuery + - setTable + - setWithPartitions + - toBeamRow +SingleStoreSchemaTransformReadProvider: + methods: + - buildTransform + - expand + - identifier + - inputCollectionNames + - outputCollectionNames +SingleStoreSchemaTransformWriteConfiguration: + methods: + - build + - builder + - getBatchSize + - getDataSourceConfiguration + - getTable + - setBatchSize + - setDataSourceConfiguration + - setTable + - toBeamRow +SingleStoreSchemaTransformWriteProvider: + methods: + - buildTransform + - expand + - identifier + - inputCollectionNames + - outputCollectionNames + properties: + - INPUT_TAG SingleValueCollector: methods: - asContext @@ -11152,7 +11481,9 @@ SparkReceiverIO: - read - validateTransform - withGetOffsetFn + - withPullFrequencySec - withSparkReceiverBuilder + - withStartOffset - withTimestampFn Split: methods: @@ -11391,10 +11722,12 @@ StateSpecs: - hashCode - map - match + - multimap - offerCoders - orderedList - rowBag - rowMap + - rowMultimap - rowOrderedList - rowSet - rowValue diff --git a/playground/frontend/playground_components/assets/symbols/python.g.yaml b/playground/frontend/playground_components/assets/symbols/python.g.yaml index 01d5afbf2d8..a47447225a6 100644 --- a/playground/frontend/playground_components/assets/symbols/python.g.yaml +++ b/playground/frontend/playground_components/assets/symbols/python.g.yaml @@ -899,6 +899,9 @@ BigqueryMatcher: methods: - describe_mismatch - describe_to +BigQueryMetricsFetcher: + methods: + - fetch BigQueryMetricsPublisher: methods: - publish @@ -1273,6 +1276,7 @@ BlobStorageIO: - delete_tree - exists - last_updated + - list_files - list_prefix - open - rename @@ -4824,6 +4828,7 @@ GcsIO: - get_project_number - kms_key - last_updated + - list_files - list_prefix - open - rename @@ -4987,6 +4992,16 @@ GitHubEventsConfig: - owner - pullRequest - push +GitHubIssueMetaData: + properties: + - change_point + - change_point_timestamp + - issue_number + - issue_timestamp + - issue_url + - metric_name + - test_id + - test_name GitRepoSource: properties: - bitbucketServerConfig @@ -5795,10 +5810,6 @@ JoinIndex: JoinPersonAuctionFn: methods: - process -JrhReadPTransformOverride: - methods: - - get_replacement_transform_for_applied_ptransform - - matches JsonCoder: methods: - decode @@ -5832,6 +5843,7 @@ JustBids: JustPerson: methods: - expand +KafkaIOTestOptions: {} Key: methods: - from_client_key @@ -6332,6 +6344,7 @@ MetricsPublisher: - publish MetricsReader: methods: + - get_counter_metric - publish_metrics - publish_values MetricStructuredName: @@ -7877,6 +7890,7 @@ PythonCallable: - urn PythonCallableWithSource: methods: + - default_label - get_source - load_from_expression - load_from_fully_qualified_name @@ -8686,6 +8700,7 @@ S3IO: - delete_tree - exists - last_updated + - list_files - list_prefix - open - rename @@ -10294,6 +10309,18 @@ TestBQJobNames: - test_matches_template - test_random_in_name - test_simple_names +TestChangePointAnalysis: + methods: + - setUp + - test_alert_on_data_with_change_point + - test_alert_on_data_with_reported_change_point + - test_change_point_outside_inspection_window_is_not_a_valid_alert + - test_duplicate_change_point + - test_duplicate_change_points_are_not_valid_alerts + - test_edivisive_means + - test_is_changepoint_in_valid_window + - test_no_alerts_when_no_change_points + - test_validate_config TestCheckSchemaEqual: methods: - test_descriptions @@ -11356,6 +11383,7 @@ TriggerCopyJobs: - display_data - finish_bundle - process + - process_one - start_bundle properties: - TRIGGER_DELETE_TEMP_TABLES diff --git a/playground/frontend/playground_components/lib/src/controllers/code_runner.dart b/playground/frontend/playground_components/lib/src/controllers/code_runner.dart new file mode 100644 index 00000000000..ad2df180d94 --- /dev/null +++ b/playground/frontend/playground_components/lib/src/controllers/code_runner.dart @@ -0,0 +1,165 @@ +/* + * 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 'dart:async'; + +import 'package:flutter/material.dart'; + +import '../../playground_components.dart'; +import '../repositories/models/run_code_request.dart'; +import '../repositories/models/run_code_result.dart'; +import 'snippet_editing_controller.dart'; + +class CodeRunner extends ChangeNotifier { + final CodeRepository? _codeRepository; + final ValueGetter<SnippetEditingController> _snippetEditingControllerGetter; + SnippetEditingController? snippetEditingController; + + CodeRunner({ + required ValueGetter<SnippetEditingController> + snippetEditingControllerGetter, + CodeRepository? codeRepository, + }) : _codeRepository = codeRepository, + _snippetEditingControllerGetter = snippetEditingControllerGetter; + + RunCodeResult? _result; + StreamSubscription<RunCodeResult>? _runSubscription; + DateTime? _runStartDate; + DateTime? _runStopDate; + + String? get pipelineOptions => + _snippetEditingControllerGetter().pipelineOptions; + RunCodeResult? get result => _result; + DateTime? get runStartDate => _runStartDate; + DateTime? get runStopDate => _runStopDate; + bool get isCodeRunning => !(_result?.isFinished ?? true); + + String get resultLog => _result?.log ?? ''; + String get resultOutput => _result?.output ?? ''; + String get resultLogOutput => resultLog + resultOutput; + + bool get isExampleChanged { + return _snippetEditingControllerGetter().isChanged; + } + + void clearResult() { + _result = null; + notifyListeners(); + } + + void runCode({void Function()? onFinish}) { + _runStartDate = DateTime.now(); + _runStopDate = null; + notifyListeners(); + snippetEditingController = _snippetEditingControllerGetter(); + + final parsedPipelineOptions = + parsePipelineOptions(snippetEditingController!.pipelineOptions); + if (parsedPipelineOptions == null) { + _result = const RunCodeResult( + status: RunCodeStatus.compileError, + errorMessage: kPipelineOptionsParseError, + ); + _runStopDate = DateTime.now(); + notifyListeners(); + return; + } + + if (!isExampleChanged && + snippetEditingController!.example?.outputs != null) { + unawaited(_showPrecompiledResult()); + } else { + final request = RunCodeRequest( + datasets: snippetEditingController?.example?.datasets ?? [], + files: snippetEditingController!.getFiles(), + sdk: snippetEditingController!.sdk, + pipelineOptions: parsedPipelineOptions, + ); + _runSubscription = _codeRepository?.runCode(request).listen((event) { + _result = event; + notifyListeners(); + + if (event.isFinished) { + if (onFinish != null) { + onFinish(); + } + snippetEditingController = null; + _runStopDate = DateTime.now(); + } + }); + notifyListeners(); + } + } + + /// Resets the error message text so that on the next rebuild + /// of `CodeTextAreaWrapper` it is not picked up and not shown as a toast. + // TODO: Listen to this object outside of widgets, + // emit toasts from notifications, then remove this method. + void resetErrorMessageText() { + if (_result == null) { + return; + } + _result = RunCodeResult( + status: _result!.status, + output: _result!.output, + ); + notifyListeners(); + } + + Future<void> cancelRun() async { + snippetEditingController = null; + await _runSubscription?.cancel(); + final pipelineUuid = _result?.pipelineUuid ?? ''; + + if (pipelineUuid.isNotEmpty) { + await _codeRepository?.cancelExecution(pipelineUuid); + } + + _result = RunCodeResult( + status: RunCodeStatus.finished, + output: _result?.output, + log: (_result?.log ?? '') + kExecutionCancelledText, + graph: _result?.graph, + ); + + _runStopDate = DateTime.now(); + notifyListeners(); + } + + Future<void> _showPrecompiledResult() async { + _result = const RunCodeResult( + status: RunCodeStatus.preparation, + ); + final selectedExample = snippetEditingController!.example!; + + notifyListeners(); + // add a little delay to improve user experience + await Future.delayed(kPrecompiledDelay); + + final String logs = selectedExample.logs ?? ''; + _result = RunCodeResult( + status: RunCodeStatus.finished, + output: selectedExample.outputs, + log: kCachedResultsLog + logs, + graph: selectedExample.graph, + ); + + _runStopDate = DateTime.now(); + notifyListeners(); + } +} diff --git a/playground/frontend/playground_components/lib/src/models/outputs.dart b/playground/frontend/playground_components/lib/src/controllers/output_filter_type_controller.dart similarity index 73% copy from playground/frontend/playground_components/lib/src/models/outputs.dart copy to playground/frontend/playground_components/lib/src/controllers/output_filter_type_controller.dart index fa1a360063c..d245e800b01 100644 --- a/playground/frontend/playground_components/lib/src/models/outputs.dart +++ b/playground/frontend/playground_components/lib/src/controllers/output_filter_type_controller.dart @@ -16,21 +16,15 @@ * limitations under the License. */ -enum OutputType { - all, - log, - output, - graph, -} +import 'package:flutter/material.dart'; + +import '../../playground_components.dart'; -class Outputs { - final String output; - final String graph; - final String log; +class OutputFilterTypeController extends ChangeNotifier { + OutputType outputFilterType = OutputType.all; - const Outputs({ - required this.output, - required this.graph, - required this.log, - }); + void setOutputFilterType(OutputType type) { + outputFilterType = type; + notifyListeners(); + } } diff --git a/playground/frontend/playground_components/lib/src/controllers/playground_controller.dart b/playground/frontend/playground_components/lib/src/controllers/playground_controller.dart index 86aa44f86b9..de8ee9112ed 100644 --- a/playground/frontend/playground_components/lib/src/controllers/playground_controller.dart +++ b/playground/frontend/playground_components/lib/src/controllers/playground_controller.dart @@ -32,16 +32,14 @@ import '../models/example_loading_descriptors/examples_loading_descriptor.dart'; import '../models/example_loading_descriptors/standard_example_loading_descriptor.dart'; import '../models/example_loading_descriptors/user_shared_example_loading_descriptor.dart'; import '../models/intents.dart'; -import '../models/outputs.dart'; import '../models/sdk.dart'; import '../models/shortcut.dart'; import '../repositories/code_repository.dart'; -import '../repositories/models/run_code_request.dart'; -import '../repositories/models/run_code_result.dart'; import '../services/symbols/loaders/map.dart'; import '../services/symbols/symbols_notifier.dart'; -import '../util/pipeline_options.dart'; +import 'code_runner.dart'; import 'example_loaders/examples_loader.dart'; +import 'output_filter_type_controller.dart'; import 'snippet_editing_controller.dart'; const kTitleLength = 25; @@ -58,26 +56,26 @@ const kCachedResultsLog = class PlaygroundController with ChangeNotifier { final ExampleCache exampleCache; final ExamplesLoader examplesLoader; + final OutputFilterTypeController outputTypeController = + OutputFilterTypeController(); + + late final CodeRunner codeRunner; final _snippetEditingControllers = <Sdk, SnippetEditingController>{}; Sdk? _sdk; - final CodeRepository? _codeRepository; - - RunCodeResult? _result; - StreamSubscription<RunCodeResult>? _runSubscription; - StreamController<int>? _executionTime; - - // TODO(alexeyinkin): Extract along with run status, https://github.com/apache/beam/issues/23248 - OutputType selectedOutputFilterType = OutputType.all; - String outputResult = ''; PlaygroundController({ required this.exampleCache, required this.examplesLoader, CodeRepository? codeRepository, - }) : _codeRepository = codeRepository { + }) { examplesLoader.setPlaygroundController(this); + + codeRunner = CodeRunner( + codeRepository: codeRepository, + snippetEditingControllerGetter: requireSnippetEditingController, + )..addListener(notifyListeners); } SnippetEditingController _getOrCreateSnippetEditingController( @@ -127,18 +125,6 @@ class PlaygroundController with ChangeNotifier { String? get source => snippetEditingController?.activeFileController?.codeController.fullText; - bool get isCodeRunning => !(result?.isFinished ?? true); - - RunCodeResult? get result => _result; - - String? get pipelineOptions => snippetEditingController?.pipelineOptions; - - Stream<int>? get executionTime => _executionTime?.stream; - - bool get isExampleChanged { - return snippetEditingController?.isChanged ?? false; - } - // TODO(alexeyinkin): Single source of truth for whether graph is supported, https://github.com/apache/beam/issues/23251 bool get graphAvailable => selectedExample?.type != ExampleType.test && @@ -232,9 +218,7 @@ class PlaygroundController with ChangeNotifier { controller.setExample(example, descriptor: descriptor); } - _result = null; - _executionTime = null; - setOutputResult(''); + codeRunner.clearResult(); notifyListeners(); } @@ -265,34 +249,14 @@ class PlaygroundController with ChangeNotifier { GetIt.instance.get<SymbolsNotifier>().addLoaderIfNot(mode, loader); } - void setSelectedOutputFilterType(OutputType type) { - selectedOutputFilterType = type; - notifyListeners(); - } - - void setOutputResult(String outputs) { - outputResult = outputs; - notifyListeners(); - } - - void clearOutput() { - _result = null; - notifyListeners(); - } - - void reset() { + Future<void> reset() async { + await codeRunner.cancelRun(); snippetEditingController?.reset(); - _executionTime = null; - outputResult = ''; - notifyListeners(); + codeRunner.clearResult(); } - void resetError() { - if (result == null) { - return; - } - _result = RunCodeResult(status: result!.status, output: result!.output); - notifyListeners(); + void resetErrorMessageText() { + codeRunner.resetErrorMessageText(); } void setPipelineOptions(String options) { @@ -301,136 +265,6 @@ class PlaygroundController with ChangeNotifier { notifyListeners(); } - void runCode({void Function()? onFinish}) { - final controller = requireSnippetEditingController(); - final parsedPipelineOptions = - parsePipelineOptions(controller.pipelineOptions); - if (parsedPipelineOptions == null) { - _result = const RunCodeResult( - status: RunCodeStatus.compileError, - errorMessage: kPipelineOptionsParseError, - ); - notifyListeners(); - return; - } - _executionTime?.close(); - _executionTime = _createExecutionTimeStream(); - if (!isExampleChanged && controller.example?.outputs != null) { - _showPrecompiledResult(controller); - } else { - final request = RunCodeRequest( - datasets: selectedExample?.datasets ?? [], - files: controller.getFiles(), - pipelineOptions: parsedPipelineOptions, - sdk: controller.sdk, - ); - _runSubscription = _codeRepository?.runCode(request).listen((event) { - _result = event; - filterOutput(selectedOutputFilterType); - - if (event.isFinished && onFinish != null) { - onFinish(); - _executionTime?.close(); - } - notifyListeners(); - }); - notifyListeners(); - } - } - - Future<void> cancelRun() async { - await _runSubscription?.cancel(); - final pipelineUuid = result?.pipelineUuid ?? ''; - - if (pipelineUuid.isNotEmpty) { - await _codeRepository?.cancelExecution(pipelineUuid); - } - - _result = RunCodeResult( - status: RunCodeStatus.finished, - output: _result?.output, - log: (_result?.log ?? '') + kExecutionCancelledText, - graph: _result?.graph, - ); - - final log = _result?.log ?? ''; - final output = _result?.output ?? ''; - setOutputResult(log + output); - await _executionTime?.close(); - notifyListeners(); - } - - Future<void> _showPrecompiledResult( - SnippetEditingController snippetEditingController, - ) async { - _result = const RunCodeResult( - status: RunCodeStatus.preparation, - ); - final selectedExample = snippetEditingController.example!; - - notifyListeners(); - // add a little delay to improve user experience - await Future.delayed(kPrecompiledDelay); - - String logs = selectedExample.logs ?? ''; - _result = RunCodeResult( - status: RunCodeStatus.finished, - output: selectedExample.outputs, - log: kCachedResultsLog + logs, - graph: selectedExample.graph, - ); - - filterOutput(selectedOutputFilterType); - await _executionTime?.close(); - notifyListeners(); - } - - StreamController<int> _createExecutionTimeStream() { - StreamController<int>? streamController; - Timer? timer; - Duration timerInterval = const Duration(milliseconds: kExecutionTimeUpdate); - int ms = 0; - - void stopTimer() { - timer?.cancel(); - streamController?.close(); - } - - void tick(_) { - ms += kExecutionTimeUpdate; - streamController?.add(ms); - } - - void startTimer() { - timer = Timer.periodic(timerInterval, tick); - } - - streamController = StreamController<int>.broadcast( - onListen: startTimer, - onCancel: stopTimer, - ); - - return streamController; - } - - void filterOutput(OutputType type) { - final output = result?.output ?? ''; - final log = result?.log ?? ''; - - switch (type) { - case OutputType.all: - case OutputType.graph: - setOutputResult(log + output); - break; - case OutputType.log: - setOutputResult(log); - break; - case OutputType.output: - setOutputResult(output); - break; - } - } - Future<UserSharedExampleLoadingDescriptor> saveSnippet() async { final snippetController = requireSnippetEditingController(); final files = snippetController.getFiles(); @@ -480,7 +314,7 @@ class PlaygroundController with ChangeNotifier { ), actionIntent: const RunIntent(), createAction: (BuildContext context) => CallbackAction( - onInvoke: (_) => runCode(), + onInvoke: (_) => codeRunner.runCode(), ), ); @@ -500,4 +334,10 @@ class PlaygroundController with ChangeNotifier { runShortcut, resetShortcut, ]; + + @override + void dispose() { + super.dispose(); + codeRunner.removeListener(notifyListeners); + } } diff --git a/playground/frontend/playground_components/lib/src/models/outputs.dart b/playground/frontend/playground_components/lib/src/models/outputs.dart index fa1a360063c..4d56e19b217 100644 --- a/playground/frontend/playground_components/lib/src/models/outputs.dart +++ b/playground/frontend/playground_components/lib/src/models/outputs.dart @@ -20,7 +20,6 @@ enum OutputType { all, log, output, - graph, } class Outputs { diff --git a/playground/frontend/playground_components/lib/src/widgets/output/output_area.dart b/playground/frontend/playground_components/lib/src/widgets/output/output_area.dart index f1bf48b2c26..d0ac762f858 100644 --- a/playground/frontend/playground_components/lib/src/widgets/output/output_area.dart +++ b/playground/frontend/playground_components/lib/src/widgets/output/output_area.dart @@ -17,8 +17,9 @@ */ import 'package:flutter/material.dart'; -import 'package:playground_components/playground_components.dart'; +import '../../controllers/playground_controller.dart'; +import '../../models/outputs.dart'; import 'graph/graph.dart'; import 'output_result.dart'; @@ -28,35 +29,52 @@ class OutputArea extends StatelessWidget { final Axis graphDirection; const OutputArea({ - Key? key, + super.key, required this.playgroundController, required this.tabController, required this.graphDirection, - }) : super(key: key); + }); + + String _getResultOutput() { + final outputType = + playgroundController.outputTypeController.outputFilterType; + switch (outputType) { + case OutputType.log: + return playgroundController.codeRunner.resultLog; + case OutputType.output: + return playgroundController.codeRunner.resultOutput; + case OutputType.all: + return playgroundController.codeRunner.resultLogOutput; + } + } @override Widget build(BuildContext context) { final sdk = playgroundController.sdk; - return Container( - color: Theme.of(context).backgroundColor, - child: TabBarView( - controller: tabController, - physics: const NeverScrollableScrollPhysics(), - children: <Widget>[ - OutputResult( - text: playgroundController.outputResult, - isSelected: tabController.index == 0, - ), - if (playgroundController.graphAvailable) - sdk == null - ? Container() - : GraphTab( - graph: playgroundController.result?.graph ?? '', - sdk: sdk, - direction: graphDirection, - ), - ], + return AnimatedBuilder( + animation: playgroundController.outputTypeController, + builder: (context, child) => ColoredBox( + color: Theme.of(context).backgroundColor, + child: TabBarView( + controller: tabController, + physics: const NeverScrollableScrollPhysics(), + children: <Widget>[ + OutputResult( + text: _getResultOutput(), + isSelected: tabController.index == 0, + ), + if (playgroundController.graphAvailable) + sdk == null + ? Container() + : GraphTab( + graph: + playgroundController.codeRunner.result?.graph ?? '', + sdk: sdk, + direction: graphDirection, + ), + ], + ), ), ); } diff --git a/playground/frontend/playground_components/lib/src/widgets/output/output_tab.dart b/playground/frontend/playground_components/lib/src/widgets/output/output_tab.dart index 326b1c72448..2fb40e9ecd1 100644 --- a/playground/frontend/playground_components/lib/src/widgets/output/output_tab.dart +++ b/playground/frontend/playground_components/lib/src/widgets/output/output_tab.dart @@ -27,7 +27,9 @@ class OutputTab extends StatefulWidget { final PlaygroundController playgroundController; final String name; final bool isSelected; - final String value; + + /// Used to check if an update marker should be added on the tab + final String maxPossibleContent; final bool hasFilter; const OutputTab({ @@ -35,7 +37,7 @@ class OutputTab extends StatefulWidget { required this.playgroundController, required this.name, required this.isSelected, - required this.value, + required this.maxPossibleContent, this.hasFilter = false, }); @@ -53,8 +55,8 @@ class _OutputTabState extends State<OutputTab> { hasNewContent = false; }); } else if (!widget.isSelected && - widget.value.isNotEmpty && - oldWidget.value != widget.value) { + widget.maxPossibleContent.isNotEmpty && + oldWidget.maxPossibleContent != widget.maxPossibleContent) { setState(() { hasNewContent = true; }); diff --git a/playground/frontend/playground_components/lib/src/widgets/output/output_tabs.dart b/playground/frontend/playground_components/lib/src/widgets/output/output_tabs.dart index 80839296fbf..f36a6389fc2 100644 --- a/playground/frontend/playground_components/lib/src/widgets/output/output_tabs.dart +++ b/playground/frontend/playground_components/lib/src/widgets/output/output_tabs.dart @@ -43,7 +43,7 @@ class OutputTabs extends StatelessWidget { playgroundController: playgroundController, name: 'widgets.output.result'.tr(), isSelected: tabController.index == 0, - value: playgroundController.outputResult, + maxPossibleContent: playgroundController.codeRunner.resultLogOutput, hasFilter: true, ), if (playgroundController.graphAvailable) @@ -51,7 +51,8 @@ class OutputTabs extends StatelessWidget { playgroundController: playgroundController, name: 'widgets.output.graph'.tr(), isSelected: tabController.index == 2, - value: playgroundController.result?.graph ?? '', + maxPossibleContent: + playgroundController.codeRunner.result?.graph ?? '', ), ], ), diff --git a/playground/frontend/playground_components/lib/src/widgets/output/result_filter_bubble.dart b/playground/frontend/playground_components/lib/src/widgets/output/result_filter_bubble.dart index a18ddb01d81..2a93919e0e5 100644 --- a/playground/frontend/playground_components/lib/src/widgets/output/result_filter_bubble.dart +++ b/playground/frontend/playground_components/lib/src/widgets/output/result_filter_bubble.dart @@ -36,14 +36,14 @@ class ResultFilterBubble extends StatelessWidget { @override Widget build(BuildContext context) { - final isSelected = type == playgroundController.selectedOutputFilterType; + final isSelected = + type == playgroundController.outputTypeController.outputFilterType; return BubbleWidget( isSelected: isSelected, onTap: () { if (!isSelected) { - playgroundController.setSelectedOutputFilterType(type); - playgroundController.filterOutput(type); + playgroundController.outputTypeController.setOutputFilterType(type); } }, title: name, diff --git a/playground/frontend/playground_components/lib/src/widgets/output/result_filter_popover.dart b/playground/frontend/playground_components/lib/src/widgets/output/result_filter_popover.dart index a74c67e2fa1..671f7c56613 100644 --- a/playground/frontend/playground_components/lib/src/widgets/output/result_filter_popover.dart +++ b/playground/frontend/playground_components/lib/src/widgets/output/result_filter_popover.dart @@ -52,7 +52,7 @@ class ResultFilterPopover extends StatelessWidget { vertical: BeamSizes.size4, ), child: AnimatedBuilder( - animation: playgroundController, + animation: playgroundController.outputTypeController, builder: (context, child) => Row( children: [ ResultFilterBubble( diff --git a/playground/frontend/lib/pages/standalone_playground/widgets/close_listener.dart b/playground/frontend/playground_components/lib/src/widgets/periodic_builder.dart similarity index 60% copy from playground/frontend/lib/pages/standalone_playground/widgets/close_listener.dart copy to playground/frontend/playground_components/lib/src/widgets/periodic_builder.dart index ba2a19a7ae2..aed7d8c21b8 100644 --- a/playground/frontend/lib/pages/standalone_playground/widgets/close_listener.dart +++ b/playground/frontend/playground_components/lib/src/widgets/periodic_builder.dart @@ -16,34 +16,46 @@ * limitations under the License. */ -import 'package:flutter/material.dart'; -import 'package:playground_components/playground_components.dart'; -import 'dart:html' as html; +import 'dart:async'; -import 'package:provider/provider.dart'; +import 'package:flutter/material.dart'; -class CloseListener extends StatefulWidget { - final Widget child; +class PeriodicBuilderWidget extends StatefulWidget { + final Duration interval; + final ValueGetter<Widget> builder; - const CloseListener({Key? key, required this.child}) : super(key: key); + const PeriodicBuilderWidget({ + super.key, + required this.interval, + required this.builder, + }); @override - State<CloseListener> createState() => _CloseListenerState(); + State<PeriodicBuilderWidget> createState() => _PeriodicBuilderWidgetState(); } -class _CloseListenerState extends State<CloseListener> { +class _PeriodicBuilderWidgetState extends State<PeriodicBuilderWidget> { + late Timer _timer; + @override void initState() { - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - html.window.onBeforeUnload.listen((event) async { - Provider.of<PlaygroundController>(context, listen: false).cancelRun(); - }); - }); super.initState(); + _timer = Timer.periodic( + widget.interval, + (_) { + setState(() {}); + }, + ); + } + + @override + void dispose() { + super.dispose(); + _timer.cancel(); } @override Widget build(BuildContext context) { - return widget.child; + return widget.builder(); } } diff --git a/playground/frontend/playground_components/lib/src/widgets/run_button.dart b/playground/frontend/playground_components/lib/src/widgets/run_button.dart index 66ac0224797..c3cdaea4553 100644 --- a/playground/frontend/playground_components/lib/src/widgets/run_button.dart +++ b/playground/frontend/playground_components/lib/src/widgets/run_button.dart @@ -22,76 +22,118 @@ import 'package:flutter/material.dart'; import '../constants/sizes.dart'; import '../controllers/playground_controller.dart'; import '../theme/theme.dart'; +import 'periodic_builder.dart'; import 'shortcut_tooltip.dart'; -const kMsToSec = 1000; -const kSecondsFractions = 1; - -const _width = 150.0; - class RunButton extends StatelessWidget { final PlaygroundController playgroundController; - final bool isRunning; final VoidCallback runCode; final VoidCallback cancelRun; - final bool disabled; + final bool isEnabled; const RunButton({ super.key, required this.playgroundController, - required this.isRunning, required this.runCode, required this.cancelRun, - this.disabled = false, + this.isEnabled = true, }); + static const _buttonTextRebuildInterval = 100; + static const _width = 150.0; + @override Widget build(BuildContext context) { - return SizedBox( - width: _width, - height: BeamSizes.buttonHeight, - child: ShortcutTooltip( - shortcut: playgroundController.runShortcut, - child: ElevatedButton.icon( - style: const ButtonStyle( - padding: MaterialStatePropertyAll(EdgeInsets.zero), + return AnimatedBuilder( + animation: playgroundController.codeRunner, + builder: (context, child) { + final isRunning = playgroundController.codeRunner.isCodeRunning; + final runStartDate = playgroundController.codeRunner.runStartDate; + final runStopDate = playgroundController.codeRunner.runStopDate; + + return SizedBox( + width: _width, + height: BeamSizes.buttonHeight, + child: ShortcutTooltip( + shortcut: playgroundController.runShortcut, + child: ElevatedButton.icon( + style: const ButtonStyle( + padding: MaterialStatePropertyAll(EdgeInsets.zero), + ), + icon: isRunning + ? SizedBox( + width: BeamIconSizes.small, + height: BeamIconSizes.small, + child: CircularProgressIndicator( + color: Theme.of(context) + .extension<BeamThemeExtension>()! + .primaryBackgroundTextColor, + ), + ) + : const Icon(Icons.play_arrow), + label: isRunning + // TODO(nausharipov): fix bug + // It is also rebuilt on every codeRunner notification + ? PeriodicBuilderWidget( + interval: const Duration( + milliseconds: _buttonTextRebuildInterval, + ), + builder: () { + return _ButtonText( + isRunning: isRunning, + runStartDate: runStartDate, + runStopDate: runStopDate, + ); + }, + ) + : _ButtonText( + isRunning: isRunning, + runStartDate: runStartDate, + runStopDate: runStopDate, + ), + onPressed: isEnabled ? _onPressed() : null, + ), ), - icon: isRunning - ? SizedBox( - width: BeamIconSizes.small, - height: BeamIconSizes.small, - child: CircularProgressIndicator( - color: Theme.of(context) - .extension<BeamThemeExtension>()! - .primaryBackgroundTextColor, - ), - ) - : const Icon(Icons.play_arrow), - label: StreamBuilder( - stream: playgroundController.executionTime, - builder: (context, AsyncSnapshot<int> state) { - final seconds = (state.data ?? 0) / kMsToSec; - final runText = 'widgets.runOrCancelButton.titles.run'.tr(); - final cancelText = - 'widgets.runOrCancelButton.titles.cancel'.tr(); - final buttonText = isRunning ? cancelText : runText; - if (seconds > 0) { - return Text( - '$buttonText (${seconds.toStringAsFixed(kSecondsFractions)} s)', - ); - } - return Text(buttonText); - }), - onPressed: onPressHandler(), - ), - ), + ); + }, ); } - onPressHandler() { - if (disabled) { - return null; + VoidCallback _onPressed() { + return playgroundController.codeRunner.isCodeRunning ? cancelRun : runCode; + } +} + +class _ButtonText extends StatelessWidget { + final bool isRunning; + final DateTime? runStartDate; + final DateTime? runStopDate; + + const _ButtonText({ + required this.isRunning, + required this.runStartDate, + required this.runStopDate, + }); + + static const _msToSec = 1000; + static const _secondsFractionDigits = 1; + + @override + Widget build(BuildContext context) { + final runText = 'widgets.runOrCancelButton.titles.run'.tr(); + final cancelText = 'widgets.runOrCancelButton.titles.cancel'.tr(); + final buttonText = isRunning ? cancelText : runText; + final runStopDateOrNow = runStopDate ?? DateTime.now(); + + final elapsedDuration = + runStopDateOrNow.difference(runStartDate ?? DateTime.now()); + + if (elapsedDuration.inMilliseconds > 0) { + final seconds = elapsedDuration.inMilliseconds / _msToSec; + return Text( + '$buttonText (${seconds.toStringAsFixed(_secondsFractionDigits)} s)', + ); } - return !isRunning ? runCode : cancelRun; + return Text(buttonText); } } diff --git a/playground/frontend/playground_components/lib/src/widgets/run_or_cancel_button.dart b/playground/frontend/playground_components/lib/src/widgets/run_or_cancel_button.dart index 04b6b911f76..75ebf74c7f9 100644 --- a/playground/frontend/playground_components/lib/src/widgets/run_or_cancel_button.dart +++ b/playground/frontend/playground_components/lib/src/widgets/run_or_cancel_button.dart @@ -42,16 +42,16 @@ class RunOrCancelButton extends StatelessWidget { Widget build(BuildContext context) { return RunButton( playgroundController: playgroundController, - isRunning: playgroundController.isCodeRunning, - cancelRun: () { + isEnabled: !(playgroundController.selectedExample?.isMultiFile ?? false), + cancelRun: () async { beforeCancel?.call(); - playgroundController.cancelRun().catchError( + await playgroundController.codeRunner.cancelRun().catchError( (_) => PlaygroundComponents.toastNotifier.add(_getErrorToast()), ); }, runCode: () { beforeRun?.call(); - playgroundController.runCode( + playgroundController.codeRunner.runCode( onFinish: onComplete, ); }, diff --git a/playground/frontend/playground_components/test/src/controllers/example_loaders/examples_loader_test.mocks.dart b/playground/frontend/playground_components/test/src/controllers/example_loaders/examples_loader_test.mocks.dart index 6ac39341a84..35b0ac0a006 100644 --- a/playground/frontend/playground_components/test/src/controllers/example_loaders/examples_loader_test.mocks.dart +++ b/playground/frontend/playground_components/test/src/controllers/example_loaders/examples_loader_test.mocks.dart @@ -4,31 +4,33 @@ // ignore_for_file: no_leading_underscores_for_library_prefixes import 'dart:async' as _i14; -import 'dart:ui' as _i15; +import 'dart:ui' as _i16; import 'package:mockito/mockito.dart' as _i1; import 'package:playground_components/src/cache/example_cache.dart' as _i2; +import 'package:playground_components/src/controllers/code_runner.dart' as _i5; import 'package:playground_components/src/controllers/example_loaders/examples_loader.dart' as _i3; +import 'package:playground_components/src/controllers/output_filter_type_controller.dart' + as _i4; import 'package:playground_components/src/controllers/playground_controller.dart' - as _i10; + as _i12; import 'package:playground_components/src/controllers/snippet_editing_controller.dart' - as _i5; + as _i7; import 'package:playground_components/src/models/category_with_examples.dart' - as _i16; -import 'package:playground_components/src/models/example.dart' as _i9; -import 'package:playground_components/src/models/example_base.dart' as _i8; + as _i17; +import 'package:playground_components/src/models/example.dart' as _i11; +import 'package:playground_components/src/models/example_base.dart' as _i10; import 'package:playground_components/src/models/example_loading_descriptors/example_loading_descriptor.dart' - as _i13; + as _i15; import 'package:playground_components/src/models/example_loading_descriptors/examples_loading_descriptor.dart' - as _i7; + as _i9; import 'package:playground_components/src/models/example_loading_descriptors/user_shared_example_loading_descriptor.dart' - as _i6; -import 'package:playground_components/src/models/loading_status.dart' as _i17; -import 'package:playground_components/src/models/outputs.dart' as _i11; -import 'package:playground_components/src/models/sdk.dart' as _i12; -import 'package:playground_components/src/models/shortcut.dart' as _i4; -import 'package:playground_components/src/models/snippet_file.dart' as _i18; + as _i8; +import 'package:playground_components/src/models/loading_status.dart' as _i18; +import 'package:playground_components/src/models/sdk.dart' as _i13; +import 'package:playground_components/src/models/shortcut.dart' as _i6; +import 'package:playground_components/src/models/snippet_file.dart' as _i19; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -44,26 +46,31 @@ class _FakeExampleCache_0 extends _i1.Fake implements _i2.ExampleCache {} class _FakeExamplesLoader_1 extends _i1.Fake implements _i3.ExamplesLoader {} -class _FakeBeamShortcut_2 extends _i1.Fake implements _i4.BeamShortcut {} +class _FakeOutputFilterTypeController_2 extends _i1.Fake + implements _i4.OutputFilterTypeController {} + +class _FakeCodeRunner_3 extends _i1.Fake implements _i5.CodeRunner {} -class _FakeSnippetEditingController_3 extends _i1.Fake - implements _i5.SnippetEditingController {} +class _FakeBeamShortcut_4 extends _i1.Fake implements _i6.BeamShortcut {} -class _FakeUserSharedExampleLoadingDescriptor_4 extends _i1.Fake - implements _i6.UserSharedExampleLoadingDescriptor {} +class _FakeSnippetEditingController_5 extends _i1.Fake + implements _i7.SnippetEditingController {} -class _FakeExamplesLoadingDescriptor_5 extends _i1.Fake - implements _i7.ExamplesLoadingDescriptor {} +class _FakeUserSharedExampleLoadingDescriptor_6 extends _i1.Fake + implements _i8.UserSharedExampleLoadingDescriptor {} -class _FakeExampleBase_6 extends _i1.Fake implements _i8.ExampleBase {} +class _FakeExamplesLoadingDescriptor_7 extends _i1.Fake + implements _i9.ExamplesLoadingDescriptor {} -class _FakeExample_7 extends _i1.Fake implements _i9.Example {} +class _FakeExampleBase_8 extends _i1.Fake implements _i10.ExampleBase {} + +class _FakeExample_9 extends _i1.Fake implements _i11.Example {} /// A class which mocks [PlaygroundController]. /// /// See the documentation for Mockito's code generation for more information. class MockPlaygroundController extends _i1.Mock - implements _i10.PlaygroundController { + implements _i12.PlaygroundController { MockPlaygroundController() { _i1.throwOnMissingStub(this); } @@ -79,39 +86,31 @@ class MockPlaygroundController extends _i1.Mock returnValue: _FakeExamplesLoader_1(), ) as _i3.ExamplesLoader); @override - _i11.OutputType get selectedOutputFilterType => (super.noSuchMethod( - Invocation.getter(#selectedOutputFilterType), - returnValue: _i11.OutputType.all, - ) as _i11.OutputType); - @override - set selectedOutputFilterType(_i11.OutputType? _selectedOutputFilterType) => - super.noSuchMethod( - Invocation.setter( - #selectedOutputFilterType, - _selectedOutputFilterType, - ), - returnValueForMissingStub: null, - ); + _i4.OutputFilterTypeController get outputTypeController => + (super.noSuchMethod( + Invocation.getter(#outputTypeController), + returnValue: _FakeOutputFilterTypeController_2(), + ) as _i4.OutputFilterTypeController); @override - String get outputResult => (super.noSuchMethod( - Invocation.getter(#outputResult), - returnValue: '', - ) as String); + _i5.CodeRunner get codeRunner => (super.noSuchMethod( + Invocation.getter(#codeRunner), + returnValue: _FakeCodeRunner_3(), + ) as _i5.CodeRunner); @override - set outputResult(String? _outputResult) => super.noSuchMethod( + set codeRunner(_i5.CodeRunner? _codeRunner) => super.noSuchMethod( Invocation.setter( - #outputResult, - _outputResult, + #codeRunner, + _codeRunner, ), returnValueForMissingStub: null, ); @override - _i4.BeamShortcut get runShortcut => (super.noSuchMethod( + _i6.BeamShortcut get runShortcut => (super.noSuchMethod( Invocation.getter(#runShortcut), - returnValue: _FakeBeamShortcut_2(), - ) as _i4.BeamShortcut); + returnValue: _FakeBeamShortcut_4(), + ) as _i6.BeamShortcut); @override - set runShortcut(_i4.BeamShortcut? _runShortcut) => super.noSuchMethod( + set runShortcut(_i6.BeamShortcut? _runShortcut) => super.noSuchMethod( Invocation.setter( #runShortcut, _runShortcut, @@ -119,12 +118,12 @@ class MockPlaygroundController extends _i1.Mock returnValueForMissingStub: null, ); @override - _i4.BeamShortcut get resetShortcut => (super.noSuchMethod( + _i6.BeamShortcut get resetShortcut => (super.noSuchMethod( Invocation.getter(#resetShortcut), - returnValue: _FakeBeamShortcut_2(), - ) as _i4.BeamShortcut); + returnValue: _FakeBeamShortcut_4(), + ) as _i6.BeamShortcut); @override - set resetShortcut(_i4.BeamShortcut? _resetShortcut) => super.noSuchMethod( + set resetShortcut(_i6.BeamShortcut? _resetShortcut) => super.noSuchMethod( Invocation.setter( #resetShortcut, _resetShortcut, @@ -137,41 +136,31 @@ class MockPlaygroundController extends _i1.Mock returnValue: '', ) as String); @override - bool get isCodeRunning => (super.noSuchMethod( - Invocation.getter(#isCodeRunning), - returnValue: false, - ) as bool); - @override - bool get isExampleChanged => (super.noSuchMethod( - Invocation.getter(#isExampleChanged), - returnValue: false, - ) as bool); - @override bool get graphAvailable => (super.noSuchMethod( Invocation.getter(#graphAvailable), returnValue: false, ) as bool); @override - List<_i4.BeamShortcut> get shortcuts => (super.noSuchMethod( + List<_i6.BeamShortcut> get shortcuts => (super.noSuchMethod( Invocation.getter(#shortcuts), - returnValue: <_i4.BeamShortcut>[], - ) as List<_i4.BeamShortcut>); + returnValue: <_i6.BeamShortcut>[], + ) as List<_i6.BeamShortcut>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i5.SnippetEditingController requireSnippetEditingController() => + _i7.SnippetEditingController requireSnippetEditingController() => (super.noSuchMethod( Invocation.method( #requireSnippetEditingController, [], ), - returnValue: _FakeSnippetEditingController_3(), - ) as _i5.SnippetEditingController); + returnValue: _FakeSnippetEditingController_5(), + ) as _i7.SnippetEditingController); @override - void setEmptyIfNoSdk(_i12.Sdk? sdk) => super.noSuchMethod( + void setEmptyIfNoSdk(_i13.Sdk? sdk) => super.noSuchMethod( Invocation.method( #setEmptyIfNoSdk, [sdk], @@ -180,7 +169,7 @@ class MockPlaygroundController extends _i1.Mock ); @override void setEmptyIfNotExists( - _i12.Sdk? sdk, { + _i13.Sdk? sdk, { bool? setCurrentSdk, }) => super.noSuchMethod( @@ -192,9 +181,19 @@ class MockPlaygroundController extends _i1.Mock returnValueForMissingStub: null, ); @override + _i14.Future<void> setExampleBase(_i10.ExampleBase? exampleBase) => + (super.noSuchMethod( + Invocation.method( + #setExampleBase, + [exampleBase], + ), + returnValue: Future<void>.value(), + returnValueForMissingStub: Future<void>.value(), + ) as _i14.Future<void>); + @override void setExample( - _i9.Example? example, { - _i13.ExampleLoadingDescriptor? descriptor, + _i11.Example? example, { + _i15.ExampleLoadingDescriptor? descriptor, bool? setCurrentSdk, }) => super.noSuchMethod( @@ -210,7 +209,7 @@ class MockPlaygroundController extends _i1.Mock ); @override void setSdk( - _i12.Sdk? sdk, { + _i13.Sdk? sdk, { bool? notify = true, }) => super.noSuchMethod( @@ -222,41 +221,18 @@ class MockPlaygroundController extends _i1.Mock returnValueForMissingStub: null, ); @override - void setSelectedOutputFilterType(_i11.OutputType? type) => super.noSuchMethod( - Invocation.method( - #setSelectedOutputFilterType, - [type], - ), - returnValueForMissingStub: null, - ); - @override - void setOutputResult(String? outputs) => super.noSuchMethod( - Invocation.method( - #setOutputResult, - [outputs], - ), - returnValueForMissingStub: null, - ); - @override - void clearOutput() => super.noSuchMethod( - Invocation.method( - #clearOutput, - [], - ), - returnValueForMissingStub: null, - ); - @override - void reset() => super.noSuchMethod( + _i14.Future<void> reset() => (super.noSuchMethod( Invocation.method( #reset, [], ), - returnValueForMissingStub: null, - ); + returnValue: Future<void>.value(), + returnValueForMissingStub: Future<void>.value(), + ) as _i14.Future<void>); @override - void resetError() => super.noSuchMethod( + void resetErrorMessageText() => super.noSuchMethod( Invocation.method( - #resetError, + #resetErrorMessageText, [], ), returnValueForMissingStub: null, @@ -270,70 +246,44 @@ class MockPlaygroundController extends _i1.Mock returnValueForMissingStub: null, ); @override - void runCode({void Function()? onFinish}) => super.noSuchMethod( - Invocation.method( - #runCode, - [], - {#onFinish: onFinish}, - ), - returnValueForMissingStub: null, - ); - @override - _i14.Future<void> cancelRun() => (super.noSuchMethod( - Invocation.method( - #cancelRun, - [], - ), - returnValue: Future<void>.value(), - returnValueForMissingStub: Future<void>.value(), - ) as _i14.Future<void>); - @override - void filterOutput(_i11.OutputType? type) => super.noSuchMethod( - Invocation.method( - #filterOutput, - [type], - ), - returnValueForMissingStub: null, - ); - @override - _i14.Future<_i6.UserSharedExampleLoadingDescriptor> saveSnippet() => + _i14.Future<_i8.UserSharedExampleLoadingDescriptor> saveSnippet() => (super.noSuchMethod( Invocation.method( #saveSnippet, [], ), - returnValue: Future<_i6.UserSharedExampleLoadingDescriptor>.value( - _FakeUserSharedExampleLoadingDescriptor_4()), - ) as _i14.Future<_i6.UserSharedExampleLoadingDescriptor>); + returnValue: Future<_i8.UserSharedExampleLoadingDescriptor>.value( + _FakeUserSharedExampleLoadingDescriptor_6()), + ) as _i14.Future<_i8.UserSharedExampleLoadingDescriptor>); @override - _i7.ExamplesLoadingDescriptor getLoadingDescriptor() => (super.noSuchMethod( + _i9.ExamplesLoadingDescriptor getLoadingDescriptor() => (super.noSuchMethod( Invocation.method( #getLoadingDescriptor, [], ), - returnValue: _FakeExamplesLoadingDescriptor_5(), - ) as _i7.ExamplesLoadingDescriptor); + returnValue: _FakeExamplesLoadingDescriptor_7(), + ) as _i9.ExamplesLoadingDescriptor); @override - void addListener(_i15.VoidCallback? listener) => super.noSuchMethod( + void dispose() => super.noSuchMethod( Invocation.method( - #addListener, - [listener], + #dispose, + [], ), returnValueForMissingStub: null, ); @override - void removeListener(_i15.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method( - #removeListener, + #addListener, [listener], ), returnValueForMissingStub: null, ); @override - void dispose() => super.noSuchMethod( + void removeListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method( - #dispose, - [], + #removeListener, + [listener], ), returnValueForMissingStub: null, ); @@ -356,16 +306,16 @@ class MockExampleCache extends _i1.Mock implements _i2.ExampleCache { } @override - Map<_i12.Sdk, List<_i16.CategoryWithExamples>> get categoryListsBySdk => + Map<_i13.Sdk, List<_i17.CategoryWithExamples>> get categoryListsBySdk => (super.noSuchMethod( Invocation.getter(#categoryListsBySdk), - returnValue: <_i12.Sdk, List<_i16.CategoryWithExamples>>{}, - ) as Map<_i12.Sdk, List<_i16.CategoryWithExamples>>); + returnValue: <_i13.Sdk, List<_i17.CategoryWithExamples>>{}, + ) as Map<_i13.Sdk, List<_i17.CategoryWithExamples>>); @override - Map<_i12.Sdk, _i9.Example> get defaultExamplesBySdk => (super.noSuchMethod( + Map<_i13.Sdk, _i11.Example> get defaultExamplesBySdk => (super.noSuchMethod( Invocation.getter(#defaultExamplesBySdk), - returnValue: <_i12.Sdk, _i9.Example>{}, - ) as Map<_i12.Sdk, _i9.Example>); + returnValue: <_i13.Sdk, _i11.Example>{}, + ) as Map<_i13.Sdk, _i11.Example>); @override bool get isSelectorOpened => (super.noSuchMethod( Invocation.getter(#isSelectorOpened), @@ -385,10 +335,10 @@ class MockExampleCache extends _i1.Mock implements _i2.ExampleCache { returnValue: Future<void>.value(), ) as _i14.Future<void>); @override - _i17.LoadingStatus get catalogStatus => (super.noSuchMethod( + _i18.LoadingStatus get catalogStatus => (super.noSuchMethod( Invocation.getter(#catalogStatus), - returnValue: _i17.LoadingStatus.loading, - ) as _i17.LoadingStatus); + returnValue: _i18.LoadingStatus.loading, + ) as _i18.LoadingStatus); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), @@ -404,18 +354,18 @@ class MockExampleCache extends _i1.Mock implements _i2.ExampleCache { returnValueForMissingStub: Future<void>.value(), ) as _i14.Future<void>); @override - List<_i16.CategoryWithExamples> getCategories(_i12.Sdk? sdk) => + List<_i17.CategoryWithExamples> getCategories(_i13.Sdk? sdk) => (super.noSuchMethod( Invocation.method( #getCategories, [sdk], ), - returnValue: <_i16.CategoryWithExamples>[], - ) as List<_i16.CategoryWithExamples>); + returnValue: <_i17.CategoryWithExamples>[], + ) as List<_i17.CategoryWithExamples>); @override - _i14.Future<_i8.ExampleBase> getPrecompiledObject( + _i14.Future<_i10.ExampleBase> getPrecompiledObject( String? path, - _i12.Sdk? sdk, + _i13.Sdk? sdk, ) => (super.noSuchMethod( Invocation.method( @@ -425,20 +375,21 @@ class MockExampleCache extends _i1.Mock implements _i2.ExampleCache { sdk, ], ), - returnValue: Future<_i8.ExampleBase>.value(_FakeExampleBase_6()), - ) as _i14.Future<_i8.ExampleBase>); + returnValue: Future<_i10.ExampleBase>.value(_FakeExampleBase_8()), + ) as _i14.Future<_i10.ExampleBase>); @override - _i14.Future<_i9.Example> loadSharedExample(String? id) => (super.noSuchMethod( + _i14.Future<_i11.Example> loadSharedExample(String? id) => + (super.noSuchMethod( Invocation.method( #loadSharedExample, [id], ), - returnValue: Future<_i9.Example>.value(_FakeExample_7()), - ) as _i14.Future<_i9.Example>); + returnValue: Future<_i11.Example>.value(_FakeExample_9()), + ) as _i14.Future<_i11.Example>); @override _i14.Future<String> saveSnippet({ - List<_i18.SnippetFile>? files, - _i12.Sdk? sdk, + List<_i19.SnippetFile>? files, + _i13.Sdk? sdk, String? pipelineOptions, }) => (super.noSuchMethod( @@ -454,14 +405,14 @@ class MockExampleCache extends _i1.Mock implements _i2.ExampleCache { returnValue: Future<String>.value(''), ) as _i14.Future<String>); @override - _i14.Future<_i9.Example> loadExampleInfo(_i8.ExampleBase? example) => + _i14.Future<_i11.Example> loadExampleInfo(_i10.ExampleBase? example) => (super.noSuchMethod( Invocation.method( #loadExampleInfo, [example], ), - returnValue: Future<_i9.Example>.value(_FakeExample_7()), - ) as _i14.Future<_i9.Example>); + returnValue: Future<_i11.Example>.value(_FakeExample_9()), + ) as _i14.Future<_i11.Example>); @override void setSelectorOpened(bool? value) => super.noSuchMethod( Invocation.method( @@ -471,14 +422,14 @@ class MockExampleCache extends _i1.Mock implements _i2.ExampleCache { returnValueForMissingStub: null, ); @override - _i14.Future<_i9.Example?> getDefaultExampleBySdk(_i12.Sdk? sdk) => + _i14.Future<_i11.Example?> getDefaultExampleBySdk(_i13.Sdk? sdk) => (super.noSuchMethod( Invocation.method( #getDefaultExampleBySdk, [sdk], ), - returnValue: Future<_i9.Example?>.value(), - ) as _i14.Future<_i9.Example?>); + returnValue: Future<_i11.Example?>.value(), + ) as _i14.Future<_i11.Example?>); @override _i14.Future<void> loadDefaultPrecompiledObjects() => (super.noSuchMethod( Invocation.method( @@ -498,16 +449,16 @@ class MockExampleCache extends _i1.Mock implements _i2.ExampleCache { returnValueForMissingStub: Future<void>.value(), ) as _i14.Future<void>); @override - _i14.Future<_i8.ExampleBase?> getCatalogExampleByPath(String? path) => + _i14.Future<_i10.ExampleBase?> getCatalogExampleByPath(String? path) => (super.noSuchMethod( Invocation.method( #getCatalogExampleByPath, [path], ), - returnValue: Future<_i8.ExampleBase?>.value(), - ) as _i14.Future<_i8.ExampleBase?>); + returnValue: Future<_i10.ExampleBase?>.value(), + ) as _i14.Future<_i10.ExampleBase?>); @override - void addListener(_i15.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -515,7 +466,7 @@ class MockExampleCache extends _i1.Mock implements _i2.ExampleCache { returnValueForMissingStub: null, ); @override - void removeListener(_i15.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], diff --git a/playground/frontend/playground_components/test/src/controllers/playground_controller_test.dart b/playground/frontend/playground_components/test/src/controllers/playground_controller_test.dart index 30d39e293c9..628b1cc9443 100644 --- a/playground/frontend/playground_components/test/src/controllers/playground_controller_test.dart +++ b/playground/frontend/playground_components/test/src/controllers/playground_controller_test.dart @@ -54,13 +54,12 @@ Future<void> main() async { }); test('Initial value of isCodeRunning should be false', () { - expect(controller.isCodeRunning, false); + expect(controller.codeRunner.isCodeRunning, false); }); test('Initial value of pipelineOptions should be empty string', () { - expect(controller.pipelineOptions, null); controller.setSdk(Sdk.go); - expect(controller.pipelineOptions, ''); + expect(controller.codeRunner.pipelineOptions, ''); }); test('source', () { @@ -80,10 +79,10 @@ Future<void> main() async { descriptor: emptyDescriptor, setCurrentSdk: true, ); - expect(controller.isExampleChanged, false); + expect(controller.codeRunner.isExampleChanged, false); controller.snippetEditingController?.fileControllers.first .codeController.text = 'test'; - expect(controller.isExampleChanged, true); + expect(controller.codeRunner.isExampleChanged, true); }, ); @@ -95,9 +94,9 @@ Future<void> main() async { descriptor: emptyDescriptor, setCurrentSdk: true, ); - expect(controller.isExampleChanged, false); + expect(controller.codeRunner.isExampleChanged, false); controller.setPipelineOptions('test options'); - expect(controller.isExampleChanged, true); + expect(controller.codeRunner.isExampleChanged, true); }, ); }); @@ -156,8 +155,8 @@ Future<void> main() async { test( 'If Playground state result is empty, then resetError should break the execution', () { - controller.resetError(); - expect(controller.result, null); + controller.resetErrorMessageText(); + expect(controller.codeRunner.result, null); }, ); @@ -166,7 +165,7 @@ Future<void> main() async { () { controller.setSdk(Sdk.go); controller.addListener(() { - expect(controller.pipelineOptions, 'test options'); + expect(controller.codeRunner.pipelineOptions, 'test options'); }); controller.setPipelineOptions('test options'); },