diff --git a/akka-docs/src/main/paradox/stream/operators/Source/repeat.md b/akka-docs/src/main/paradox/stream/operators/Source/repeat.md
index 347cfb3985..ba87b3f9f1 100644
--- a/akka-docs/src/main/paradox/stream/operators/Source/repeat.md
+++ b/akka-docs/src/main/paradox/stream/operators/Source/repeat.md
@@ -1,20 +1,34 @@
# Source.repeat
-Stream a single object repeatedly
+Stream a single object repeatedly.
@ref[Source operators](../index.md#source-operators)
-@@@div { .group-scala }
-
## Signature
-@@signature [Source.scala](/akka-stream/src/main/scala/akka/stream/scaladsl/Source.scala) { #repeat }
-
-@@@
+@apidoc[Source.repeat](Source$) { scala="#repeat[T](element:T):akka.stream.scaladsl.Source[T,akka.NotUsed]" java="#repeat(T)" }
## Description
-Stream a single object repeatedly
+This source emits a single element repeatedly. It never completes, if you want the stream to be finite you will need to limit it by combining with another operator
+
+See also:
+
+* @ref:[`single`](single.md) Stream a single object once.
+* @ref:[`tick`](tick.md) A periodical repetition of an arbitrary object.
+* @ref:[`cycle`](cycle.md) Stream iterator in cycled manner.
+
+## Example
+
+This example prints the first 4 elements emitted by `Source.repeat`.
+
+Scala
+: @@snip [snip](/akka-stream-tests/src/test/scala/akka/stream/scaladsl/SourceSpec.scala) { #repeat }
+
+Java
+: @@snip [snip](/akka-stream-tests/src/test/java/akka/stream/javadsl/SourceTest.java) { #repeat }
+
+
## Reactive Streams semantics
diff --git a/akka-docs/src/main/paradox/stream/operators/Source/single.md b/akka-docs/src/main/paradox/stream/operators/Source/single.md
index aa2777f3a9..d25d55e247 100644
--- a/akka-docs/src/main/paradox/stream/operators/Source/single.md
+++ b/akka-docs/src/main/paradox/stream/operators/Source/single.md
@@ -1,20 +1,22 @@
# Source.single
-Stream a single object
+Stream a single object once.
@ref[Source operators](../index.md#source-operators)
-@@@div { .group-scala }
-
## Signature
-@@signature [Source.scala](/akka-stream/src/main/scala/akka/stream/scaladsl/Source.scala) { #single }
-
-@@@
+@apidoc[Source.single](Source$) { scala="#single[T](element:T):akka.stream.scaladsl.Source[T,akka.NotUsed]" java="#single(T)" }
## Description
-Stream a single object
+Stream a single object once and complete after thereafter.
+
+See also:
+
+* @ref:[`repeat`](repeat.md) Stream a single object repeatedly.
+* @ref:[`tick`](tick.md) A periodical repetition of an arbitrary object.
+* @ref:[`cycle`](cycle.md) Stream iterator in cycled manner.
## Examples
diff --git a/akka-docs/src/main/paradox/stream/operators/Source/tick.md b/akka-docs/src/main/paradox/stream/operators/Source/tick.md
index af2201b864..45d2c17dbf 100644
--- a/akka-docs/src/main/paradox/stream/operators/Source/tick.md
+++ b/akka-docs/src/main/paradox/stream/operators/Source/tick.md
@@ -28,6 +28,11 @@ example for achieving a periodical element that changes over time.
@@@
+See also:
+
+* @ref:[`repeat`](repeat.md) Stream a single object repeatedly.
+* @ref:[`cycle`](cycle.md) Stream iterator in cycled manner.
+
## Examples
This first example prints to standard out periodically:
diff --git a/akka-docs/src/main/paradox/stream/operators/index.md b/akka-docs/src/main/paradox/stream/operators/index.md
index 9ac5fbc2c9..6175ada555 100644
--- a/akka-docs/src/main/paradox/stream/operators/index.md
+++ b/akka-docs/src/main/paradox/stream/operators/index.md
@@ -37,8 +37,8 @@ These built-in sources are available from @scala[`akka.stream.scaladsl.Source`]
|Source|@ref[maybe](Source/maybe.md)|Create a source that emits once the materialized @scala[`Promise`] @java[`CompletableFuture`] is completed with a value.|
|Source|@ref[queue](Source/queue.md)|Materialize a `SourceQueue` onto which elements can be pushed for emitting from the source. |
|Source|@ref[range](Source/range.md)|Emit each integer in a range, with an option to take bigger steps than 1.|
-|Source|@ref[repeat](Source/repeat.md)|Stream a single object repeatedly|
-|Source|@ref[single](Source/single.md)|Stream a single object|
+|Source|@ref[repeat](Source/repeat.md)|Stream a single object repeatedly.|
+|Source|@ref[single](Source/single.md)|Stream a single object once.|
|Source|@ref[tick](Source/tick.md)|A periodical repetition of an arbitrary object.|
|Source|@ref[unfold](Source/unfold.md)|Stream the result of a function as long as it returns a @scala[`Some`] @java[non empty `Optional`].|
|Source|@ref[unfoldAsync](Source/unfoldAsync.md)|Just like `unfold` but the fold function returns a @scala[`Future`] @java[`CompletionStage`].|
diff --git a/akka-stream-tests/src/test/java/akka/stream/javadsl/SourceTest.java b/akka-stream-tests/src/test/java/akka/stream/javadsl/SourceTest.java
index 028fe4970c..9835abce67 100644
--- a/akka-stream-tests/src/test/java/akka/stream/javadsl/SourceTest.java
+++ b/akka-stream-tests/src/test/java/akka/stream/javadsl/SourceTest.java
@@ -626,6 +626,20 @@ public class SourceTest extends StreamTest {
for (Integer i : result) assertEquals(i, (Integer) 42);
}
+ @Test
+ public void mustRepeatForDocs() throws Exception {
+ // #repeat
+ Source source = Source.repeat(42);
+ CompletionStage f = source.take(4).runWith(Sink.foreach(System.out::println), system);
+ // 42
+ // 42
+ // 42
+ // 42
+ // #repeat
+ final Done result = f.toCompletableFuture().get(3, TimeUnit.SECONDS);
+ assertEquals(Done.done(), result);
+ }
+
@Test
public void mustBeAbleToUseQueue() throws Exception {
final Pair, CompletionStage>> x =
diff --git a/akka-stream-tests/src/test/scala/akka/stream/scaladsl/SourceSpec.scala b/akka-stream-tests/src/test/scala/akka/stream/scaladsl/SourceSpec.scala
index ff8f7da402..bbd25039d2 100644
--- a/akka-stream-tests/src/test/scala/akka/stream/scaladsl/SourceSpec.scala
+++ b/akka-stream-tests/src/test/scala/akka/stream/scaladsl/SourceSpec.scala
@@ -4,6 +4,7 @@
package akka.stream.scaladsl
+import akka.Done
import akka.stream.testkit.Utils.TE
import akka.testkit.DefaultTimeout
import com.github.ghik.silencer.silent
@@ -215,6 +216,18 @@ class SourceSpec extends StreamSpec with DefaultTimeout {
f.futureValue.size should ===(1000)
f.futureValue.toSet should ===(Set(42))
}
+
+ "repeat example" in {
+ // #repeat
+ val source: Source[Int, NotUsed] = Source.repeat(42)
+ val f = source.take(4).runWith(Sink.foreach(println))
+ // 42
+ // 42
+ // 42
+ // 42
+ // #repeat
+ f.futureValue shouldBe Done
+ }
}
"Unfold Source" must {