sockets.rs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. //! Basic tests for real-time collaboration.
  2. use std::time::Duration;
  3. use anyhow::Result;
  4. use common::*;
  5. use log::info;
  6. use operational_transform::OperationSeq;
  7. use rustpad_server::{server, ServerConfig};
  8. use serde_json::json;
  9. use tokio::time;
  10. pub mod common;
  11. #[tokio::test]
  12. async fn test_single_operation() -> Result<()> {
  13. pretty_env_logger::try_init().ok();
  14. let filter = server(ServerConfig::default());
  15. expect_text(&filter, "foobar", "").await;
  16. let mut client = connect(&filter, "foobar").await?;
  17. let msg = client.recv().await?;
  18. assert_eq!(msg, json!({ "Identity": 0 }));
  19. let mut operation = OperationSeq::default();
  20. operation.insert("hello");
  21. let msg = json!({
  22. "Edit": {
  23. "revision": 0,
  24. "operation": operation
  25. }
  26. });
  27. info!("sending ClientMsg {}", msg);
  28. client.send(&msg).await;
  29. let msg = client.recv().await?;
  30. assert_eq!(
  31. msg,
  32. json!({
  33. "History": {
  34. "start": 0,
  35. "operations": [
  36. { "id": 0, "operation": ["hello"] }
  37. ]
  38. }
  39. })
  40. );
  41. expect_text(&filter, "foobar", "hello").await;
  42. Ok(())
  43. }
  44. #[tokio::test]
  45. async fn test_invalid_operation() -> Result<()> {
  46. pretty_env_logger::try_init().ok();
  47. let filter = server(ServerConfig::default());
  48. expect_text(&filter, "foobar", "").await;
  49. let mut client = connect(&filter, "foobar").await?;
  50. let msg = client.recv().await?;
  51. assert_eq!(msg, json!({ "Identity": 0 }));
  52. let mut operation = OperationSeq::default();
  53. operation.insert("hello");
  54. let msg = json!({
  55. "Edit": {
  56. "revision": 1,
  57. "operation": operation
  58. }
  59. });
  60. info!("sending ClientMsg {}", msg);
  61. client.send(&msg).await;
  62. client.recv_closed().await?;
  63. Ok(())
  64. }
  65. #[tokio::test]
  66. async fn test_concurrent_transform() -> Result<()> {
  67. pretty_env_logger::try_init().ok();
  68. let filter = server(ServerConfig::default());
  69. // Connect the first client
  70. let mut client = connect(&filter, "foobar").await?;
  71. let msg = client.recv().await?;
  72. assert_eq!(msg, json!({ "Identity": 0 }));
  73. // Insert the first operation
  74. let mut operation = OperationSeq::default();
  75. operation.insert("hello");
  76. let msg = json!({
  77. "Edit": {
  78. "revision": 0,
  79. "operation": operation
  80. }
  81. });
  82. info!("sending ClientMsg {}", msg);
  83. client.send(&msg).await;
  84. let msg = client.recv().await?;
  85. assert_eq!(
  86. msg,
  87. json!({
  88. "History": {
  89. "start": 0,
  90. "operations": [
  91. { "id": 0, "operation": ["hello"] }
  92. ]
  93. }
  94. })
  95. );
  96. // Insert the second operation
  97. let mut operation = OperationSeq::default();
  98. operation.retain(2);
  99. operation.delete(1);
  100. operation.insert("n");
  101. operation.retain(2);
  102. let msg = json!({
  103. "Edit": {
  104. "revision": 1,
  105. "operation": operation
  106. }
  107. });
  108. info!("sending ClientMsg {}", msg);
  109. client.send(&msg).await;
  110. let msg = client.recv().await?;
  111. assert_eq!(
  112. msg,
  113. json!({
  114. "History": {
  115. "start": 1,
  116. "operations": [
  117. { "id": 0, "operation": [2, "n", -1, 2] }
  118. ]
  119. }
  120. })
  121. );
  122. expect_text(&filter, "foobar", "henlo").await;
  123. // Connect the second client
  124. let mut client2 = connect(&filter, "foobar").await?;
  125. let msg = client2.recv().await?;
  126. assert_eq!(msg, json!({ "Identity": 1 }));
  127. // Insert a concurrent operation before seeing the existing history
  128. time::sleep(Duration::from_millis(50)).await;
  129. let mut operation = OperationSeq::default();
  130. operation.insert("~rust~");
  131. let msg = json!({
  132. "Edit": {
  133. "revision": 0,
  134. "operation": operation
  135. }
  136. });
  137. info!("sending ClientMsg {}", msg);
  138. client2.send(&msg).await;
  139. // Receive the existing history
  140. let msg = client2.recv().await?;
  141. assert_eq!(
  142. msg,
  143. json!({
  144. "History": {
  145. "start": 0,
  146. "operations": [
  147. { "id": 0, "operation": ["hello"] },
  148. { "id": 0, "operation": [2, "n", -1, 2] }
  149. ]
  150. }
  151. })
  152. );
  153. // Expect to receive a transformed operation
  154. let transformed_op = json!({
  155. "History": {
  156. "start": 2,
  157. "operations": [
  158. { "id": 1, "operation": ["~rust~", 5] },
  159. ]
  160. }
  161. });
  162. // ... in the first client
  163. let msg = client.recv().await?;
  164. assert_eq!(msg, transformed_op);
  165. // ... and in the second client
  166. let msg = client2.recv().await?;
  167. assert_eq!(msg, transformed_op);
  168. expect_text(&filter, "foobar", "~rust~henlo").await;
  169. Ok(())
  170. }
  171. #[tokio::test]
  172. async fn test_set_language() -> Result<()> {
  173. pretty_env_logger::try_init().ok();
  174. let filter = server(ServerConfig::default());
  175. let mut client = connect(&filter, "foobar").await?;
  176. let msg = client.recv().await?;
  177. assert_eq!(msg, json!({ "Identity": 0 }));
  178. let msg = json!({ "SetLanguage": "javascript" });
  179. client.send(&msg).await;
  180. let msg = client.recv().await?;
  181. assert_eq!(msg, json!({ "Language": "javascript" }));
  182. let mut client2 = connect(&filter, "foobar").await?;
  183. let msg = client2.recv().await?;
  184. assert_eq!(msg, json!({ "Identity": 1 }));
  185. let msg = client2.recv().await?;
  186. assert_eq!(msg, json!({ "Language": "javascript" }));
  187. let msg = json!({ "SetLanguage": "python" });
  188. client2.send(&msg).await;
  189. let msg = client.recv().await?;
  190. assert_eq!(msg, json!({ "Language": "python" }));
  191. let msg = client2.recv().await?;
  192. assert_eq!(msg, json!({ "Language": "python" }));
  193. expect_text(&filter, "foobar", "").await;
  194. Ok(())
  195. }