1// TODO: under unit test 2 3package reporting 4 5import ( 6 "bytes" 7 "encoding/json" 8 "fmt" 9 "strings" 10) 11 12type JsonReporter struct { 13 out *Printer 14 currentKey []string 15 current *ScopeResult 16 index map[string]*ScopeResult 17 scopes []*ScopeResult 18} 19 20func (self *JsonReporter) depth() int { return len(self.currentKey) } 21 22func (self *JsonReporter) BeginStory(story *StoryReport) {} 23 24func (self *JsonReporter) Enter(scope *ScopeReport) { 25 self.currentKey = append(self.currentKey, scope.Title) 26 ID := strings.Join(self.currentKey, "|") 27 if _, found := self.index[ID]; !found { 28 next := newScopeResult(scope.Title, self.depth(), scope.File, scope.Line) 29 self.scopes = append(self.scopes, next) 30 self.index[ID] = next 31 } 32 self.current = self.index[ID] 33} 34 35func (self *JsonReporter) Report(report *AssertionResult) { 36 self.current.Assertions = append(self.current.Assertions, report) 37} 38 39func (self *JsonReporter) Exit() { 40 self.currentKey = self.currentKey[:len(self.currentKey)-1] 41} 42 43func (self *JsonReporter) EndStory() { 44 self.report() 45 self.reset() 46} 47func (self *JsonReporter) report() { 48 scopes := []string{} 49 for _, scope := range self.scopes { 50 serialized, err := json.Marshal(scope) 51 if err != nil { 52 self.out.Println(jsonMarshalFailure) 53 panic(err) 54 } 55 var buffer bytes.Buffer 56 json.Indent(&buffer, serialized, "", " ") 57 scopes = append(scopes, buffer.String()) 58 } 59 self.out.Print(fmt.Sprintf("%s\n%s,\n%s\n", OpenJson, strings.Join(scopes, ","), CloseJson)) 60} 61func (self *JsonReporter) reset() { 62 self.scopes = []*ScopeResult{} 63 self.index = map[string]*ScopeResult{} 64 self.currentKey = nil 65} 66 67func (self *JsonReporter) Write(content []byte) (written int, err error) { 68 self.current.Output += string(content) 69 return len(content), nil 70} 71 72func NewJsonReporter(out *Printer) *JsonReporter { 73 self := new(JsonReporter) 74 self.out = out 75 self.reset() 76 return self 77} 78 79const OpenJson = ">->->OPEN-JSON->->->" // "⌦" 80const CloseJson = "<-<-<-CLOSE-JSON<-<-<" // "⌫" 81const jsonMarshalFailure = ` 82 83GOCONVEY_JSON_MARSHALL_FAILURE: There was an error when attempting to convert test results to JSON. 84Please file a bug report and reference the code that caused this failure if possible. 85 86Here's the panic: 87 88` 89