No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

doc_test.go 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. package caddyhugo
  2. import (
  3. "path"
  4. "sync"
  5. "testing"
  6. "time"
  7. "git.stephensearles.com/stephen/acedoc"
  8. )
  9. func TestEdits(t *testing.T) {
  10. w := NewWorld(t)
  11. defer w.Clean()
  12. const title = "sometitle"
  13. var (
  14. mtx sync.Mutex
  15. contentPath = path.Join("content", title+".md")
  16. // we will send these to the doc
  17. send = []acedoc.Delta{
  18. acedoc.Insert(0, 0, "hello"),
  19. acedoc.Insert(0, 5, " world"),
  20. acedoc.Insert(0, 11, " world"),
  21. }
  22. // we will use this to track what we get out of the doc
  23. received = []acedoc.Delta{}
  24. )
  25. // prepare a new post
  26. w.CH.NewContent(title, "")
  27. // start an edit session
  28. es, err := w.CH.editSession(contentPath)
  29. if err != nil {
  30. t.Fatal("error creating document client:", err)
  31. }
  32. // register a client that we will use to push the deltas. we dont need
  33. // to actually do anything to receive deltas here, though.
  34. c := es.doc.Client(acedoc.DeltaHandlerFunc(func(ds []acedoc.Delta) error {
  35. return nil
  36. }))
  37. // register an *extra* client that just adds to the received delta
  38. // slice we're tracking
  39. es.doc.Client(acedoc.DeltaHandlerFunc(func(ds []acedoc.Delta) error {
  40. mtx.Lock()
  41. defer mtx.Unlock()
  42. received = append(received, ds...)
  43. return nil
  44. }))
  45. // make sure we have an edit session
  46. _, ok := w.CH.hasEditSession(contentPath)
  47. if !ok {
  48. t.Fatal("expected there to be an established client")
  49. }
  50. // push the deltas
  51. c.PushDeltas(send...)
  52. // wait...
  53. <-time.After(5 * time.Second)
  54. // be sure we got the correct number of deltas back
  55. mtx.Lock()
  56. defer mtx.Unlock()
  57. if len(received) != len(send) {
  58. t.Errorf("expected %d deltas, received %d; expected: %v, received: %v", len(send), len(received), send, received)
  59. }
  60. }
  61. func TestDeltasSingle(t *testing.T) {
  62. w := NewWorld(t)
  63. defer w.Clean()
  64. const title = "test"
  65. _, err := w.CH.NewContent(title, "")
  66. if err != nil {
  67. t.Fatal("couldn't create new content:", err)
  68. }
  69. client := new(WebsocketTester)
  70. es, err := w.CH.editSession("content/" + title + ".md")
  71. if err != nil {
  72. t.Fatal("couldn't establish docref for client 0:", err)
  73. }
  74. go w.CH.handleDeltaConn(client, es)
  75. a := acedoc.Insert(0, 0, "a")
  76. // pretend to get one sent from the "browser"
  77. client.ReceiveJSON(w.CH.Message(a))
  78. // wait to make sure it was processed
  79. time.Sleep(50 * time.Millisecond)
  80. // we shouldn't have written back to the client,
  81. // so we expect to have written 0 *deltas*. (we may have written
  82. // empty messages without deltas because of the pings to the client)
  83. if len(client.wroteDeltas) != 0 {
  84. t.Errorf("client wrote %d deltas, should have written %d", len(client.wroteMessages), 0)
  85. t.Logf("%v", client.wroteMessages)
  86. }
  87. // we received one, so make sure that's counted properly
  88. if len(client.received) != 1 {
  89. t.Errorf("client has %d messages, should have received %d", len(client.received), 1)
  90. }
  91. }
  92. func TestDeltasDouble(t *testing.T) {
  93. w := NewWorld(t)
  94. defer w.Clean()
  95. const title = "test"
  96. _, err := w.CH.NewContent(title, "")
  97. if err != nil {
  98. t.Fatal("couldn't create new content:", err)
  99. }
  100. clientA := new(WebsocketTester)
  101. clientB := new(WebsocketTester)
  102. doc, err := w.CH.editSession("content/" + title + ".md")
  103. if err != nil {
  104. t.Fatal("couldn't establish docref for client 0:", err)
  105. }
  106. go w.CH.handleDeltaConn(clientA, doc)
  107. go w.CH.handleDeltaConn(clientB, doc)
  108. // send the first message, simulating the browser on clientA
  109. clientA.ReceiveJSON(w.CH.Message(acedoc.Insert(0, 0, "a")))
  110. time.Sleep(100 * time.Millisecond)
  111. clientA.mtx.Lock()
  112. clientB.mtx.Lock()
  113. // so we expect clientA to have written 0 messages, and
  114. // clientB to have written 1
  115. if len(clientA.wroteDeltas) != 0 || len(clientB.wroteDeltas) != 1 {
  116. t.Errorf("clientA wrote %d messages, should have written 0. clientB wrote %d, should have written 1", len(clientA.wroteMessages), len(clientB.wroteMessages))
  117. }
  118. // we received one via clientA and zero via clientB, so make sure
  119. // that's counted properly
  120. if len(clientA.received) != 1 || len(clientB.received) != 0 {
  121. t.Errorf("clientA has %d messages, should have received 1; clientB has %d messages, should have received 0", len(clientA.received), len(clientB.received))
  122. }
  123. clientA.mtx.Unlock()
  124. clientB.mtx.Unlock()
  125. // send the second message, via clientB
  126. clientB.ReceiveJSON(w.CH.Message(acedoc.Insert(0, 0, "b")))
  127. time.Sleep(400 * time.Millisecond)
  128. clientA.mtx.Lock()
  129. clientB.mtx.Lock()
  130. // so we expect clientA to have written 1 delta this time, and
  131. // clientB to have written nothing new, so 1 still
  132. if len(clientA.wroteDeltas) != 1 || len(clientB.wroteDeltas) != 1 {
  133. t.Errorf("clientA wrote %d messages, should have written 1. clientB wrote %d, should have written 1 (just from before)", len(clientA.wroteMessages), len(clientB.wroteMessages))
  134. }
  135. // we received zero (new) via clientA and one via clientB, so make sure
  136. // that's counted properly
  137. if len(clientA.received) != 1 || len(clientB.received) != 1 {
  138. t.Errorf("clientA has %d messages, should have received 1; clientB has %d messages, should have received 1", len(clientA.received), len(clientB.received))
  139. }
  140. clientA.mtx.Unlock()
  141. clientB.mtx.Unlock()
  142. }
  143. func TestDeltasMulti(t *testing.T) {
  144. w := NewWorld(t)
  145. defer w.Clean()
  146. const title = "test"
  147. _, err := w.CH.NewContent(title, "")
  148. if err != nil {
  149. t.Fatal("couldn't create new content:", err)
  150. }
  151. clients := []*WebsocketTester{{}, {}, {}}
  152. doc, err := w.CH.editSession("content/" + title + ".md")
  153. if err != nil {
  154. t.Fatal("couldn't establish edit session:", err)
  155. }
  156. go w.CH.handleDeltaConn(clients[0], doc)
  157. go w.CH.handleDeltaConn(clients[1], doc)
  158. go w.CH.handleDeltaConn(clients[2], doc)
  159. time.Sleep(100 * time.Millisecond)
  160. a := acedoc.Insert(0, 0, "a")
  161. b := acedoc.Insert(0, 0, "b")
  162. c := acedoc.Insert(0, 0, "c")
  163. clients[0].ReceiveJSON(w.CH.Message(a))
  164. clients[1].ReceiveJSON(w.CH.Message(b))
  165. clients[2].ReceiveJSON(w.CH.Message(c))
  166. time.Sleep(1000 * time.Millisecond)
  167. for i, client := range clients {
  168. client.mtx.Lock()
  169. // all clients should have "written" 2 deltas out to their "browser"
  170. // that came from the other clients
  171. if len(client.wroteDeltas) != 2 {
  172. t.Errorf("client %d wrote %d deltas, should have written 2", i, len(client.wroteDeltas))
  173. }
  174. // all clients "received" 1 message from the "browser"
  175. if len(client.received) != 1 {
  176. t.Errorf("client %d has %d messages, should have received 1", i, len(client.received))
  177. }
  178. client.mtx.Unlock()
  179. }
  180. }
  181. func TestPagesInPagesOut(t *testing.T) {
  182. w := NewWorld(t)
  183. defer w.Clean()
  184. // check there's no content at first
  185. c, err := GetContent(w.BlogFolder, w.CH.HugoSites)
  186. if err != nil {
  187. t.Fatalf("couldn't get content from a blank test environment: %v", err)
  188. }
  189. if len(c) != 0 {
  190. t.Fatalf("expected a blank test environment, but saw %d pages", len(c))
  191. }
  192. titles := []string{
  193. "test1",
  194. "TEST 2!!",
  195. }
  196. found := map[string]bool{}
  197. // create some known content
  198. for i, title := range titles {
  199. w.CH.NewContent(title, "")
  200. c, err = GetContent(w.BlogFolder, w.CH.HugoSites)
  201. if err != nil {
  202. t.Fatalf("couldn't get content from the test environment: %v", err)
  203. }
  204. if len(c)-1 != i {
  205. t.Fatalf("expected %d page, but saw %d pages", i+1, len(c))
  206. }
  207. }
  208. // make sure we get the content out that we just created
  209. c, err = GetContent(w.BlogFolder, w.CH.HugoSites)
  210. if err != nil {
  211. t.Fatalf("couldn't get content from the test environment: %v", err)
  212. }
  213. for _, content := range c {
  214. if content.Metadata == nil {
  215. t.Errorf("didn't see metadata for %q", content.Filename)
  216. }
  217. found[content.Filename] = true
  218. }
  219. var missingSomething bool
  220. for _, title := range titles {
  221. adjusted := path.Join("content", docname(title)+".md")
  222. if !found[adjusted] {
  223. missingSomething = true
  224. t.Errorf("expected to find title %q, but didn't see it", adjusted)
  225. }
  226. }
  227. if missingSomething {
  228. t.Logf("found titles: %v", found)
  229. }
  230. }