We are entering into the actual project part

So now its time to do the actual application programming.

















The ascii diagram again.

                                 v <-- you are here (still)
                                                    (but now you are a gopher)
   +----------+    +----------+      +----------+    +----------+
   | cli opts | -> | project  | -+-> |  print   | -> | display  |
   +----------+    |  config  |  |   +----------+    +----------+
                   +----------+  |
                                 |   +----------+    +----------+
                                 +-> |   add    | -> |   save   |
                                 |   +----------+    +----------+
                                 |
                                 |   +----------+    +----------+
                                 +-> |    rm    | -> |   save   |
                                     +----------+    +----------+
















So lets create the file (pkg/projector/projector.go)

> pkg/projector/projector.go

GOPHER TIME

















Here is what the code could look like

package projector

import (
    "encoding/json"
    "os"
    "path"
)

type Lookup = map[string]map[string]string
type ProjectorData struct {
    Projector Lookup `json:"projector"`
}

type Projector struct {
    data   ProjectorData
    config *ProjectorConfig
}

func (p *Projector) GetValue(key string) (string, bool) {
    found := false
    out := ""

    curr := p.config.Pwd
    prev := ""

    for {

        if dir, prs := p.data.Projector[curr]; prs {
            if value, prs := dir[key]; prs {
                found = true
                out = value
                break
            }
        }

        if curr == prev {
            break
        }

        prev = curr
        curr = path.Dir(curr)
    }

    return out, found
}

func (p *Projector) SetValue(key string, value string) {
    pwd := p.config.Pwd
    if _, prs := p.data.Projector[pwd]; !prs {
        p.data.Projector[pwd] = map[string]string{}
    }

    p.data.Projector[pwd][key] = value
}

func (p *Projector) DeleteValue(key string) {
    pwd := p.config.Pwd
    if dir, prs := p.data.Projector[pwd]; prs {
        delete(dir, key)
    }
}

func defaultProjector(config *ProjectorConfig) *Projector {
    return &Projector{
        config: config,
        data:   ProjectorData{},
    }
}

func FromConfig(config *ProjectorConfig) (*Projector, error) {
    if _, err := os.Stat(config.Config); os.IsNotExist(err) {
        return defaultProjector(config), nil
    }

    bytes, err := os.ReadFile(config.Config)
    if err != nil {
        return defaultProjector(config), nil
    }

    var data ProjectorData
    err = json.Unmarshal(bytes, &data)
    if err != nil {
        return defaultProjector(config), nil
    }
    return &Projector{
        data,
        config,
    }, nil
}
















Did you skip leg day?

Lets test

















Your tests could look like

package projector_test

import (
    "testing"

    "github.com/theprimeagen/go-tem/pkg/projector"
)

func getData() *projector.ProjectorData {
    return &projector.ProjectorData{
        Projector: map[string]map[string]string{
            "/": {
                "bar": "buzz",
                "foo": "bar1",
            },
            "/foo": {
                "foo": "bar2",
            },
            "/foo/bar": {
                "foo": "bar3",
            },
            "/foo/bar/baz": {
                "foo": "bar4",
            },
        },
    }
}

func getConfig(pwd string) *projector.ProjectorConfig {
    return &projector.ProjectorConfig{
        Pwd: pwd,
        Config: "dnm",
        Operation: projector.Print,
        Arguments: []string{},
    }
}

func TestGetValue(t *testing.T) {
    p := projector.NewProjector(getConfig("/foo/bar"), getData())

    val, ok := p.GetValue("foo")
    if !ok {
        t.Error("couldn't find value")
    }

    if val != "bar3" {
        t.Errorf("expected bar3 but got %v", val)
    }

    _, ok = p.GetValue("bazbar")
    if ok {
        t.Error("expected to find no value")
    }


    val, ok = p.GetValue("bar")
    if !ok {
        t.Error("couldn't find value")
    }

    if val != "buzz" {
        t.Errorf("expected buzz but got %v", val)
    }
}

func TestSetValue(t *testing.T) {
    p := projector.NewProjector(getConfig("/foo/bar"), getData())
    p.SetValue("foo", "bar69")
    val, ok := p.GetValue("foo")

    if !ok {
        t.Error("couldn't find value")
    }

    if val != "bar69" {
        t.Errorf("expected bar69 but got %v", val)
    }
}

func TestRemoveValue(t *testing.T) {
    p := projector.NewProjector(getConfig("/foo/bar"), getData())
    p.DeleteValue("foo")
    val, ok := p.GetValue("foo")

    if !ok {
        t.Error("couldn't find value")
    }

    if val != "bar2" {
        t.Errorf("expected bar2 but got %v", val)
    }
}
















Crab people

Twitch