Skip to content

Commit

Permalink
Merge pull request #62 from yanosea/57-add-interactive-generating-com…
Browse files Browse the repository at this point in the history
…mand

✨feat: add interactive generating command and interactive options (#57)
  • Loading branch information
yanosea authored Oct 16, 2024
2 parents 12636e8 + fea02fc commit 7d0ba01
Show file tree
Hide file tree
Showing 45 changed files with 7,164 additions and 279 deletions.
29 changes: 29 additions & 0 deletions CREDITS
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,35 @@ SOFTWARE.

<http://www.opensource.org/licenses/mit-license.php>

================================================================

github.com/eiannone/keyboard
https://github.com/eiannone/keyboard
----------------------------------------------------------------
The MIT License (MIT)

Copyright (C) 2012 termbox-go authors
Copyright (c) 2015 Emanuele Iannone

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================================

github.com/fatih/color
Expand Down
31 changes: 17 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,25 @@ Usage:
jrp [command]
Available Subcommands:
download, dl, d 📦 Download WordNet Japan sqlite database file from the official web site.
generate, gen, g ✨ Generate Japanese random phrase(s). You can abbreviate "generate" sub command. ("jrp" and "jrp generate" are the same.)
history, hist, h 📜 Manage the history of the "generate" command.
favorite, fav, f ⭐ Manage the favorited phrase(s) of the history of "generate" command.
help 🤝 Help for jrp.
completion 🔧 Generate the autocompletion script for the specified shell.
version 🔖 Show the version of jrp.
download, dl, d 📦 Download WordNet Japan sqlite database file from the official web site.
generate, gen, g ✨ Generate Japanese random phrase(s).
history, hist, h 📜 Manage the history of the "generate" command.
favorite, fav, f ⭐ Manage the favorited phrase(s) of the history of "generate" command.
interactive, int, i 💬 Generate Japanese random phrase(s) interactively.
help 🤝 Help for jrp.
completion 🔧 Generate the autocompletion script for the specified shell.
version 🔖 Show the version of jrp.
Flags:
-n, --number 🔢 number of phrases to generate (default 1, e.g: 10)
-p --prefix 💬 prefix of phrase(s) to generate
-s --suffix 💬 suffix of phrase(s) to generate
-d --dry-run 🧪 generate phrase(s) without saving to the history
-P, --plain 📝 plain text output instead of table output
-h, --help 🤝 help for jrp
-v, --version 🔖 version for jrp
-n, --number 🔢 number of phrases to generate (default 1, e.g: 10)
-p --prefix 💬 prefix of phrase(s) to generate
-s --suffix 💬 suffix of phrase(s) to generate
-d --dry-run 🧪 generate phrase(s) without saving to the history
-P, --plain 📝 plain text output instead of table output
-i, --interactive 💬 generate Japanese random phrase(s) interactively
-t, --timeout ⏱️ timeout in seconds for the interactive mode (default 30, e.g: 10)
-h, --help 🤝 help for jrp
-v, --version 🔖 version for jrp
Arguments:
number 🔢 number of phrases to generate (e.g: 10)
Expand Down
40 changes: 36 additions & 4 deletions app/library/jrpwriter/jrpwriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
type JrpWritable interface {
WriteGenerateResultAsTable(writer ioproxy.WriterInstanceInterface, jrps []*model.Jrp, showID bool)
WriteAsTable(writer ioproxy.WriterInstanceInterface, jrps []*model.Jrp)
WriteInteractiveResultAsTable(writer ioproxy.WriterInstanceInterface, jrps []*model.Jrp)
}

// JrpWriter is a struct that implements JrpWritable.
Expand Down Expand Up @@ -62,7 +63,7 @@ func (j *JrpWriter) WriteGenerateResultAsTable(writer ioproxy.WriterInstanceInte
return row
}

j.writeTable(writer, jrps, headers, rowFunc)
j.writeTable(writer, jrps, headers, rowFunc, true)
}

// WriteAsTable writes the jrps as table.
Expand Down Expand Up @@ -96,11 +97,40 @@ func (j *JrpWriter) WriteAsTable(writer ioproxy.WriterInstanceInterface, jrps []
}
}

j.writeTable(writer, jrps, headers, rowFunc)
j.writeTable(writer, jrps, headers, rowFunc, true)
}

// WriteInteractiveResultAsTable writes the interactive result as table.
func (j *JrpWriter) WriteInteractiveResultAsTable(writer ioproxy.WriterInstanceInterface, jrps []*model.Jrp) {
if jrps == nil || len(jrps) <= 0 {
return
}

headers := []string{"phrase", "prefix", "suffix", "created_at"}

rowFunc := func(jrp *model.Jrp) []string {
prefix := ""
if jrp.Prefix.FieldNullString.Valid {
prefix = jrp.Prefix.FieldNullString.String
}
suffix := ""
if jrp.Suffix.FieldNullString.Valid {
suffix = jrp.Suffix.FieldNullString.String
}
row := []string{
jrp.Phrase,
prefix,
suffix,
jrp.CreatedAt.Format("2006-01-02 15:04:05"),
}
return row
}

j.writeTable(writer, jrps, headers, rowFunc, false)
}

