func TestBranchRender2(t *testing.T) { cb := ctests.New(t).SetApp(true, true, false) defer cb.Finish() b := NewBranchView(cb.Ctx(), models.NewBranchModel(cb.Ctx(), &models.RootContents{Name: "a"})) expected := elem.Div( prop.Class("node"), NewBranchControlView(cb.Ctx(), models.NewBranchModel(cb.Ctx(), nil)), elem.Div( prop.Class("children"), ), ) equal(t, expected, b.Render()) }
func TestBranchNotifySelectFileClick(t *testing.T) { cb := ctests.New(t).SetApp(true, false, false) defer cb.Finish() setupForSuccessfulFileLoad(t, cb) m := models.NewBranchModel(cb.Ctx(), &models.AsyncContents{FileContents: models.FileContents{NodeContents: models.NodeContents{Name: "a"}, Filename: "b"}}) b := NewBranchView(cb.Ctx(), m) cb.ExpectDispatched( &actions.LoadFileSent{Branch: b.model}, &actions.LoadFileSuccess{Branch: b.model}, &actions.BranchOpening{Branch: b.model}, &actions.BranchSelected{Branch: b.model, Loaded: true}, ) done := cb.GetApp().Notifier.NotifyWithData( b.model, stores.BranchSelecting, &stores.BranchSelectOperationData{Op: models.BranchOpClickToggle}, ) <-done cb.AssertAppSuccess() }
func TestBranchControlView_Render(t *testing.T) { cb := ctests.New(t).SetApp(true, false, false) defer cb.Finish() b := NewBranchControlView(cb.Ctx(), models.NewBranchModel(cb.Ctx(), &models.RootContents{Name: "a"})) expected := elem.Div( elem.Anchor( vecty.ClassMap{ "toggle": true, "empty": true, }, event.Click(nil), ), elem.Div( vecty.ClassMap{ "node-content": true, }, elem.Span( prop.Class("node-label"), event.Click(nil), vecty.Text("a"), ), elem.Span( prop.Class("badge"), vecty.Style("display", "none"), ), ), ) equal(t, expected, b.Render()) cb.AssertAppSuccess() }
func (s *BranchStore) NewNodeBranchModel(ctx context.Context, n *node.Node, name string) *models.BranchModel { b := models.NewBranchModel(ctx, &models.NodeContents{ Node: n, Name: name, }) s.AppendNodeBranchModelChildren(b, n) s.nodeBranches[n] = b return b }
func TestBranchView_Unmount(t *testing.T) { cb := ctests.New(t).SetApp(true, true, false) defer cb.Finish() b := NewBranchView(cb.Ctx(), models.NewBranchModel(cb.Ctx(), &models.RootContents{Name: "a"})) c := mock_vecty.NewMockComponent(cb.GetMock()) c.EXPECT().Unmount() b.Body = c b.Unmount() assert.Nil(t, b.Notifs) }
func TestBranchNotifyOpen(t *testing.T) { cb := ctests.New(t).SetApp(true, false, false) defer cb.Finish() b := NewBranchView(cb.Ctx(), models.NewBranchModel(cb.Ctx(), &models.RootContents{Name: "a"})) cb.GetConnection().EXPECT().Go(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(0) cb.ExpectDispatched(&actions.BranchOpened{Branch: b.model, Loaded: false}) done := cb.GetApp().Notifier.Notify(b.model, stores.BranchOpening) <-done cb.AssertAppSuccess() }
func testBranchReconcile(t *testing.T, notif flux.Notif) { cb := ctests.New(t).SetApp(true, false, false) defer cb.Finish() b := NewBranchView(cb.Ctx(), models.NewBranchModel(cb.Ctx(), &models.RootContents{Name: "a"})) cb.ExpectReconcile(&b.Composite) cb.ExpectNoneDispatched() done := cb.GetApp().Notifier.Notify(b.model, notif) <-done cb.AssertAppSuccess() }
func TestBranchNotifyOpenFile(t *testing.T) { cb := ctests.New(t).SetApp(true, false, false) defer cb.Finish() setupForSuccessfulFileLoad(t, cb) b := NewBranchView(cb.Ctx(), models.NewBranchModel(cb.Ctx(), &models.AsyncContents{FileContents: models.FileContents{NodeContents: models.NodeContents{Name: "a"}, Filename: "b"}})) cb.ExpectDispatched( &actions.LoadFileSent{Branch: b.model}, &actions.LoadFileSuccess{Branch: b.model}, &actions.BranchOpened{Branch: b.model, Loaded: true}, ) done := cb.GetApp().Notifier.Notify(b.model, stores.BranchOpening) <-done cb.AssertAppSuccess() }
func TestBranchNotifySelect(t *testing.T) { cb := ctests.New(t).SetApp(true, false, false) defer cb.Finish() b := NewBranchView(cb.Ctx(), models.NewBranchModel(cb.Ctx(), &models.RootContents{Name: "a"})) cb.ExpectDispatched( &actions.BranchSelected{Branch: b.model, Loaded: false}, ) done := cb.GetApp().Notifier.NotifyWithData( b.model, stores.BranchSelecting, &stores.BranchSelectOperationData{Op: models.BranchOpClickLabel}, ) <-done cb.AssertAppSuccess() }
func (s *BranchStore) Handle(payload *flux.Payload) bool { previous := s.selected switch action := payload.Action.(type) { case *actions.ChangeView: s.view = action.View s.selected = s.Root() payload.Notify(nil, ViewChanged) case *actions.Add: payload.Wait(s.app.Nodes) switch action.Direction() { case actions.New, actions.Redo: child, parent, err := mutateAppendBranch(s, action.Parent, action.Node, action.BranchName, action.BranchFile) if err != nil { s.app.Fail <- kerr.Wrap("LDBMBRHWHB", err) break } if child != nil { if ancestor := child.EnsureVisible(); ancestor != nil { payload.NotifyWithData(ancestor, BranchOpened, &BranchDescendantSelectData{ Branch: child, Op: models.BranchOpChildAdded, }) } s.selected = child payload.Notify(previous, BranchUnselectControl) payload.Notify(s.selected, BranchSelectControl) payload.Notify(s.selected, BranchSelected) } if parent != nil { payload.Notify(parent, BranchChildAdded) } case actions.Undo: _, parent, err := mutateDeleteBranch(s, action.Node) if err != nil { s.app.Fail <- kerr.Wrap("NLFWVSNNTY", err) break } if parent != nil { payload.Notify(parent, BranchChildDeleted) s.selected = parent payload.Notify(previous, BranchUnselectControl) payload.Notify(s.selected, BranchSelectControl) payload.Notify(s.selected, BranchSelected) } } case *actions.Delete: payload.Wait(s.app.Nodes) switch action.Direction() { case actions.New, actions.Redo: branch, parent, err := mutateDeleteBranch(s, action.Node) if err != nil { s.app.Fail <- kerr.Wrap("QTXPXAKXHH", err) break } if branch != nil { action.BranchIndex = branch.Index if nci, ok := branch.Contents.(models.NodeContentsInterface); ok { action.BranchName = nci.GetName() } if fci, ok := branch.Contents.(models.FileContentsInterface); ok { action.BranchFile = fci.GetFilename() } } if parent != nil { payload.Notify(parent, BranchChildDeleted) s.selected = parent payload.Notify(previous, BranchUnselectControl) payload.Notify(s.selected, BranchSelectControl) payload.Notify(s.selected, BranchSelected) } case actions.Undo: child, parent, err := mutateInsertBranch(s, action.Parent, action.Node, action.BranchIndex, action.BranchName, action.BranchFile) if err != nil { s.app.Fail <- kerr.Wrap("OOGOEWKPIL", err) break } if child != nil { if ancestor := child.EnsureVisible(); ancestor != nil { payload.NotifyWithData(ancestor, BranchOpened, &BranchDescendantSelectData{ Branch: child, Op: models.BranchOpChildAdded, }) } s.selected = child payload.Notify(previous, BranchUnselectControl) payload.Notify(s.selected, BranchSelectControl) payload.Notify(s.selected, BranchSelected) } if parent != nil { payload.Notify(parent, BranchChildAdded) } } case *actions.Reorder: payload.Wait(s.app.Nodes) parent, err := mutateReorderBranch(s, action.Model.Node) if err != nil { s.app.Fail <- kerr.Wrap("NUQOPWWXHA", err) break } if parent != nil { payload.Notify(parent, BranchChildrenReordered) } case *actions.BranchClose: if !action.Branch.CanOpen() { // branch can't open - ignore break } action.Branch.RecursiveClose() payload.Notify(action.Branch, BranchClose) case *actions.BranchOpening: if !action.Branch.CanOpen() { // branch can't open - ignore break } // The branch may not be loaded, so we don't open the branch until the BranchOpenPostLoad // action is received. This will happen immediately if the branch is loaded or not async. payload.Notify(action.Branch, BranchOpening) case *actions.BranchOpened: if !action.Branch.CanOpen() { // branch can't open - ignore break } action.Branch.Open = true payload.Notify(action.Branch, BranchOpened) case *actions.BranchSelecting: if ancestor := action.Branch.EnsureVisible(); ancestor != nil { payload.NotifyWithData(ancestor, BranchOpened, &BranchDescendantSelectData{ Branch: action.Branch, Op: action.Op, }) break } s.selected = action.Branch payload.Notify(previous, BranchUnselectControl) payload.Notify(s.selected, BranchSelectControl) if action.Op == models.BranchOpKeyboard { go func() { <-time.After(common.EditorKeyboardDebounceShort) if s.selected == action.Branch { payload.NotifyWithData( s.selected, BranchSelecting, &BranchSelectOperationData{Op: action.Op}, ) } }() } else { payload.NotifyWithData( s.selected, BranchSelecting, &BranchSelectOperationData{Op: action.Op}, ) } case *actions.BranchSelected: payload.Wait(s.app.Nodes) payload.Notify(s.selected, BranchSelected) case *actions.InitialState: payload.Wait(s.app.Package, s.app.Types, s.app.Data, s.app.Env) s.pkg = s.NewFileBranchModel(s.ctx, s.app.Package.Node(), "package", s.app.Package.Filename()) s.pkg.Root = true s.pkg.Open = true s.types = models.NewBranchModel(s.ctx, &models.TypesContents{}) s.types.Root = true s.types.Open = true for _, name := range s.app.Types.Names() { t := s.app.Types.Get(name) typeBranch := s.NewFileBranchModel(s.ctx, t.Node, name, t.File) s.types.Append(typeBranch) } s.data = models.NewBranchModel(s.ctx, &models.DataContents{}) s.data.Root = true s.data.Open = true for _, name := range s.app.Data.Names() { s.data.Append(models.NewBranchModel(s.ctx, &models.AsyncContents{ FileContents: models.FileContents{ NodeContents: models.NodeContents{ Name: name, }, Filename: s.app.Data.Get(name).File, }, })) } s.selected = s.data payload.Notify(nil, BranchInitialStateLoaded) case *actions.LoadFileSuccess: ni, ok := action.Branch.Contents.(models.NodeContentsInterface) if !ok { break } n := ni.GetNode() s.AppendNodeBranchModelChildren(action.Branch, n) s.nodeBranches[n] = action.Branch payload.Notify(action.Branch, BranchLoaded) } return true }