Skip to content

Latest commit

 

History

History
217 lines (169 loc) · 5.64 KB

CONTRIBUTING.md

File metadata and controls

217 lines (169 loc) · 5.64 KB

Contributing to PTerm

This document explains how to participate in the development of PTerm.
If your goal is to report a bug instead of programming PTerm, you can do so here.

Creating a new printer

In this chapter we will show you how to create a new printer.

TextPrinter Template

package pterm

type TemplatePrinter struct{
	// TODO: Add printer settings here
}

// Sprint formats using the default formats for its operands and returns the resulting string.
// Spaces are added between operands when neither is a string.
func (p TemplatePrinter) Sprint(a ...interface{}) string {
	panic("write printer code here")
}

// Sprintln formats using the default formats for its operands and returns the resulting string.
// Spaces are always added between operands and a newline is appended.
func (p TemplatePrinter) Sprintln(a ...interface{}) string {
	return Sprintln(p.Sprint(a...))
}

// Sprintf formats according to a format specifier and returns the resulting string.
func (p TemplatePrinter) Sprintf(format string, a ...interface{}) string {
	return p.Sprint(Sprintf(format, a...))
}

// Print formats using the default formats for its operands and writes to standard output.
// Spaces are added between operands when neither is a string.
// It returns the number of bytes written and any write error encountered.
func (p TemplatePrinter) Print(a ...interface{}) *TextPrinter {
	Print(p.Sprint(a...))
	tp := TextPrinter(p)
	return &tp
}

// Println formats using the default formats for its operands and writes to standard output.
// Spaces are always added between operands and a newline is appended.
// It returns the number of bytes written and any write error encountered.
func (p TemplatePrinter) Println(a ...interface{}) *TextPrinter {
	Println(p.Sprint(a...))
    tp := TextPrinter(p)
    return &tp
}

// Printf formats according to a format specifier and writes to standard output.
// It returns the number of bytes written and any write error encountered.
func (p TemplatePrinter) Printf(format string, a ...interface{}) *TextPrinter {
	Print(p.Sprintf(format, a...))
	tp := TextPrinter(p)
	return &tp
}

RenderablePrinter Template

package pterm

type TemplatePrinter struct{
	// TODO: Add printer settings here
}

// Srender renders the Template as a string.
func (p TemplatePrinter) Srender() (string, error) {
	var ret string

    return ret, nil
}

// Render prints the Template to the terminal.
func (p TemplatePrinter) Render() error {
	s, err := p.Srender()
    if err != nil {
        return err
    }
    Println(s)

    return nil
}

LivePrinter Template

// Start the TemplatePrinter.
package pterm
import "github.com/gemini/pterm"

type TemplatePrinter struct{

}


func (s TemplatePrinter) Start(text...interface{}) (*TemplatePrinter, error) { // TODO: Replace Template with actual printer.
	// TODO: start logic
	return &s, nil
}

// Stop terminates the TemplatePrinter immediately.
// The TemplatePrinter will not resolve into anything.
func (s *TemplatePrinter) Stop() error {
	// TODO: stop logic
    return nil
}

// GenericStart runs Start, but returns a LivePrinter.
// This is used for the interface LivePrinter.
// You most likely want to use Start instead of this in your program.
func (s *TemplatePrinter) GenericStart() (*LivePrinter, error) {
	_, err := s.Start()
	lp := LivePrinter(s)
	return &lp, err
}

// GenericStop runs Stop, but returns a LivePrinter.
// This is used for the interface LivePrinter.
// You most likely want to use Stop instead of this in your program.
func (s *TemplatePrinter) GenericStop() (*LivePrinter, error) {
	err := s.Stop()
	lp := LivePrinter(s)
	return &lp, err
}

Writing Tests

Each method of PTerm must be tested.

Required tests for every printer

Nil Check

This ensures that a printer without set values will not produce errors.

func TestTemplatePrinterNilPrint(t *testing.T) { // TODO: Replace "Template" with actual printer name.
	p := TemplatePrinter{} // TODO: Replace "Template" with actual printer name.
	p.Println("Hello, World!")
}

WithXxx() Methods

Each method, which starts with With can be tested by checking if it actually creates a new printer and sets the value.

Example from SectionPrinter:

func TestSectionPrinter_WithStyle(t *testing.T) {
	p := SectionPrinter{}
	s := NewStyle(FgRed, BgRed, Bold)
	p2 := p.WithStyle(s)

	assert.Equal(t, s, p2.Style)
	assert.Empty(t, p.Style)
}

func TestSectionPrinter_WithTopPadding(t *testing.T) {
	p := SectionPrinter{}
	p2 := p.WithTopPadding(1337)

	assert.Equal(t, 1337, p2.TopPadding)
	assert.Empty(t, p.TopPadding)
}

TextPrinter Tests Template

func TestTemplatePrinterPrintMethods(t *testing.T) { // TODO: Replace "Template" with actual printer name.
	p := DefaultTemplate // TODO: Replace "Template" with actual printer name.

	t.Run("Print", func(t *testing.T) {
		testPrintContains(t, func(w io.Writer, a interface{}) {
			p.Print(a)
		})
	})

	t.Run("Printf", func(t *testing.T) {
		testPrintfContains(t, func(w io.Writer, format string, a interface{}) {
			p.Printf(format, a)
		})
	})

	t.Run("Println", func(t *testing.T) {
		testPrintlnContains(t, func(w io.Writer, a interface{}) {
			p.Println(a)
		})
	})

	t.Run("Sprint", func(t *testing.T) {
		testSprintContains(t, func(a interface{}) string {
			return p.Sprint(a)
		})
	})

	t.Run("Sprintf", func(t *testing.T) {
		testSprintfContains(t, func(format string, a interface{}) string {
			return p.Sprintf(format, a)
		})
	})

	t.Run("Sprintln", func(t *testing.T) {
		testSprintlnContains(t, func(a interface{}) string {
			return p.Sprintln(a)
		})
	})
}