// writeTable writes the table.
func (j *JrpWriter) writeTable(writer ioproxy.WriterInstanceInterface, jrps []*model.Jrp, headers []string, rowFunc func(*model.Jrp) []string) {
func (j *JrpWriter) writeTable(writer ioproxy.WriterInstanceInterface, jrps []*model.Jrp, headers []string, rowFunc func(*model.Jrp) []string, showTotal bool) {
if jrps == nil || len(jrps) <= 0 {
return
}
Expand All @@ -111,7 +141,9 @@ func (j *JrpWriter) writeTable(writer ioproxy.WriterInstanceInterface, jrps []*m
}
total := j.StrconvProxy.Itoa(len(rows))
rows = append(rows, make([]string, len(headers)))
rows = append(rows, append([]string{"TOTAL : " + total}, make([]string, len(headers)-1)...))
if showTotal {
rows = append(rows, append([]string{"TOTAL : " + total}, make([]string, len(headers)-1)...))
}

table := j.getDefaultTableWriter(writer)
table.SetHeader(headers)
Expand Down
192 changes: 181 additions & 11 deletions app/library/jrpwriter/jrpwriter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,10 +343,141 @@ func TestJrpWriter_WriteAsTable(t *testing.T) {
t.Errorf("Capturer.CaptureOutput() : error =\n%v, wantErr =\n%v", err, tt.wantErr)
}
if stdout != tt.wantStdOut {
t.Errorf("JrpWriter.WriteJrpAsTable() : stdout =\n%v, wantStdOut =\n%v", stdout, tt.wantStdOut)
t.Errorf("JrpWriter.WriteAsTable() : stdout =\n%v, wantStdOut =\n%v", stdout, tt.wantStdOut)
}
if stderr != tt.wantStdErr {
t.Errorf("JrpWriter.WriteJrpAsTable() : stderr =\n%v, wantStdErr =\n%v", stderr, tt.wantStdErr)
t.Errorf("JrpWriter.WriteAsTable() : stderr =\n%v, wantStdErr =\n%v", stderr, tt.wantStdErr)
}
})
}
}

