| ... | ... |
@@ -164,3 +164,30 @@ func Tail(src io.Reader, n int, dst *[]string) {
|
| 164 | 164 |
*dst = append(*dst, v.(string)) |
| 165 | 165 |
}) |
| 166 | 166 |
} |
| 167 |
+ |
|
| 168 |
+// AddEnv starts a new goroutine which will decode all subsequent data |
|
| 169 |
+// as a stream of json-encoded objects, and point `dst` to the last |
|
| 170 |
+// decoded object. |
|
| 171 |
+// The result `env` can be queried using the type-neutral Env interface. |
|
| 172 |
+// It is not safe to query `env` until the Output is closed. |
|
| 173 |
+func (o *Output) AddEnv() (dst *Env, err error) {
|
|
| 174 |
+ src, err := o.AddPipe() |
|
| 175 |
+ if err != nil {
|
|
| 176 |
+ return nil, err |
|
| 177 |
+ } |
|
| 178 |
+ dst = &Env{}
|
|
| 179 |
+ o.tasks.Add(1) |
|
| 180 |
+ go func() {
|
|
| 181 |
+ defer o.tasks.Done() |
|
| 182 |
+ decoder := NewDecoder(src) |
|
| 183 |
+ for {
|
|
| 184 |
+ env, err := decoder.Decode() |
|
| 185 |
+ if err != nil {
|
|
| 186 |
+ return |
|
| 187 |
+ } |
|
| 188 |
+ *dst= *env |
|
| 189 |
+ } |
|
| 190 |
+ }() |
|
| 191 |
+ return dst, nil |
|
| 192 |
+} |
|
| 193 |
+ |
| ... | ... |
@@ -72,6 +72,26 @@ func (w *sentinelWriteCloser) Close() error {
|
| 72 | 72 |
return nil |
| 73 | 73 |
} |
| 74 | 74 |
|
| 75 |
+func TestOutputAddEnv(t *testing.T) {
|
|
| 76 |
+ input := "{\"foo\": \"bar\", \"answer_to_life_the_universe_and_everything\": 42}"
|
|
| 77 |
+ o := NewOutput() |
|
| 78 |
+ result, err := o.AddEnv() |
|
| 79 |
+ if err != nil {
|
|
| 80 |
+ t.Fatal(err) |
|
| 81 |
+ } |
|
| 82 |
+ o.Write([]byte(input)) |
|
| 83 |
+ o.Close() |
|
| 84 |
+ if v := result.Get("foo"); v != "bar" {
|
|
| 85 |
+ t.Errorf("Expected %v, got %v", "bar", v)
|
|
| 86 |
+ } |
|
| 87 |
+ if v := result.GetInt("answer_to_life_the_universe_and_everything"); v != 42 {
|
|
| 88 |
+ t.Errorf("Expected %v, got %v", 42, v)
|
|
| 89 |
+ } |
|
| 90 |
+ if v := result.Get("this-value-doesnt-exist"); v != "" {
|
|
| 91 |
+ t.Errorf("Expected %v, got %v", "", v)
|
|
| 92 |
+ } |
|
| 93 |
+} |
|
| 94 |
+ |
|
| 75 | 95 |
func TestOutputAddClose(t *testing.T) {
|
| 76 | 96 |
o := NewOutput() |
| 77 | 97 |
var s sentinelWriteCloser |