Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package nntp | 5 package nntp |
6 | 6 |
7 import ( | 7 import ( |
8 "bufio" | |
9 "bytes" | |
8 "fmt" | 10 "fmt" |
11 "io" | |
12 "io/ioutil" | |
13 "os" | |
14 "strings" | |
9 "testing" | 15 "testing" |
10 "time" | 16 "time" |
11 ) | 17 ) |
12 | 18 |
13 func TestSanityChecks(t *testing.T) { | 19 func TestSanityChecks(t *testing.T) { |
14 » if _, err := Connect("", "", ""); err == nil { | 20 » if _, err := Dial("", ""); err == nil { |
15 » » t.Fatal("Connect should require at least a destination address." ) | 21 » » t.Fatal("Dial should require at least a destination address.") |
16 » } | 22 » } |
23 } | |
24 | |
25 type faker struct { | |
26 » io.Writer | |
27 } | |
28 | |
29 func (f faker) Close() os.Error { | |
30 » return nil | |
17 } | 31 } |
18 | 32 |
19 func TestBasic(t *testing.T) { | 33 func TestBasic(t *testing.T) { |
20 » conn, err := Connect("news.gmane.org:119", "", "") | 34 » basicServer = strings.Join(strings.Split(basicServer, "\n", 0), "\r\n") |
rsc
2010/03/28 07:36:29
I'd like not to introduce any more tests that depe
cemeyer
2010/03/29 04:22:59
Done.
| |
21 » if err != nil { | 35 » basicClient = strings.Join(strings.Split(basicClient, "\n", 0), "\r\n") |
22 » » t.Fatal("Connect shouldn't error: " + err.String()) | 36 |
23 » } | 37 » var cmdbuf bytes.Buffer |
38 » var fake faker | |
39 » fake.Writer = &cmdbuf | |
40 | |
41 » conn := &Conn{conn: fake, r: bufio.NewReader(strings.NewReader(basicServ er))} | |
24 | 42 |
25 // Test some global commands that don't take arguments | 43 // Test some global commands that don't take arguments |
26 » if _, err = conn.Capabilities(); err != nil { | 44 » if _, err := conn.Capabilities(); err != nil { |
27 t.Fatal("should be able to request CAPABILITIES after connecting : " + err.String()) | 45 t.Fatal("should be able to request CAPABILITIES after connecting : " + err.String()) |
28 } | 46 } |
29 | 47 |
30 » sdate, err := conn.Date() | 48 » _, err := conn.Date() |
31 if err != nil { | 49 if err != nil { |
32 t.Fatal("should be able to send DATE: " + err.String()) | 50 t.Fatal("should be able to send DATE: " + err.String()) |
33 } | 51 } |
34 » cdate := time.UTC() | 52 |
35 | 53 » /* |
36 » if sdate.Year != cdate.Year || sdate.Month != cdate.Month || sdate.Day ! = cdate.Day { | 54 » » Test broken until time.Parse adds this format. |
37 » » t.Fatal("DATE seems off, probably erroneous: " + sdate.String()) | 55 » » cdate := time.UTC() |
38 » } | 56 » » if sdate.Year != cdate.Year || sdate.Month != cdate.Month || sda te.Day != cdate.Day { |
57 » » » t.Fatal("DATE seems off, probably erroneous: " + sdate.S tring()) | |
58 » » } | |
59 » */ | |
39 | 60 |
40 // Test LIST (implicit ACTIVE) | 61 // Test LIST (implicit ACTIVE) |
41 » if _, err = conn.ListActive(); err != nil { | 62 » if _, err = conn.List(); err != nil { |
42 t.Fatal("LIST should work: " + err.String()) | 63 t.Fatal("LIST should work: " + err.String()) |
43 } | 64 } |
44 | 65 |
45 tt := new(time.Time) | 66 tt := new(time.Time) |
46 tt.Year = 2010 | 67 tt.Year = 2010 |
47 tt.Month = 3 | 68 tt.Month = 3 |
48 tt.Day = 1 | 69 tt.Day = 1 |
49 | 70 |
50 » // Browse a few groups... | 71 » const grp = "gmane.comp.lang.go.general" |
51 » for _, val := range []string{"go", "ruby", "haskell"} { | 72 » _, l, h, err := conn.Group(grp) |
52 » » grp := "gmane.comp.lang." + val + ".general" | 73 » if err != nil { |
53 | 74 » » t.Fatal("Group shouldn't error: " + err.String()) |
54 » » _, l, h, err := conn.Group(grp) | 75 » } |
55 » » if err != nil { | 76 |
56 » » » t.Fatal("Group shouldn't error: " + err.String()) | 77 » // test STAT, NEXT, and LAST |
57 » » } | 78 » if _, _, err = conn.Stat(""); err != nil { |
58 | 79 » » t.Fatal("should be able to STAT after selecting a group: " + err .String()) |
59 » » // test STAT, NEXT, and LAST | 80 » } |
60 » » if _, _, err = conn.Stat(""); err != nil { | 81 » if _, _, err = conn.Next(); err != nil { |
61 » » » t.Fatal("should be able to STAT after selecting a group: " + err.String()) | 82 » » t.Fatal("should be able to NEXT after selecting a group: " + err .String()) |
62 » » } | 83 » } |
63 » » if _, _, err = conn.Next(); err != nil { | 84 » if _, _, err = conn.Last(); err != nil { |
64 » » » t.Fatal("should be able to NEXT after selecting a group: " + err.String()) | 85 » » t.Fatal("should be able to LAST after a NEXT selecting a group: " + err.String()) |
65 » » } | 86 » } |
66 » » if _, _, err = conn.Last(); err != nil { | 87 |
67 » » » t.Fatal("should be able to LAST after a NEXT selecting a group: " + err.String()) | 88 » // Can we grab articles? |
68 » » } | 89 » a, err := conn.Article(fmt.Sprintf("%d", l)) |
69 | 90 » if err != nil { |
70 » » // Can we grab articles? | 91 » » t.Fatal("should be able to fetch the low article: " + err.String ()) |
71 » » if _, err = conn.Article(fmt.Sprintf("%d", l)); err != nil { | 92 » } |
72 » » » t.Fatal("should be able to fetch the low article: " + er r.String()) | 93 » body, err := ioutil.ReadAll(a.Body) |
73 » » } | 94 » if err != nil { |
74 | 95 » » t.Fatal("error reading reader: " + err.String()) |
75 » » // Just headers? | 96 » } |
76 » » if _, err = conn.Head(fmt.Sprintf("%d", h)); err != nil { | 97 |
77 » » » t.Fatal("should be able to fetch the high article: " + e rr.String()) | 98 » // Test that the article body doesn't get mangled. |
78 » » } | 99 » expectedbody := `Blah, blah. |
79 | 100 .A single leading . |
80 » » // Without an id? | 101 Fin. |
81 » » if _, err = conn.Head(""); err != nil { | 102 ` |
82 » » » t.Fatal("should be able to fetch the selected article wi thout specifying an id: " + err.String()) | 103 » if !bytes.Equal([]byte(expectedbody), body) { |
83 » » } | 104 » » t.Fatalf("article body read incorrectly; got:\n%s\nExpected:\n%s ", body, expectedbody) |
84 | 105 » } |
85 » » // How about bad articles? Do they error? | 106 |
86 » » if _, err = conn.Head(fmt.Sprintf("%d", l-1)); err == nil { | 107 » // Test articleReader |
87 » » » t.Fatal("shouldn't be able to fetch articles lower than low") | 108 » expectedart := `Message-Id: <b@c.d> |
88 » » } | 109 |
89 » » if _, err = conn.Head(fmt.Sprintf("%d", h+1)); err == nil { | 110 Body. |
90 » » » t.Fatal("shouldn't be able to fetch articles higher than high") | 111 ` |
91 » » } | 112 » a, err = conn.Article(fmt.Sprintf("%d", l+1)) |
92 | 113 » if err != nil { |
93 » » // Just the body? | 114 » » t.Fatal("shouldn't error reading article low+1: " + err.String() ) |
94 » » if _, err = conn.Body(fmt.Sprintf("%d", l)); err != nil { | 115 » } |
95 » » » t.Fatal("should be able to fetch the low article body\n" + err.String()) | 116 » var abuf bytes.Buffer |
96 » » } | 117 » _, err = a.WriteTo(&abuf) |
97 | 118 » if err != nil { |
98 » » // NEWNEWS (disabled because gmane doesn't allow it) | 119 » » t.Fatal("shouldn't error writing out article: " + err.String()) |
99 » » /* | 120 » } |
100 » » » if _, err = conn.NewNews(grp, tt); err != nil { | 121 » actualart := abuf.String() |
101 » » » » t.Fatal("newnews should work: " + err.String()) | 122 » if actualart != expectedart { |
102 » » » } | 123 » » t.Fatalf("articleReader broke; got:\n%s\nExpected\n%s", actualar t, expectedart) |
103 » » */ | 124 » } |
104 » } | 125 |
126 » // Just headers? | |
127 » if _, err = conn.Head(fmt.Sprintf("%d", h)); err != nil { | |
128 » » t.Fatal("should be able to fetch the high article: " + err.Strin g()) | |
129 » } | |
130 | |
131 » // Without an id? | |
132 » if _, err = conn.Head(""); err != nil { | |
133 » » t.Fatal("should be able to fetch the selected article without sp ecifying an id: " + err.String()) | |
134 » } | |
135 | |
136 » // How about bad articles? Do they error? | |
137 » if _, err = conn.Head(fmt.Sprintf("%d", l-1)); err == nil { | |
138 » » t.Fatal("shouldn't be able to fetch articles lower than low") | |
139 » } | |
140 » if _, err = conn.Head(fmt.Sprintf("%d", h+1)); err == nil { | |
141 » » t.Fatal("shouldn't be able to fetch articles higher than high") | |
142 » } | |
143 | |
144 » // Just the body? | |
145 » r, err := conn.Body(fmt.Sprintf("%d", l)) | |
146 » if err != nil { | |
147 » » t.Fatal("should be able to fetch the low article body\n" + err.S tring()) | |
148 » } | |
149 » if _, err = ioutil.ReadAll(r); err != nil { | |
150 » » t.Fatal("error reading reader: " + err.String()) | |
151 » } | |
152 | |
153 » if _, err = conn.NewNews(grp, tt); err != nil { | |
154 » » t.Fatal("newnews should work: " + err.String()) | |
155 » } | |
156 | |
105 | 157 |
106 // NewGroups | 158 // NewGroups |
107 if _, err = conn.NewGroups(tt); err != nil { | 159 if _, err = conn.NewGroups(tt); err != nil { |
108 t.Fatal("newgroups shouldn't error " + err.String()) | 160 t.Fatal("newgroups shouldn't error " + err.String()) |
109 } | 161 } |
110 | 162 |
111 if err = conn.Quit(); err != nil { | 163 if err = conn.Quit(); err != nil { |
112 t.Fatal("Quit shouldn't error: " + err.String()) | 164 t.Fatal("Quit shouldn't error: " + err.String()) |
113 } | 165 } |
114 } | 166 |
167 » actualcmds := cmdbuf.String() | |
168 » if basicClient != actualcmds { | |
169 » » t.Fatalf("Got:\n%s\nExpected\n%s", actualcmds, basicClient) | |
170 » } | |
171 } | |
172 | |
173 var basicServer = `101 Capability list: | |
174 VERSION 2 | |
175 . | |
176 111 20100329034158 | |
177 215 Blah blah | |
178 foo 7 3 y | |
179 bar 000008 02 m | |
180 . | |
181 211 100 1 100 gmane.comp.lang.go.general | |
182 223 1 <a@b.c> status | |
183 223 2 <b@c.d> Article retrieved | |
184 223 1 <a@b.c> Article retrieved | |
185 220 1 <a@b.c> article | |
186 Path: fake!not-for-mail | |
187 From: Someone | |
188 Newsgroups: gmane.comp.lang.go.general | |
189 Subject: [go-nuts] What about base members? | |
190 Message-ID: <a@b.c> | |
191 | |
192 Blah, blah. | |
193 ..A single leading . | |
194 Fin. | |
195 . | |
196 220 2 <b@c.d> article | |
197 Message-ID: <b@c.d> | |
198 | |
199 Body. | |
200 . | |
201 221 100 <c@d.e> head | |
202 Path: fake!not-for-mail | |
203 Message-ID: <c@d.e> | |
204 . | |
205 221 100 <c@d.e> head | |
206 Path: fake!not-for-mail | |
207 Message-ID: <c@d.e> | |
208 . | |
209 423 Bad article number | |
210 423 Bad article number | |
211 222 1 <a@b.c> body | |
212 Blah, blah. | |
213 ..A single leading . | |
214 Fin. | |
215 . | |
216 230 list of new articles by message-id follows | |
217 <d@e.c> | |
218 . | |
219 231 New newsgroups follow | |
220 . | |
221 205 Bye! | |
222 ` | |
223 | |
224 var basicClient = `CAPABILITIES | |
225 DATE | |
226 LIST | |
227 GROUP gmane.comp.lang.go.general | |
228 STAT | |
229 NEXT | |
230 LAST | |
231 ARTICLE 1 | |
232 ARTICLE 2 | |
233 HEAD 100 | |
234 HEAD | |
235 HEAD 0 | |
236 HEAD 101 | |
237 BODY 1 | |
238 NEWNEWS gmane.comp.lang.go.general 20100301 000000 GMT | |
239 NEWGROUPS 20100301 000000 GMT | |
240 QUIT | |
241 ` | |
LEFT | RIGHT |