func TestJrpWriter_WriteInteractiveResultAsTable(t *testing.T) {
capturer := testutility.NewCapturer(
bufferproxy.New(),
bufferproxy.New(),
osproxy.New(),
)
jrpWriter := New(
strconvproxy.New(),
tablewriterproxy.New(),
)
sqlProxy := sqlproxy.New()
timeProxy := timeproxy.New()

type fields struct {
t *testing.T
fnc func()
capturer *testutility.Capturer
}
tests := []struct {
name string
fields fields
wantStdOut string
wantStdErr string
wantErr bool
}{
{
name: "positive testing (jrps are nil)",
fields: fields{
t: t,
fnc: func() {
jrpWriter.WriteInteractiveResultAsTable(osproxy.Stdout, nil)
},
capturer: capturer,
},
wantStdOut: "",
wantStdErr: "",
wantErr: false,
},
{
name: "positive testing (jrps are empty)",
fields: fields{
t: t,
fnc: func() {
jrpWriter.WriteInteractiveResultAsTable(osproxy.Stdout, []*model.Jrp{})
},
capturer: capturer,
},
wantStdOut: "",
wantStdErr: "",
wantErr: false,
},
{
name: "positive testing (jrps are one)",
fields: fields{
t: t,
fnc: func() {
jrps := []*model.Jrp{
{
ID: 1,
Phrase: "test",
Prefix: sqlProxy.StringToNullString("prefix"),
Suffix: sqlProxy.StringToNullString("suffix"),
IsFavorited: 0,
CreatedAt: timeProxy.Date(9999, 12, 31, 0, 0, 0, 0, &timeproxy.UTC),
UpdatedAt: timeProxy.Date(9999, 12, 31, 0, 0, 0, 0, &timeproxy.UTC),
},
}
jrpWriter.WriteInteractiveResultAsTable(osproxy.Stdout, jrps)
},
capturer: capturer,
},
wantStdOut: "PHRASE\tPREFIX\tSUFFIX\tCREATED AT\ntest\tprefix\tsuffix\t9999-12-31 00:00:00\n\t\t\t\t\n",
wantStdErr: "",
},
{
name: "positive testing (jrps are two)",
fields: fields{
t: t,
fnc: func() {
jrps := []*model.Jrp{
{
ID: 1,
Phrase: "test1",
Prefix: sqlProxy.StringToNullString("prefix1"),
Suffix: sqlProxy.StringToNullString("suffix1"),
IsFavorited: 0,
CreatedAt: timeProxy.Date(9999, 12, 31, 0, 0, 0, 0, &timeproxy.UTC),
UpdatedAt: timeProxy.Date(9999, 12, 31, 0, 0, 0, 0, &timeproxy.UTC),
},
{
ID: 1,
Phrase: "test2",
Prefix: sqlProxy.StringToNullString("prefix2"),
Suffix: sqlProxy.StringToNullString("suffix2"),
IsFavorited: 1,
CreatedAt: timeProxy.Date(9999, 12, 31, 0, 0, 0, 0, &timeproxy.UTC),
UpdatedAt: timeProxy.Date(9999, 12, 31, 0, 0, 0, 0, &timeproxy.UTC),
},
}
jrpWriter.WriteInteractiveResultAsTable(osproxy.Stdout, jrps)
},
capturer: capturer,
},
wantStdOut: "PHRASE\tPREFIX\tSUFFIX\tCREATED AT\ntest1\tprefix1\tsuffix1\t9999-12-31 00:00:00\n\ttest2\tprefix2\tsuffix2\t9999-12-31 00:00:00\n\t\t\t\t\n",
wantStdErr: "",
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
stdout, stderr, err := tt.fields.capturer.CaptureOutput(
tt.fields.t,
tt.fields.fnc,
)
stdout = testutility.RemoveTabAndSpaceAndLf(stdout)
stderr = testutility.RemoveTabAndSpaceAndLf(stderr)
tt.wantStdOut = testutility.RemoveTabAndSpaceAndLf(tt.wantStdOut)
tt.wantStdErr = testutility.RemoveTabAndSpaceAndLf(tt.wantStdErr)
if (err != nil) != tt.wantErr {
t.Errorf("Capturer.CaptureOutput() : error =\n%v, wantErr =\n%v", err, tt.wantErr)
}
if stdout != tt.wantStdOut {
t.Errorf("JrpWriter.WriteInteractiveResultAsTable() : stdout =\n%v, wantStdOut =\n%v", stdout, tt.wantStdOut)
}
if stderr != tt.wantStdErr {
t.Errorf("JrpWriter.WriteInteractiveResultAsTable() : stderr =\n%v, wantStdErr =\n%v", stderr, tt.wantStdErr)
}
})
}
Expand Down Expand Up @@ -386,27 +517,29 @@ func TestJrpWriter_writeTable(t *testing.T) {
fields: fields{
t: t,
fnc: func() {
jrpWriter.writeTable(osproxy.Stdout, nil, headers, rowFunc)
jrpWriter.writeTable(osproxy.Stdout, nil, headers, rowFunc, false)
},
capturer: capturer,
},
wantStdOut: "",
wantStdErr: "",
wantErr: false,
}, {
},
{
name: "positive testing (jrps are empty)",
fields: fields{
t: t,
fnc: func() {
jrpWriter.writeTable(osproxy.Stdout, []*model.Jrp{}, headers, rowFunc)
jrpWriter.writeTable(osproxy.Stdout, []*model.Jrp{}, headers, rowFunc, false)
},
capturer: capturer,
},
wantStdOut: "",
wantStdErr: "",
wantErr: false,
}, {
name: "positive testing (jrps are one)",
},
{
name: "positive testing (jrps are one, show total)",
fields: fields{
t: t,
fnc: func() {
Expand All @@ -415,14 +548,15 @@ func TestJrpWriter_writeTable(t *testing.T) {
Phrase: "test",
},
}
jrpWriter.writeTable(osproxy.Stdout, jrps, headers, rowFunc)
jrpWriter.writeTable(osproxy.Stdout, jrps, headers, rowFunc, true)
},
capturer: capturer,
},
wantStdOut: "PHRASE\ntest\n\t\nTOTAL : 1\n",
wantStdErr: "",
}, {
name: "positive testing (jrps are two)",
},
{
name: "positive testing (jrps are two, show total)",
fields: fields{
t: t,
fnc: func() {
Expand All @@ -433,14 +567,50 @@ func TestJrpWriter_writeTable(t *testing.T) {
Phrase: "test2",
},
}
jrpWriter.writeTable(osproxy.Stdout, jrps, headers, rowFunc)
jrpWriter.writeTable(osproxy.Stdout, jrps, headers, rowFunc, true)
},
capturer: capturer,
},
wantStdOut: "PHRASE\ntest1\ntest2\n\t\nTOTAL : 2\n",
wantStdErr: "",
wantErr: false,
},
{
name: "positive testing (jrps are one, do not show total)",
fields: fields{
t: t,
fnc: func() {
jrps := []*model.Jrp{
{
Phrase: "test",
},
}
jrpWriter.writeTable(osproxy.Stdout, jrps, headers, rowFunc, false)
},
capturer: capturer,
},
wantStdOut: "PHRASE\ntest\n",
wantStdErr: "",
}, {
name: "positive testing (jrps are two, do not show total)",
fields: fields{
t: t,
fnc: func() {
jrps := []*model.Jrp{
{
Phrase: "test1",
}, {
Phrase: "test2",
},
}
jrpWriter.writeTable(osproxy.Stdout, jrps, headers, rowFunc, false)
},
capturer: capturer,
},
wantStdOut: "PHRASE\ntest1\ntest2\n",
wantStdErr: "",
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
Loading

0 comments on commit 7d0ba01

Please sign in to comment.