<commit_before>// Copyright 2014 by caixw, All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

package conv

import (
	"reflect"
	"testing"

	"github.com/issue9/assert"
)

func TestValue(t *testing.T) {
	a := assert.New(t)

	s1 := int(5)
	t1 := int8(7)
	a.NotError(Value(s1, reflect.ValueOf(&t1)))
	a.Equal(s1, t1)

	s2 := "abc"
	t2 := "def"
	a.NotError(Value(s2, reflect.ValueOf(&t2)))
	a.Equal(s2, t2)

	s3 := "abc"
	t3 := []byte("def")
	a.NotError(Value(s3, reflect.ValueOf(&t3)))
	a.Equal(s3, string(t3))

	s4 := []byte("abc")
	t4 := "def"
	a.NotError(Value(s4, reflect.ValueOf(&t4)))
	a.Equal(s4, []byte(t4))

	s5 := "on"
	t5 := false
	a.NotError(Value(s5, reflect.ValueOf(&t5)))
	a.Equal(true, t5)

	s6 := "123"
	t6 := 456
	a.NotError(Value(s6, reflect.ValueOf(&t6)))
	a.Equal(123, t6)

	s7 := float64(0)
	t7 := int64(1)
	a.NotError(Value(s7, reflect.ValueOf(&t7)))
	a.Equal(int64(0), t7)

	s8 := byte('1')
	t8 := byte('2')
	a.NotError(Value(s8, reflect.ValueOf(&t8)))
	a.Equal(byte('1'), t8)

	s9 := byte('1')
	t9 := int('2')
	a.NotError(Value(s9, reflect.ValueOf(&t9)))
	a.Equal(49, t9)

	var s10 interface{}
	s10 = '1'
	t10 := int('2')
	a.NotError(Value(s10, reflect.ValueOf(&t10)))
	a.Equal(49, t10)

	t11 := int('2')
	a.NotError(Value(nil, reflect.ValueOf(&t11)))
	a.Equal(0, t11)

	// 无法转换的
	s20 := "1a23"
	t20 := 444
	a.Error(Value(s20, reflect.ValueOf(&t20)))
}
<commit_msg>添加测试内容<commit_after>// Copyright 2014 by caixw, All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

package conv

import (
	"reflect"
	"testing"

	"github.com/issue9/assert"
)

func TestValue(t *testing.T) {
	a := assert.New(t)

	s1 := int(5)
	t1 := int8(7)
	a.NotError(Value(s1, reflect.ValueOf(&t1)))
	a.Equal(s1, t1)

	s2 := "abc"
	t2 := "def"
	a.NotError(Value(s2, reflect.ValueOf(&t2)))
	a.Equal(s2, t2)

	s3 := "abc"
	t3 := []byte("def")
	a.NotError(Value(s3, reflect.ValueOf(&t3)))
	a.Equal(s3, string(t3))

	s4 := []byte("abc")
	t4 := "def"
	a.NotError(Value(s4, reflect.ValueOf(&t4)))
	a.Equal(s4, []byte(t4))

	s5 := "on"
	t5 := false
	a.NotError(Value(s5, reflect.ValueOf(&t5)))
	a.Equal(true, t5)

	s6 := "123"
	t6 := 456
	a.NotError(Value(s6, reflect.ValueOf(&t6)))
	a.Equal(123, t6)

	s7 := float64(0)
	t7 := int64(1)
	a.NotError(Value(s7, reflect.ValueOf(&t7)))
	a.Equal(int64(0), t7)

	s8 := byte('1')
	t8 := byte('2')
	a.NotError(Value(s8, reflect.ValueOf(&t8)))
	a.Equal(byte('1'), t8)

	s9 := byte('1')
	t9 := int('2')
	a.NotError(Value(s9, reflect.ValueOf(&t9)))
	a.Equal(49, t9)

	var s10 interface{}
	s10 = '1'
	t10 := int('2')
	a.NotError(Value(s10, reflect.ValueOf(&t10)))
	a.Equal(49, t10)

	t11 := int('2')
	a.NotError(Value(nil, reflect.ValueOf(&t11)))
	a.Equal(0, t11)

	t12 := "22"
	a.NotError(Value(nil, reflect.ValueOf(&t12)))
	a.Equal("", t12)

	// 无法转换的
	s20 := "1a23"
	t20 := 444
	a.Error(Value(s20, reflect.ValueOf(&t20)))
}
<|endoftext|>


<commit_before>package cryptopals

import (
	"encoding/hex"
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestC1(t *testing.T) {
	a := assert.New(t)

	hStr := "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d"

	expected := "SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t"
	actual := HexStringToBase64String(hStr)
	a.Equal(actual, expected)
}

func TestC2(t *testing.T) {
	a := assert.New(t)

	in1 := "1c0111001f010100061a024b53535009181c"
	in2 := "686974207468652062756c6c277320657965"
	expected := "746865206b696420646f6e277420706c6179"

	bIn1, err := hex.DecodeString(in1)
	a.NoError(err)

	bIn2, err := hex.DecodeString(in2)
	a.NoError(err)

	bOut := Xor(bIn1, bIn2)
	actual := hex.EncodeToString(bOut)
	a.Equal(expected, actual)
}
<commit_msg>s1c5: add solution<commit_after>package cryptopals

import (
	"encoding/hex"
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestC1(t *testing.T) {
	a := assert.New(t)

	hStr := "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d"

	expected := "SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t"
	actual := HexStringToBase64String(hStr)
	a.Equal(actual, expected)
}

func TestC2(t *testing.T) {
	a := assert.New(t)

	in1 := "1c0111001f010100061a024b53535009181c"
	in2 := "686974207468652062756c6c277320657965"
	expected := "746865206b696420646f6e277420706c6179"

	bIn1, err := hex.DecodeString(in1)
	a.NoError(err)

	bIn2, err := hex.DecodeString(in2)
	a.NoError(err)

	bOut := Xor(bIn1, bIn2)
	actual := hex.EncodeToString(bOut)
	a.Equal(expected, actual)
}

func TestC5(t *testing.T) {
	a := assert.New(t)

	in1 := `Burning 'em, if you ain't quick and nimble
I go crazy when I hear a cymbal`
	in2 := "ICE"

	expected := `0b3637272a2b2e63622c2e69692a23693a2a3c6324202d623d63343c2a26226324272765272a282b2f20430a652e2c652a3124333a653e2b2027630c692b20283165286326302e27282f`

	actualBytes := Xor([]byte(in1), []byte(in2))
	actualStr := hex.EncodeToString(actualBytes)
	a.Equal(expected, actualStr)
}
<|endoftext|>


<commit_before>// Copyright 2014-2015 The project AUTHORS. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package src

import (
	"errors"
	"fmt"
	"io"
	"os"
	"reflect"
	"strings"
)

func Decode(r io.Reader) (*Project, error) {
	dec := newDecoder(r)
	return dec.decode()
}

func DecodeFile(path string) (*Project, error) {
	f, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	return Decode(f)
}

type decoder struct {
	scan *scanner
	buf  []byte
	err  error
	prj  *Project
}

func newDecoder(r io.Reader) *decoder {
	return &decoder{scan: newScanner(r), prj: &Project{}}
}

// TODO: implement
func (dec *decoder) decode() (*Project, error) {
	if _, tok, err := dec.scan.nextValue(); err != nil {
		return nil, dec.errorf(err)
	} else if tok != scanBeginObject {
		return nil, dec.errorf("expected '{' as first character")
	}

	if err := dec.decodeProject(); err != nil {
		return nil, dec.errorf(err)
	}

	if _, tok, err := dec.scan.nextValue(); err != nil {
		return nil, dec.errorf(err)
	} else if tok != scanEndObject {
		return nil, dec.errorf("expected '}' as last character")
	}

	return dec.prj, nil
}

func (dec *decoder) errorf(v interface{}) error {
	return fmt.Errorf("malformed json: %v", v)
}

func (dec *decoder) decodeProject() error {
	pv := reflect.ValueOf(dec.prj)

	for {
		key, err := dec.scan.nextKey()
		if err != nil {
			if err == io.EOF {
				break
			}
			return err
		}
		if key == "" {
			return errors.New("empty key")
		}

		val, tok, err := dec.scan.nextValue()
		if err != nil {
			return err
		}

		switch {
		case key == "packages":
			err = dec.decodePackages()
		case key == "languages":
			err = dec.decodeLanguages()
		case key == "repository":
			err = dec.decodeRepository()
		case tok == scanIntLit:
			var num int64
			num, err := dec.unmarshalInt(val)
			if err != nil {
				return err
			}
			f := pv.FieldByName(dec.tagToFieldName(key))
			f.SetInt(num)
		case tok == scanStringLit:
			var str string
			str, err := dec.unmarshalString(val)
			if err != nil {
				return err
			}
			f := pv.FieldByName(dec.tagToFieldName(key))
			f.SetString(str)
		default:
			return errors.New("unexpected value for project object")
		}

		if err != nil {
			return err
		}
	}
	return nil
}

// TODO: implement
func (dec *decoder) decodePackages() error {
	return nil
}

// TODO: implement
func (dec *decoder) decodePackage() error {
	return nil
}

// TODO: implement
func (dec *decoder) decodeLanguages() error {
	return nil
}

// TODO: implement
func (dec *decoder) decodeLanguage() error {
	return nil
}

// TODO: implement
func (dec *decoder) decodeRepository() error {
	return nil
}

// TODO: implement
func (dec *decoder) unmarshalInt(data []byte) (int64, error) {
	return 0, nil
}

// TODO: implement
func (dec *decoder) unmarshalString(data []byte) (string, error) {
	return "", nil
}

// TODO: implement
func (dec *decoder) tagToFieldName(tag string) string {
	var field string
	for _, seg := range strings.Split(tag, "_") {
		if len(seg) == 0 {
			return ""
		}
		field += strings.ToUpper(string(seg[0]))
		if len(seg) > 1 {
			field += seg[1:]
		}
	}
	return field
}
<commit_msg>src: partial packages decoding<commit_after>// Copyright 2014-2015 The project AUTHORS. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package src

import (
	"errors"
	"fmt"
	"io"
	"os"
	"reflect"
	"strings"
)

func Decode(r io.Reader) (*Project, error) {
	dec := newDecoder(r)
	return dec.decode()
}

func DecodeFile(path string) (*Project, error) {
	f, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	return Decode(f)
}

type decoder struct {
	scan *scanner
	buf  []byte
	err  error
	prj  *Project
}

func newDecoder(r io.Reader) *decoder {
	return &decoder{scan: newScanner(r), prj: &Project{}}
}

// TODO: implement
func (dec *decoder) decode() (*Project, error) {
	if _, tok, err := dec.scan.nextValue(); err != nil {
		return nil, dec.errorf(err)
	} else if tok != scanBeginObject {
		return nil, dec.errorf("expected '{' as first character")
	}

	if err := dec.decodeProject(); err != nil {
		return nil, dec.errorf(err)
	}

	if _, tok, err := dec.scan.nextValue(); err != nil {
		return nil, dec.errorf(err)
	} else if tok != scanEndObject {
		return nil, dec.errorf("expected '}' as last character")
	}

	return dec.prj, nil
}

func (dec *decoder) errorf(v interface{}) error {
	return fmt.Errorf("malformed json: %v", v)
}

func (dec *decoder) decodeProject() error {
	pv := reflect.ValueOf(dec.prj)

	for {
		key, err := dec.scan.nextKey()
		if err != nil {
			if err == io.EOF {
				break
			}
			return err
		}
		if key == "" {
			return errors.New("empty key")
		}

		val, tok, err := dec.scan.nextValue()
		if err != nil {
			return err
		}

		switch {
		case key == "packages":
			err = dec.decodePackages()
		case key == "languages":
			err = dec.decodeLanguages()
		case key == "repository":
			err = dec.decodeRepository()
		case tok == scanIntLit:
			var num int64
			num, err := dec.unmarshalInt(val)
			if err != nil {
				return err
			}
			f := pv.FieldByName(dec.tagToFieldName(key))
			f.SetInt(num)
		case tok == scanStringLit:
			var str string
			str, err := dec.unmarshalString(val)
			if err != nil {
				return err
			}
			f := pv.FieldByName(dec.tagToFieldName(key))
			f.SetString(str)
		default:
			return errors.New("unexpected value for project object")
		}

		if err != nil {
			return err
		}
	}
	return nil
}

func (dec *decoder) decodePackages() error {
	dec.prj.Packages = make([]*Package, 0)
	for {
		_, tok, err := dec.scan.nextValue()
		if err != nil {
			return err
		}
		if tok == scanEndArray {
			break
		}
		if tok != scanBeginObject {
			return errors.New("expected an object")
		}
		if err := dec.decodePackage(); err != nil {
			return err
		}
	}

	return nil
}

// TODO: implement
func (dec *decoder) decodePackage() error {
	for {

	}
	return nil
}

// TODO: implement
func (dec *decoder) decodeLanguages() error {
	return nil
}

// TODO: implement
func (dec *decoder) decodeLanguage() error {
	return nil
}

// TODO: implement
func (dec *decoder) decodeRepository() error {
	return nil
}

// TODO: implement
func (dec *decoder) unmarshalInt(data []byte) (int64, error) {
	return 0, nil
}

// TODO: implement
func (dec *decoder) unmarshalString(data []byte) (string, error) {
	return "", nil
}

// TODO: implement
func (dec *decoder) tagToFieldName(tag string) string {
	var field string
	for _, seg := range strings.Split(tag, "_") {
		if len(seg) == 0 {
			return ""
		}
		field += strings.ToUpper(string(seg[0]))
		if len(seg) > 1 {
			field += seg[1:]
		}
	}
	return field
}
<|endoftext|>


<commit_before>package sdees

import (
	"errors"
	"fmt"
	"os"
	"os/exec"
)

func IsItDocumentOrEntry(doc string) (bool, string, string) {
	availableFiles := ListFiles(RemoteFolder)
	for _, file := range availableFiles {
		logger.Debug(doc, file)
		if EncryptOTP(doc) == EncryptOTP(file) {
			return true, EncryptOTP(doc), ""
		}
	}
	branchList, _ := ListBranches(RemoteFolder)
	for _, branch := range branchList {
		if EncryptOTP(branch) == EncryptOTP(doc) {
			for _, doc := range ListFilesOfOne(RemoteFolder, branch) {
				logger.Debug("You've entered a entry '%s' which is in document '%s'", branch, doc)
				return true, EncryptOTP(doc), EncryptOTP(branch)
			}
		}
	}
	return false, "", ""
}

func GoDelete() {
	// Check if user is deleting a entry or a document
	if len(InputDocument) == 0 {
		fmt.Printf("Which document or entry would you like to delete? ")
		fmt.Scanln(&InputDocument)
	}
	gotOne, document, entry := IsItDocumentOrEntry(InputDocument)
	if !gotOne {
		fmt.Printf("%s is not a document or entry, did you type it correctly?\n", DecryptOTP(InputDocument))
		return
	}

	// Get the cache
	cache, _, err := UpdateCache(RemoteFolder, document, false)
	if err != nil {
		logger.Error("Error updating cache: %s", err.Error())
		return
	}
	if len(entry) == 0 {
		GoDeleteDocument(document, cache)
	} else {
		GoDeleteEntry(document, entry, cache)
	}
}

func GoDeleteEntry(document string, entry string, cache Cache) {
	var yesno string
	fmt.Printf("Are you sure you want to delete the entry '%s' in document '%s'? (y/n) ", DecryptOTP(entry), DecryptOTP(document))
	fmt.Scanln(&yesno)
	if string(yesno) == "y" {
		deleteSuccess := false
		for _, branch := range cache.Branch {
			if branch.Branch == entry {
				err := DeleteBranch(entry)
				deleteSuccess = true
				if err == nil {
					fmt.Printf("Deleted entry %s\n", (entry))
				} else {
					fmt.Printf("Error deleting %s, does it exist?\n", DecryptOTP(entry))
				}
			}
		}
		if !deleteSuccess {
			fmt.Printf("Error deleting %s, it does not exist\n", DecryptOTP(entry))
		}
	} else {
		fmt.Printf("Did not delete %s\n", (entry))
	}
}

func GoDeleteDocument(document string, cache Cache) error {
	var yesno string
	fmt.Printf("Are you sure you want to delete the document %s? (y/n) ", DecryptOTP(document))
	fmt.Scanln(&yesno)
	if string(yesno) == "y" {
		for _, branch := range cache.Branch {
			err := Delete(RemoteFolder, branch.Branch)
			if err != nil {
				logger.Debug(err.Error())
			}
			if err == nil {
				fmt.Printf("Deleted entry %s\n", DecryptOTP(branch.Branch))
			} else {
				fmt.Printf("Error deleting %s\n", DecryptOTP(branch.Branch))
			}
		}
	} else {
		fmt.Printf("Did not delete %s\n", DecryptOTP(document))
	}

	logger.Debug("Deleting cache")
	err := DeleteCache()
	if err != nil {
		logger.Debug(err.Error())
		return err
	}

	logger.Debug("Deleting master index file: .%s", document)
	cwd, _ := os.Getwd()
	defer os.Chdir(cwd)
	os.Chdir(RemoteFolder)

	// Make sure we aren't on that branch
	cmd := exec.Command("git", "checkout", "master")
	_, err = cmd.Output()
	if err != nil {
		return errors.New("Problem switching to master")
	}

	// Remove file from index
	logger.Debug("git rm -f '.%s'", document)
	cmd = exec.Command("git", "rm", "-f", "."+document)
	_, err = cmd.Output()
	if err != nil {
		return errors.New("Problem git rm -f ")
	}

	logger.Debug("git commit -m %s", document)
	cmd = exec.Command("git", "commit", "-m", "removed '"+document+"'")
	_, err = cmd.Output()
	if err != nil {
		return errors.New("Problem git commit -m ")
	}

	fmt.Print("Deleting on remote")
	err = Push(RemoteFolder)
	if err != nil {
		logger.Debug(err.Error())
		return err
	}
	fmt.Println("...done")
	return nil
}
<commit_msg>Need to delete cache<commit_after>package sdees

import (
	"errors"
	"fmt"
	"os"
	"os/exec"
)

func IsItDocumentOrEntry(doc string) (bool, string, string) {
	availableFiles := ListFiles(RemoteFolder)
	for _, file := range availableFiles {
		logger.Debug(doc, file)
		if EncryptOTP(doc) == EncryptOTP(file) {
			return true, EncryptOTP(doc), ""
		}
	}
	branchList, _ := ListBranches(RemoteFolder)
	for _, branch := range branchList {
		if EncryptOTP(branch) == EncryptOTP(doc) {
			for _, doc := range ListFilesOfOne(RemoteFolder, branch) {
				logger.Debug("You've entered a entry '%s' which is in document '%s'", branch, doc)
				return true, EncryptOTP(doc), EncryptOTP(branch)
			}
		}
	}
	return false, "", ""
}

func GoDelete() {
	// Check if user is deleting a entry or a document
	if len(InputDocument) == 0 {
		fmt.Printf("Which document or entry would you like to delete? ")
		fmt.Scanln(&InputDocument)
	}
	gotOne, document, entry := IsItDocumentOrEntry(InputDocument)
	if !gotOne {
		fmt.Printf("%s is not a document or entry, did you type it correctly?\n", DecryptOTP(InputDocument))
		return
	}

	// Get the cache
	cache, _, err := UpdateCache(RemoteFolder, document, false)
	if err != nil {
		logger.Error("Error updating cache: %s", err.Error())
		return
	}
	if len(entry) == 0 {
		GoDeleteDocument(document, cache)
	} else {
		GoDeleteEntry(document, entry, cache)
	}
	CurrentDocument = document
	DeleteCache()
}

func GoDeleteEntry(document string, entry string, cache Cache) {
	var yesno string
	fmt.Printf("Are you sure you want to delete the entry '%s' in document '%s'? (y/n) ", DecryptOTP(entry), DecryptOTP(document))
	fmt.Scanln(&yesno)
	if string(yesno) == "y" {
		deleteSuccess := false
		for _, branch := range cache.Branch {
			if branch.Branch == entry {
				err := DeleteBranch(entry)
				deleteSuccess = true
				if err == nil {
					fmt.Printf("Deleted entry %s\n", (entry))
				} else {
					fmt.Printf("Error deleting %s, does it exist?\n", DecryptOTP(entry))
				}
			}
		}
		if !deleteSuccess {
			fmt.Printf("Error deleting %s, it does not exist\n", DecryptOTP(entry))
		}
	} else {
		fmt.Printf("Did not delete %s\n", (entry))
	}
}

func GoDeleteDocument(document string, cache Cache) error {
	var yesno string
	fmt.Printf("Are you sure you want to delete the document %s? (y/n) ", DecryptOTP(document))
	fmt.Scanln(&yesno)
	if string(yesno) == "y" {
		for _, branch := range cache.Branch {
			err := Delete(RemoteFolder, branch.Branch)
			if err != nil {
				logger.Debug(err.Error())
			}
			if err == nil {
				fmt.Printf("Deleted entry %s\n", DecryptOTP(branch.Branch))
			} else {
				fmt.Printf("Error deleting %s\n", DecryptOTP(branch.Branch))
			}
		}
	} else {
		fmt.Printf("Did not delete %s\n", DecryptOTP(document))
	}

	logger.Debug("Deleting master index file: .%s", document)
	cwd, _ := os.Getwd()
	defer os.Chdir(cwd)
	os.Chdir(RemoteFolder)

	// Make sure we aren't on that branch
	cmd := exec.Command("git", "checkout", "master")
	_, err := cmd.Output()
	if err != nil {
		return errors.New("Problem switching to master")
	}

	// Remove file from index
	logger.Debug("git rm -f '.%s'", document)
	cmd = exec.Command("git", "rm", "-f", "."+document)
	_, err = cmd.Output()
	if err != nil {
		return errors.New("Problem git rm -f ")
	}

	logger.Debug("git commit -m %s", document)
	cmd = exec.Command("git", "commit", "-m", "removed '"+document+"'")
	_, err = cmd.Output()
	if err != nil {
		return errors.New("Problem git commit -m ")
	}

	fmt.Print("Deleting on remote")
	err = Push(RemoteFolder)
	if err != nil {
		logger.Debug(err.Error())
		return err
	}
	fmt.Println("...done")
	return nil
}
<|endoftext|>


<commit_before>package cask

// The Lexer has been stolen from:
// https://github.com/goruby/goruby/blob/master/lexer

import (
	"fmt"
	"testing"

	"github.com/stretchr/testify/assert"
)

func testSingleNextToken(t *testing.T, input string, expectedType TokenType, expectedLiteral string) {
	lexer := NewLexer(input)

	if lexer.HasNext() {
		token := lexer.NextToken()

		// type
		assert.Equal(t, expectedType, token.Type, fmt.Sprintf(
			"Expected token with type %q, got type %q\n",
			expectedType,
			token.Type,
		))

		// literal
		assert.Equal(t, expectedLiteral, token.Literal, fmt.Sprintf(
			"Expected token with literal %q, got literal %q\n",
			expectedLiteral,
			token.Literal,
		))
	}
}

func TestLexerNextToken(t *testing.T) {
	// test (successful)
	input := `five = 5
# just comment
fifty = 5_0
ten = 10

def add(x, y)
	x + y
end

result = add(five, ten)
!-/*5;
5 < 10 > 5
return

if 5 < 10 then
	true
else
	false
end

10 == 10
10 != 9
""
"foobar"
'foobar'
"foo bar"
'foo bar'
:sym
.

def nil?
end

def run!
end

[1, 2]
nil
self
Ten = 10
module Abc
end
class Abc
end
add { |x| x }
add do |x|
end
yield
A::B
$foo;
$Foo
$@
$a`

	testCases := []struct {
		expectedType    TokenType
		expectedLiteral string
	}{
		{IDENT, "five"},
		{ASSIGN, "="},
		{INT, "5"},
		{NEWLINE, "\n"},
		{IDENT, "fifty"},
		{ASSIGN, "="},
		{INT, "5_0"},
		{NEWLINE, "\n"},
		{IDENT, "ten"},
		{ASSIGN, "="},
		{INT, "10"},
		{NEWLINE, "\n"},
		{NEWLINE, "\n"},
		{DEF, "def"},
		{IDENT, "add"},
		{LPAREN, "("},
		{IDENT, "x"},
		{COMMA, ","},
		{IDENT, "y"},
		{RPAREN, ")"},
		{NEWLINE, "\n"},
		{IDENT, "x"},
		{PLUS, "+"},
		{IDENT, "y"},
		{NEWLINE, "\n"},
		{END, "end"},
		{NEWLINE, "\n"},
		{NEWLINE, "\n"},
		{IDENT, "result"},
		{ASSIGN, "="},
		{IDENT, "add"},
		{LPAREN, "("},
		{IDENT, "five"},
		{COMMA, ","},
		{IDENT, "ten"},
		{RPAREN, ")"},
		{NEWLINE, "\n"},
		{BANG, "!"},
		{MINUS, "-"},
		{SLASH, "/"},
		{ASTERISK, "*"},
		{INT, "5"},
		{SEMICOLON, ";"},
		{NEWLINE, "\n"},
		{INT, "5"},
		{LT, "<"},
		{INT, "10"},
		{GT, ">"},
		{INT, "5"},
		{NEWLINE, "\n"},
		{RETURN, "return"},
		{NEWLINE, "\n"},
		{NEWLINE, "\n"},
		{IF, "if"},
		{INT, "5"},
		{LT, "<"},
		{INT, "10"},
		{THEN, "then"},
		{NEWLINE, "\n"},
		{TRUE, "true"},
		{NEWLINE, "\n"},
		{ELSE, "else"},
		{NEWLINE, "\n"},
		{FALSE, "false"},
		{NEWLINE, "\n"},
		{END, "end"},
		{NEWLINE, "\n"},
		{NEWLINE, "\n"},
		{INT, "10"},
		{EQ, "=="},
		{INT, "10"},
		{NEWLINE, "\n"},
		{INT, "10"},
		{NOTEQ, "!="},
		{INT, "9"},
		{NEWLINE, "\n"},
		{STRING, ""},
		{NEWLINE, "\n"},
		{STRING, "foobar"},
		{NEWLINE, "\n"},
		{STRING, "foobar"},
		{NEWLINE, "\n"},
		{STRING, "foo bar"},
		{NEWLINE, "\n"},
		{STRING, "foo bar"},
		{NEWLINE, "\n"},
		{SYMBOL, "sym"},
		{NEWLINE, "\n"},
		{DOT, "."},
		{NEWLINE, "\n"},
		{NEWLINE, "\n"},
		{DEF, "def"},
		{IDENT, "nil?"},
		{NEWLINE, "\n"},
		{END, "end"},
		{NEWLINE, "\n"},
		{NEWLINE, "\n"},
		{DEF, "def"},
		{IDENT, "run!"},
		{NEWLINE, "\n"},
		{END, "end"},
		{NEWLINE, "\n"},
		{NEWLINE, "\n"},
		{LBRACKET, "["},
		{INT, "1"},
		{COMMA, ","},
		{INT, "2"},
		{RBRACKET, "]"},
		{NEWLINE, "\n"},
		{NIL, "nil"},
		{NEWLINE, "\n"},
		{SELF, "self"},
		{NEWLINE, "\n"},
		{CONST, "Ten"},
		{ASSIGN, "="},
		{INT, "10"},
		{NEWLINE, "\n"},
		{MODULE, "module"},
		{CONST, "Abc"},
		{NEWLINE, "\n"},
		{END, "end"},
		{NEWLINE, "\n"},
		{CLASS, "class"},
		{CONST, "Abc"},
		{NEWLINE, "\n"},
		{END, "end"},
		{NEWLINE, "\n"},
		{IDENT, "add"},
		{LBRACE, "{"},
		{PIPE, "|"},
		{IDENT, "x"},
		{PIPE, "|"},
		{IDENT, "x"},
		{RBRACE, "}"},
		{NEWLINE, "\n"},
		{IDENT, "add"},
		{DO, "do"},
		{PIPE, "|"},
		{IDENT, "x"},
		{PIPE, "|"},
		{NEWLINE, "\n"},
		{END, "end"},
		{NEWLINE, "\n"},
		{YIELD, "yield"},
		{NEWLINE, "\n"},
		{CONST, "A"},
		{SCOPE, "::"},
		{CONST, "B"},
		{NEWLINE, "\n"},
		{GLOBAL, "$foo"},
		{SEMICOLON, ";"},
		{NEWLINE, "\n"},
		{GLOBAL, "$Foo"},
		{NEWLINE, "\n"},
		{GLOBAL, "$@"},
		{NEWLINE, "\n"},
		{GLOBAL, "$a"},
		{EOF, ""},
	}

	lexer := NewLexer(input)

	// test
	for pos, testCase := range testCases {
		token := lexer.NextToken()

		// type
		assert.Equal(t, testCase.expectedType, token.Type, fmt.Sprintf(
			"Expected token with type %q at position %d, got type %q\n",
			testCase.expectedType,
			pos,
			token.Type,
		))

		// literal
		assert.Equal(t, testCase.expectedLiteral, token.Literal, fmt.Sprintf(
			"Expected token with literal %q at position %d, got literal %q\n",
			testCase.expectedLiteral,
			pos,
			token.Literal,
		))
	}

	// test (error)
	testSingleNextToken(t, "$ ", ILLEGAL, "Illegal character at 2: ' '")
	testSingleNextToken(t, "$;", ILLEGAL, "Illegal character at 2: ';'")
	testSingleNextToken(t, "\\", ILLEGAL, "Illegal character at 0: '\\'")
}
<commit_msg>Fix and improve Lexer tests<commit_after>package cask

// The Lexer has been stolen from:
// https://github.com/goruby/goruby/blob/master/lexer

import (
	"fmt"
	"testing"

	"github.com/stretchr/testify/assert"
)

func assertNextToken(t *testing.T, lexer *Lexer, expectedType TokenType, expectedLiteral string, position int) {
	token := lexer.NextToken()

	// type
	assert.Equal(t, expectedType, token.Type, fmt.Sprintf(
		"Expected token with type %q at position %d, got type %q\n",
		expectedType,
		position,
		token.Type,
	))

	// literal
	assert.Equal(t, expectedLiteral, token.Literal, fmt.Sprintf(
		"Expected token with literal %q at position %d, got literal %q\n",
		expectedLiteral,
		position,
		token.Literal,
	))
}

func assertSingleNextToken(t *testing.T, input string, expectedType TokenType, expectedLiteral string) {
	lexer := NewLexer(input)

	if lexer.HasNext() {
		token := lexer.NextToken()

		// type
		assert.Equal(t, expectedType, token.Type, fmt.Sprintf(
			"Expected token with type %q, got type %q\n",
			expectedType,
			token.Type,
		))

		// literal
		assert.Equal(t, expectedLiteral, token.Literal, fmt.Sprintf(
			"Expected token with literal %q, got literal %q\n",
			expectedLiteral,
			token.Literal,
		))
	}
}

func TestLexerNextToken(t *testing.T) {
	// test (successful)
	input := `
# just comment

five = 5
fifty = 50
result = add(five, fifty)

!-/*5;
10 == 10
10 != 9
4 % 2
5 < 10 > 5

[1, 2]
A::B
:symbol

$foo;
$Foo
$@
$a

def add(x, y)
	x + y
end

def nil?
end

def run!
end

module Abc
end

class Abc
end

if 5 < 10 then
	true
else
	false
end

add do |x|
end

add { |x| x }
`

	testCases := []struct {
		expectedType    TokenType
		expectedLiteral string
	}{
		{NEWLINE, "\n"},
		{NEWLINE, "\n"},

		{IDENT, "five"},
		{ASSIGN, "="},
		{INT, "5"},
		{NEWLINE, "\n"},

		{IDENT, "fifty"},
		{ASSIGN, "="},
		{INT, "50"},
		{NEWLINE, "\n"},

		{IDENT, "result"},
		{ASSIGN, "="},
		{IDENT, "add"},
		{LPAREN, "("},
		{IDENT, "five"},
		{COMMA, ","},
		{IDENT, "fifty"},
		{RPAREN, ")"},
		{NEWLINE, "\n"},
		{NEWLINE, "\n"},

		{BANG, "!"},
		{MINUS, "-"},
		{SLASH, "/"},
		{ASTERISK, "*"},
		{INT, "5"},
		{SEMICOLON, ";"},
		{NEWLINE, "\n"},

		{INT, "10"},
		{EQ, "=="},
		{INT, "10"},
		{NEWLINE, "\n"},

		{INT, "10"},
		{NOTEQ, "!="},
		{INT, "9"},
		{NEWLINE, "\n"},

		{INT, "4"},
		{MODULUS, "%"},
		{INT, "2"},
		{NEWLINE, "\n"},

		{INT, "5"},
		{LT, "<"},
		{INT, "10"},
		{GT, ">"},
		{INT, "5"},
		{NEWLINE, "\n"},
		{NEWLINE, "\n"},

		{LBRACKET, "["},
		{INT, "1"},
		{COMMA, ","},
		{INT, "2"},
		{RBRACKET, "]"},
		{NEWLINE, "\n"},

		{CONST, "A"},
		{SCOPE, "::"},
		{CONST, "B"},
		{NEWLINE, "\n"},

		{SYMBOL, "symbol"},
		{NEWLINE, "\n"},
		{NEWLINE, "\n"},

		// Globals

		{GLOBAL, "$foo"},
		{SEMICOLON, ";"},
		{NEWLINE, "\n"},

		{GLOBAL, "$Foo"},
		{NEWLINE, "\n"},

		{GLOBAL, "$@"},
		{NEWLINE, "\n"},

		{GLOBAL, "$a"},
		{NEWLINE, "\n"},
		{NEWLINE, "\n"},

		// Blocks

		{DEF, "def"},
		{IDENT, "add"},
		{LPAREN, "("},
		{IDENT, "x"},
		{COMMA, ","},
		{IDENT, "y"},
		{RPAREN, ")"},
		{NEWLINE, "\n"},
		{IDENT, "x"},
		{PLUS, "+"},
		{IDENT, "y"},
		{NEWLINE, "\n"},
		{END, "end"},
		{NEWLINE, "\n"},
		{NEWLINE, "\n"},

		{DEF, "def"},
		{IDENT, "nil?"},
		{NEWLINE, "\n"},
		{END, "end"},
		{NEWLINE, "\n"},
		{NEWLINE, "\n"},

		{DEF, "def"},
		{IDENT, "run!"},
		{NEWLINE, "\n"},
		{END, "end"},
		{NEWLINE, "\n"},
		{NEWLINE, "\n"},

		{MODULE, "module"},
		{CONST, "Abc"},
		{NEWLINE, "\n"},
		{END, "end"},
		{NEWLINE, "\n"},
		{NEWLINE, "\n"},

		{CLASS, "class"},
		{CONST, "Abc"},
		{NEWLINE, "\n"},
		{END, "end"},
		{NEWLINE, "\n"},
		{NEWLINE, "\n"},

		{IF, "if"},
		{INT, "5"},
		{LT, "<"},
		{INT, "10"},
		{THEN, "then"},
		{NEWLINE, "\n"},
		{TRUE, "true"},
		{NEWLINE, "\n"},
		{ELSE, "else"},
		{NEWLINE, "\n"},
		{FALSE, "false"},
		{NEWLINE, "\n"},
		{END, "end"},
		{NEWLINE, "\n"},
		{NEWLINE, "\n"},

		{IDENT, "add"},
		{DO, "do"},
		{PIPE, "|"},
		{IDENT, "x"},
		{PIPE, "|"},
		{NEWLINE, "\n"},
		{END, "end"},
		{NEWLINE, "\n"},
		{NEWLINE, "\n"},

		{IDENT, "add"},
		{LBRACE, "{"},
		{PIPE, "|"},
		{IDENT, "x"},
		{PIPE, "|"},
		{IDENT, "x"},
		{RBRACE, "}"},
		{NEWLINE, "\n"},

		{EOF, ""},
	}

	lexer := NewLexer(input)

	// test
	for position, testCase := range testCases {
		assertNextToken(t, lexer, testCase.expectedType, testCase.expectedLiteral, position)
	}

	// test (error)
	assertSingleNextToken(t, "$ ", ILLEGAL, "Illegal character at 2: ' '")
	assertSingleNextToken(t, "$;", ILLEGAL, "Illegal character at 2: ';'")
	assertSingleNextToken(t, "\\", ILLEGAL, "Illegal character at 0: '\\'")
}

func TestLexerPercentNotationRegexp(t *testing.T) {
	// test (successful)
	input := `
%r(regex)
%r[regex]
%r{regex}
%r<regex>
`

	testCases := []struct {
		expectedType    TokenType
		expectedLiteral string
	}{
		{NEWLINE, "\n"},

		{PNREGEXP, "%r"},
		{PNSTART, "("},
		{REGEXP, "regex"},
		{PNEND, ")"},
		{NEWLINE, "\n"},

		{PNREGEXP, "%r"},
		{PNSTART, "["},
		{REGEXP, "regex"},
		{PNEND, "]"},
		{NEWLINE, "\n"},

		{PNREGEXP, "%r"},
		{PNSTART, "{"},
		{REGEXP, "regex"},
		{PNEND, "}"},
		{NEWLINE, "\n"},

		{PNREGEXP, "%r"},
		{PNSTART, "<"},
		{REGEXP, "regex"},
		{PNEND, ">"},
		{NEWLINE, "\n"},

		{EOF, ""},
	}

	lexer := NewLexer(input)

	// test
	for position, testCase := range testCases {
		assertNextToken(t, lexer, testCase.expectedType, testCase.expectedLiteral, position)
	}
}

func TestLexerStrings(t *testing.T) {
	// test (successful)
	input := `
""
''
"double quoted string"
'single quoted string'
`

	testCases := []struct {
		expectedType    TokenType
		expectedLiteral string
	}{
		{NEWLINE, "\n"},

		{STRING, ""},
		{NEWLINE, "\n"},

		{STRING, ""},
		{NEWLINE, "\n"},

		{STRING, "double quoted string"},
		{NEWLINE, "\n"},

		{STRING, "single quoted string"},
		{NEWLINE, "\n"},

		{EOF, ""},
	}

	lexer := NewLexer(input)

	// test
	for position, testCase := range testCases {
		assertNextToken(t, lexer, testCase.expectedType, testCase.expectedLiteral, position)
	}
}

func TestLexerDelimiters(t *testing.T) {
	assertSingleNextToken(t, ",", COMMA, ",")
	assertSingleNextToken(t, "\n", NEWLINE, "\n")
	assertSingleNextToken(t, ";", SEMICOLON, ";")
	assertSingleNextToken(t, ".", DOT, ".")
	assertSingleNextToken(t, "{", LBRACE, "{")
	assertSingleNextToken(t, "[", LBRACKET, "[")
	assertSingleNextToken(t, "(", LPAREN, "(")
	assertSingleNextToken(t, "|", PIPE, "|")
	assertSingleNextToken(t, "}", RBRACE, "}")
	assertSingleNextToken(t, "]", RBRACKET, "]")
	assertSingleNextToken(t, ")", RPAREN, ")")
	assertSingleNextToken(t, "::", SCOPE, "::")
}

func TestLexerKeywords(t *testing.T) {
	assertSingleNextToken(t, "class", CLASS, "class")
	assertSingleNextToken(t, "def", DEF, "def")
	assertSingleNextToken(t, "do", DO, "do")
	assertSingleNextToken(t, "else", ELSE, "else")
	assertSingleNextToken(t, "end", END, "end")
	assertSingleNextToken(t, "false", FALSE, "false")
	assertSingleNextToken(t, "if", IF, "if")
	assertSingleNextToken(t, "elsif", ELSEIF, "elsif")
	assertSingleNextToken(t, "module", MODULE, "module")
	assertSingleNextToken(t, "nil", NIL, "nil")
	assertSingleNextToken(t, "return", RETURN, "return")
	assertSingleNextToken(t, "self", SELF, "self")
	assertSingleNextToken(t, "then", THEN, "then")
	assertSingleNextToken(t, "true", TRUE, "true")
	assertSingleNextToken(t, "yield", YIELD, "yield")
}
<|endoftext|>


<commit_before>package uuid

import (
	"testing"
)

var (
	testStringUUID = "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"
	testByteUUID   = []byte("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11")
)

func TestZero(t *testing.T) {
	u := UUID{}

	if !u.IsZero() {
		t.Error("Default value is not zero")
	}
}

func TestZero2(t *testing.T) {
	u := UUID{}

	if u.String() != "00000000-0000-0000-0000-000000000000" {
		t.Error("Default zero value is not zero uuid")
	}
}

func TestFromString(t *testing.T) {
	u, err := FromString("00000000-0000-0000-0000-000000000000")
	if err != nil {
		t.Error("Failed to read zero-uuid")
	}

	if !u.IsZero() {
		t.Error("Zero-uuid from string does not yield zero-uuid")
	}

	if u.String() != "00000000-0000-0000-0000-000000000000" {
		t.Error("zero uuid is not zero uuid")
	}
}

func TestFromStringMultiple(t *testing.T) {
	list := []string{
		"00000000-0000-0000-0000-00000000000f",
		"00000000-0000-0000-0000-0000000000f0",
		"00000000-0000-0000-0000-100000000000",
		"00000000-0000-0000-f000-000000000000",
		"00000000-0000-f000-0000-000000000000",
		"00000000-f000-0000-0000-000000000000",
		"f0000000-0000-0000-0000-000000000000",
		"0f000000-0000-0000-0000-000000000000",
		"000f0000-0000-0000-0000-000000000000",
		"00000000-00f0-0000-0000-000000000000",
		"f0000000-f000-f000-f000-f00000000000",
		"12345678-9abc-deff-edcb-a98765432100",
		"ffffffff-ffff-ffff-ffff-ffffffffffff",
	}

	for _, i := range list {
		u, err := FromString(i)
		if err != nil {
			t.Error("Failed to read uuid '" + i + "':" + err.Error())

			continue
		}

		if u.String() != i {
			t.Error("String representation of UUID '" + i + "' does not match, got '" + u.String() + "'.")
		}
	}
}

func TestMaybeFromString(t *testing.T) {
	list := map[string]string{
		"00000000-0000-0000-0000-00000000000f": "00000000-0000-0000-0000-00000000000f",
		"12345678-1234-5678-1234-567812345678": "12345678-1234-5678-1234-567812345678",
		"c56a4180-65aa-42ec-a945-5fd21dec0538": "c56a4180-65aa-42ec-a945-5fd21dec0538",
		"00000000-0000-0000-0000-00000000000":  "00000000-0000-0000-0000-000000000000",
		"":                                     "00000000-0000-0000-0000-000000000000",
		"C56A4180-65AA-42EC-A945-5FD21DEC":     "00000000-0000-0000-0000-000000000000",
		"x56a4180-h5aa-42ec-a945-5fd21dec0538": "00000000-0000-0000-0000-000000000000",
		"null":                                 "00000000-0000-0000-0000-000000000000",
		"something invalid here":               "00000000-0000-0000-0000-000000000000",
	}

	for input, expected := range list {
		u := MaybeFromString(input)
		if u.String() != expected {
			t.Errorf("MaybeFromString(%s) does not match %s, got %s", input, expected, u.String())
		}
	}
}

func TestMustFromString(t *testing.T) {
	list := map[string]string{
		"00000000-0000-0000-0000-00000000000f": "00000000-0000-0000-0000-00000000000f",
		"12345678-1234-5678-1234-567812345678": "12345678-1234-5678-1234-567812345678",
		"c56a4180-65aa-42ec-a945-5fd21dec0538": "c56a4180-65aa-42ec-a945-5fd21dec0538",
		"00000000-0000-0000-0000-00000000000":  "", /* Means panic is expected */
		"":                                     "",
		"C56A4180-65AA-42EC-A945-5FD21DEC":     "",
		"x56a4180-h5aa-42ec-a945-5fd21dec0538": "",
		"null":                                 "",
		"something invalid here":               "",
	}

	for input, expected := range list {
		testMustFromString(t, input, expected)
	}
}

func testMustFromString(t *testing.T, input string, expected string) {
	var u UUID

	defer func() {
		err := recover()

		if expected == "" && err == nil {
			t.Errorf("MustFromString(%s) expected panic, got %s", input, u.String())
		}

		if expected != "" && err != nil {
			t.Errorf("MustFromString(%s) paniced, expected %s", input, expected)
		}
	}()

	u = MustFromString(input)
	if expected != "" && u.String() != expected {
		t.Errorf("MustFromString(%s) does not match %s, got %s", input, expected, u.String())
	}
}

func TestAlternativeValid(t *testing.T) {
	uuid := "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"
	list := []string{
		"A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11",
		"{a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11}",
		"a0eebc999c0b4ef8bb6d6bb9bd380a11",
		"a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11",
		"{a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11}",
	}

	for _, i := range list {
		u, err := FromString(i)
		if err != nil {
			t.Error("Failed to read uuid '" + i + "':" + err.Error())

			continue
		}

		if u.String() != uuid {
			t.Error("String representation of UUID '" + i + "' does not match, got '" + u.String() + "'.")
		}
	}
}

func TestInvalid(t *testing.T) {
	list := []string{
		"",
		"0",
		"abcdefg",
		"fffffff-ffff-ffff-ffff-fffffffffffff",   /* all - shifted one to the left */
		"fffffffff-ffff-ffff-ffff-fffffffffff",   /* all - shifted one to the right */
		"ffffffff-ffff-ffff-ffff-fffffffffff",    /* one char too short */
		"ffffffff-ffff-ffff-ffff-fffffffffffff",  /* one char too long */
		"ffffffff-ffff-ffff-ffff-ffffffffffffff", /* two char too long */
		"ffffffff-ffff-ffff-ffff--fffffffffff",   /* one dash instead of char */
	}

	for _, i := range list {
		_, err := FromString(i)
		if err == nil {
			t.Error("Expected error but got nothing when reading uuid '" + i + "'.")
		}
	}
}

func TestV4(t *testing.T) {
	u, err := V4()
	if err != nil {
		panic(err)
	}

	if u[6]&0xf0 != 0x40 {
		t.Error("UUID generated from V4() does not have the version byte set to 4: '" + u.String() + "'.")
	}

	if u[8]&0xf0 < 0x80 || u[8]&0xf0 > 0xB0 {
		t.Error("UUID generated from V4() does not have the 9th byte beginning with 8, 9, A or B: '" + u.String() + "'.")
	}
}

func BenchmarkFromString(b *testing.B) {
	for i := 0; i < b.N; i++ {
		FromString("12345678-9abc-deff-edcb-a98765432100")
	}
}

func BenchmarkFromString2(b *testing.B) {
	for i := 0; i < b.N; i++ {
		FromString("123456789abcdeffedcba98765432100")
	}
}

func BenchmarkSetString(b *testing.B) {
	for i := 0; i < b.N; i++ {
		u := UUID{}

		u.SetString(testStringUUID)
	}
}

func BenchmarkReadBytes(b *testing.B) {
	for i := 0; i < b.N; i++ {
		u := UUID{}

		u.ReadBytes(testByteUUID)
	}
}

func BenchmarkString(b *testing.B) {
	u, err := FromString("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11")
	if err != nil {
		panic(err)
	}

	for i := 0; i < b.N; i++ {
		u.String()
	}
}

func BenchmarkV4(b *testing.B) {
	for i := 0; i < b.N; i++ {
		V4()
	}
}
<commit_msg>Added benchmarks for MaybeFromString<commit_after>package uuid

import (
	"testing"
)

var (
	testStringUUID = "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"
	testByteUUID   = []byte("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11")
)

func TestZero(t *testing.T) {
	u := UUID{}

	if !u.IsZero() {
		t.Error("Default value is not zero")
	}
}

func TestZero2(t *testing.T) {
	u := UUID{}

	if u.String() != "00000000-0000-0000-0000-000000000000" {
		t.Error("Default zero value is not zero uuid")
	}
}

func TestFromString(t *testing.T) {
	u, err := FromString("00000000-0000-0000-0000-000000000000")
	if err != nil {
		t.Error("Failed to read zero-uuid")
	}

	if !u.IsZero() {
		t.Error("Zero-uuid from string does not yield zero-uuid")
	}

	if u.String() != "00000000-0000-0000-0000-000000000000" {
		t.Error("zero uuid is not zero uuid")
	}
}

func TestFromStringMultiple(t *testing.T) {
	list := []string{
		"00000000-0000-0000-0000-00000000000f",
		"00000000-0000-0000-0000-0000000000f0",
		"00000000-0000-0000-0000-100000000000",
		"00000000-0000-0000-f000-000000000000",
		"00000000-0000-f000-0000-000000000000",
		"00000000-f000-0000-0000-000000000000",
		"f0000000-0000-0000-0000-000000000000",
		"0f000000-0000-0000-0000-000000000000",
		"000f0000-0000-0000-0000-000000000000",
		"00000000-00f0-0000-0000-000000000000",
		"f0000000-f000-f000-f000-f00000000000",
		"12345678-9abc-deff-edcb-a98765432100",
		"ffffffff-ffff-ffff-ffff-ffffffffffff",
	}

	for _, i := range list {
		u, err := FromString(i)
		if err != nil {
			t.Error("Failed to read uuid '" + i + "':" + err.Error())

			continue
		}

		if u.String() != i {
			t.Error("String representation of UUID '" + i + "' does not match, got '" + u.String() + "'.")
		}
	}
}

func TestMaybeFromString(t *testing.T) {
	list := map[string]string{
		"00000000-0000-0000-0000-00000000000f": "00000000-0000-0000-0000-00000000000f",
		"12345678-1234-5678-1234-567812345678": "12345678-1234-5678-1234-567812345678",
		"c56a4180-65aa-42ec-a945-5fd21dec0538": "c56a4180-65aa-42ec-a945-5fd21dec0538",
		"00000000-0000-0000-0000-00000000000":  "00000000-0000-0000-0000-000000000000",
		"":                                     "00000000-0000-0000-0000-000000000000",
		"C56A4180-65AA-42EC-A945-5FD21DEC":     "00000000-0000-0000-0000-000000000000",
		"x56a4180-h5aa-42ec-a945-5fd21dec0538": "00000000-0000-0000-0000-000000000000",
		"null":                                 "00000000-0000-0000-0000-000000000000",
		"something invalid here":               "00000000-0000-0000-0000-000000000000",
	}

	for input, expected := range list {
		u := MaybeFromString(input)
		if u.String() != expected {
			t.Errorf("MaybeFromString(%s) does not match %s, got %s", input, expected, u.String())
		}
	}
}

func TestMustFromString(t *testing.T) {
	list := map[string]string{
		"00000000-0000-0000-0000-00000000000f": "00000000-0000-0000-0000-00000000000f",
		"12345678-1234-5678-1234-567812345678": "12345678-1234-5678-1234-567812345678",
		"c56a4180-65aa-42ec-a945-5fd21dec0538": "c56a4180-65aa-42ec-a945-5fd21dec0538",
		"00000000-0000-0000-0000-00000000000":  "", /* Means panic is expected */
		"":                                     "",
		"C56A4180-65AA-42EC-A945-5FD21DEC":     "",
		"x56a4180-h5aa-42ec-a945-5fd21dec0538": "",
		"null":                                 "",
		"something invalid here":               "",
	}

	for input, expected := range list {
		testMustFromString(t, input, expected)
	}
}

func testMustFromString(t *testing.T, input string, expected string) {
	var u UUID

	defer func() {
		err := recover()

		if expected == "" && err == nil {
			t.Errorf("MustFromString(%s) expected panic, got %s", input, u.String())
		}

		if expected != "" && err != nil {
			t.Errorf("MustFromString(%s) paniced, expected %s", input, expected)
		}
	}()

	u = MustFromString(input)
	if expected != "" && u.String() != expected {
		t.Errorf("MustFromString(%s) does not match %s, got %s", input, expected, u.String())
	}
}

func TestAlternativeValid(t *testing.T) {
	uuid := "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"
	list := []string{
		"A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11",
		"{a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11}",
		"a0eebc999c0b4ef8bb6d6bb9bd380a11",
		"a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11",
		"{a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11}",
	}

	for _, i := range list {
		u, err := FromString(i)
		if err != nil {
			t.Error("Failed to read uuid '" + i + "':" + err.Error())

			continue
		}

		if u.String() != uuid {
			t.Error("String representation of UUID '" + i + "' does not match, got '" + u.String() + "'.")
		}
	}
}

func TestInvalid(t *testing.T) {
	list := []string{
		"",
		"0",
		"abcdefg",
		"fffffff-ffff-ffff-ffff-fffffffffffff",   /* all - shifted one to the left */
		"fffffffff-ffff-ffff-ffff-fffffffffff",   /* all - shifted one to the right */
		"ffffffff-ffff-ffff-ffff-fffffffffff",    /* one char too short */
		"ffffffff-ffff-ffff-ffff-fffffffffffff",  /* one char too long */
		"ffffffff-ffff-ffff-ffff-ffffffffffffff", /* two char too long */
		"ffffffff-ffff-ffff-ffff--fffffffffff",   /* one dash instead of char */
	}

	for _, i := range list {
		_, err := FromString(i)
		if err == nil {
			t.Error("Expected error but got nothing when reading uuid '" + i + "'.")
		}
	}
}

func TestV4(t *testing.T) {
	u, err := V4()
	if err != nil {
		panic(err)
	}

	if u[6]&0xf0 != 0x40 {
		t.Error("UUID generated from V4() does not have the version byte set to 4: '" + u.String() + "'.")
	}

	if u[8]&0xf0 < 0x80 || u[8]&0xf0 > 0xB0 {
		t.Error("UUID generated from V4() does not have the 9th byte beginning with 8, 9, A or B: '" + u.String() + "'.")
	}
}

func BenchmarkFromString(b *testing.B) {
	for i := 0; i < b.N; i++ {
		FromString("12345678-9abc-deff-edcb-a98765432100")
	}
}

func BenchmarkFromString2(b *testing.B) {
	for i := 0; i < b.N; i++ {
		FromString("123456789abcdeffedcba98765432100")
	}
}

func BenchmarkSetString(b *testing.B) {
	for i := 0; i < b.N; i++ {
		u := UUID{}

		u.SetString(testStringUUID)
	}
}

func BenchmarkReadBytes(b *testing.B) {
	for i := 0; i < b.N; i++ {
		u := UUID{}

		u.ReadBytes(testByteUUID)
	}
}

func BenchmarkString(b *testing.B) {
	u, err := FromString("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11")
	if err != nil {
		panic(err)
	}

	for i := 0; i < b.N; i++ {
		u.String()
	}
}

func BenchmarkV4(b *testing.B) {
	for i := 0; i < b.N; i++ {
		V4()
	}
}

func BenchmarkMaybeFromStringOk(b *testing.B) {
	for i := 0; i < b.N; i++ {
		MaybeFromString("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11")
	}
}

func BenchmarkMaybeFromStringFail(b *testing.B) {
	for i := 0; i < b.N; i++ {
		MaybeFromString("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11abcdef")
	}
}
<|endoftext|>


<commit_before>// Copyright (C) 2013 by Maxim Bublis <b@codemonkey.ru>
//
// 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.

package uuid

import (
	"testing"
)

func TestString(t *testing.T) {
	if NamespaceDNS.String() != "6ba7b810-9dad-11d1-80b4-00c04fd430c8" {
		t.Errorf("Incorrect string representation for UUID: %s", NamespaceDNS.String())
	}
}

func TestEqual(t *testing.T) {
	if !Equal(NamespaceDNS, NamespaceDNS) {
		t.Errorf("Incorrect comparison of %s and %s", NamespaceDNS, NamespaceDNS)
	}

	if Equal(NamespaceDNS, NamespaceURL) {
		t.Errorf("Incorrect comparison of %s and %s", NamespaceDNS, NamespaceURL)
	}
}

func TestVersion(t *testing.T) {
	u := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

	if u.Version() != 1 {
		t.Errorf("Incorrect version for UUID: %d", u.Version())
	}
}

func TestSetVersion(t *testing.T) {
	u := new(UUID)
	u.SetVersion(4)

	if u.Version() != 4 {
		t.Errorf("Incorrect version for UUID after u.setVersion(4): %d", u.Version())
	}
}

func TestVariant(t *testing.T) {
	u1 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

	if u1.Variant() != VariantNCS {
		t.Errorf("Incorrect variant for UUID variant %d: %d", VariantNCS, u1.Variant())
	}

	u2 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

	if u2.Variant() != VariantRFC4122 {
		t.Errorf("Incorrect variant for UUID variant %d: %d", VariantRFC4122, u2.Variant())
	}

	u3 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

	if u3.Variant() != VariantMicrosoft {
		t.Errorf("Incorrect variant for UUID variant %d: %d", VariantMicrosoft, u3.Variant())
	}

	u4 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

	if u4.Variant() != VariantFuture {
		t.Errorf("Incorrect variant for UUID variant %d: %d", VariantFuture, u4.Variant())
	}
}

func TestSetVariant(t *testing.T) {
	u := new(UUID)
	u.SetVariant()

	if u.Variant() != VariantRFC4122 {
		t.Errorf("Incorrect variant for UUID after u.setVariant(): %d", u.Variant())
	}
}

func TestNewV1(t *testing.T) {
	u := NewV1()

	if u.Version() != 1 {
		t.Errorf("UUIDv1 generated with incorrect version: %d", u.Version())
	}

	if u.Variant() != VariantRFC4122 {
		t.Errorf("UUIDv1 generated with incorrect variant: %d", u.Variant())
	}

	u1 := NewV1()
	u2 := NewV1()

	if Equal(u1, u2) {
		t.Errorf("UUIDv1 generated two equal UUIDs: %s and %s", u1, u2)
	}

	oldFunc := epochFunc
	epochFunc = func() uint64 { return 0 }

	u3 := NewV1()
	u4 := NewV1()

	if Equal(u3, u4) {
		t.Errorf("UUIDv1 generated two equal UUIDs: %s and %s", u3, u4)
	}

	epochFunc = oldFunc
}

func TestNewV2(t *testing.T) {
	u1 := NewV2(DomainPerson)

	if u1.Version() != 2 {
		t.Errorf("UUIDv2 generated with incorrect version: %d", u1.Version())
	}

	if u1.Variant() != VariantRFC4122 {
		t.Errorf("UUIDv2 generated with incorrect variant: %d", u1.Variant())
	}

	u2 := NewV2(DomainGroup)

	if u2.Version() != 2 {
		t.Errorf("UUIDv2 generated with incorrect version: %d", u2.Version())
	}

	if u2.Variant() != VariantRFC4122 {
		t.Errorf("UUIDv2 generated with incorrect variant: %d", u2.Variant())
	}
}

func TestNewV3(t *testing.T) {
	u := NewV3(NamespaceDNS, "www.example.com")

	if u.Version() != 3 {
		t.Errorf("UUIDv3 generated with incorrect version: %d", u.Version())
	}

	if u.Variant() != VariantRFC4122 {
		t.Errorf("UUIDv3 generated with incorrect variant: %d", u.Variant())
	}

	if u.String() != "5df41881-3aed-3515-88a7-2f4a814cf09e" {
		t.Errorf("UUIDv3 generated incorrectly: %s", u.String())
	}

	u = NewV3(NamespaceDNS, "python.org")

	if u.String() != "6fa459ea-ee8a-3ca4-894e-db77e160355e" {
		t.Errorf("UUIDv3 generated incorrectly: %s", u.String())
	}

	u1 := NewV3(NamespaceDNS, "golang.org")
	u2 := NewV3(NamespaceDNS, "golang.org")
	if !Equal(u1, u2) {
		t.Errorf("UUIDv3 generated different UUIDs for same namespace and name: %s and %s", u1, u2)
	}

	u3 := NewV3(NamespaceDNS, "example.com")
	if Equal(u1, u3) {
		t.Errorf("UUIDv3 generated same UUIDs for different names in same namespace: %s and %s", u1, u2)
	}

	u4 := NewV3(NamespaceURL, "golang.org")
	if Equal(u1, u4) {
		t.Errorf("UUIDv3 generated same UUIDs for sane names in different namespaces: %s and %s", u1, u4)
	}
}

func TestNewV4(t *testing.T) {
	u := NewV4()

	if u.Version() != 4 {
		t.Errorf("UUIDv4 generated with incorrect version: %d", u.Version())
	}

	if u.Variant() != VariantRFC4122 {
		t.Errorf("UUIDv4 generated with incorrect variant: %d", u.Variant())
	}
}

func TestNewV5(t *testing.T) {
	u := NewV5(NamespaceDNS, "www.example.com")

	if u.Version() != 5 {
		t.Errorf("UUIDv5 generated with incorrect version: %d", u.Version())
	}

	if u.Variant() != VariantRFC4122 {
		t.Errorf("UUIDv5 generated with incorrect variant: %d", u.Variant())
	}

	u = NewV5(NamespaceDNS, "python.org")

	if u.String() != "886313e1-3b8a-5372-9b90-0c9aee199e5d" {
		t.Errorf("UUIDv5 generated incorrectly: %s", u.String())
	}

	u1 := NewV5(NamespaceDNS, "golang.org")
	u2 := NewV5(NamespaceDNS, "golang.org")
	if !Equal(u1, u2) {
		t.Errorf("UUIDv5 generated different UUIDs for same namespace and name: %s and %s", u1, u2)
	}

	u3 := NewV5(NamespaceDNS, "example.com")
	if Equal(u1, u3) {
		t.Errorf("UUIDv5 generated same UUIDs for different names in same namespace: %s and %s", u1, u2)
	}

	u4 := NewV5(NamespaceURL, "golang.org")
	if Equal(u1, u4) {
		t.Errorf("UUIDv3 generated same UUIDs for sane names in different namespaces: %s and %s", u1, u4)
	}
}
<commit_msg>Using value instead of pointer in test<commit_after>// Copyright (C) 2013 by Maxim Bublis <b@codemonkey.ru>
//
// 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.

package uuid

import (
	"testing"
)

func TestString(t *testing.T) {
	if NamespaceDNS.String() != "6ba7b810-9dad-11d1-80b4-00c04fd430c8" {
		t.Errorf("Incorrect string representation for UUID: %s", NamespaceDNS.String())
	}
}

func TestEqual(t *testing.T) {
	if !Equal(NamespaceDNS, NamespaceDNS) {
		t.Errorf("Incorrect comparison of %s and %s", NamespaceDNS, NamespaceDNS)
	}

	if Equal(NamespaceDNS, NamespaceURL) {
		t.Errorf("Incorrect comparison of %s and %s", NamespaceDNS, NamespaceURL)
	}
}

func TestVersion(t *testing.T) {
	u := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

	if u.Version() != 1 {
		t.Errorf("Incorrect version for UUID: %d", u.Version())
	}
}

func TestSetVersion(t *testing.T) {
	u := UUID{}
	u.SetVersion(4)

	if u.Version() != 4 {
		t.Errorf("Incorrect version for UUID after u.setVersion(4): %d", u.Version())
	}
}

func TestVariant(t *testing.T) {
	u1 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

	if u1.Variant() != VariantNCS {
		t.Errorf("Incorrect variant for UUID variant %d: %d", VariantNCS, u1.Variant())
	}

	u2 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

	if u2.Variant() != VariantRFC4122 {
		t.Errorf("Incorrect variant for UUID variant %d: %d", VariantRFC4122, u2.Variant())
	}

	u3 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

	if u3.Variant() != VariantMicrosoft {
		t.Errorf("Incorrect variant for UUID variant %d: %d", VariantMicrosoft, u3.Variant())
	}

	u4 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

	if u4.Variant() != VariantFuture {
		t.Errorf("Incorrect variant for UUID variant %d: %d", VariantFuture, u4.Variant())
	}
}

func TestSetVariant(t *testing.T) {
	u := new(UUID)
	u.SetVariant()

	if u.Variant() != VariantRFC4122 {
		t.Errorf("Incorrect variant for UUID after u.setVariant(): %d", u.Variant())
	}
}

func TestNewV1(t *testing.T) {
	u := NewV1()

	if u.Version() != 1 {
		t.Errorf("UUIDv1 generated with incorrect version: %d", u.Version())
	}

	if u.Variant() != VariantRFC4122 {
		t.Errorf("UUIDv1 generated with incorrect variant: %d", u.Variant())
	}

	u1 := NewV1()
	u2 := NewV1()

	if Equal(u1, u2) {
		t.Errorf("UUIDv1 generated two equal UUIDs: %s and %s", u1, u2)
	}

	oldFunc := epochFunc
	epochFunc = func() uint64 { return 0 }

	u3 := NewV1()
	u4 := NewV1()

	if Equal(u3, u4) {
		t.Errorf("UUIDv1 generated two equal UUIDs: %s and %s", u3, u4)
	}

	epochFunc = oldFunc
}

func TestNewV2(t *testing.T) {
	u1 := NewV2(DomainPerson)

	if u1.Version() != 2 {
		t.Errorf("UUIDv2 generated with incorrect version: %d", u1.Version())
	}

	if u1.Variant() != VariantRFC4122 {
		t.Errorf("UUIDv2 generated with incorrect variant: %d", u1.Variant())
	}

	u2 := NewV2(DomainGroup)

	if u2.Version() != 2 {
		t.Errorf("UUIDv2 generated with incorrect version: %d", u2.Version())
	}

	if u2.Variant() != VariantRFC4122 {
		t.Errorf("UUIDv2 generated with incorrect variant: %d", u2.Variant())
	}
}

func TestNewV3(t *testing.T) {
	u := NewV3(NamespaceDNS, "www.example.com")

	if u.Version() != 3 {
		t.Errorf("UUIDv3 generated with incorrect version: %d", u.Version())
	}

	if u.Variant() != VariantRFC4122 {
		t.Errorf("UUIDv3 generated with incorrect variant: %d", u.Variant())
	}

	if u.String() != "5df41881-3aed-3515-88a7-2f4a814cf09e" {
		t.Errorf("UUIDv3 generated incorrectly: %s", u.String())
	}

	u = NewV3(NamespaceDNS, "python.org")

	if u.String() != "6fa459ea-ee8a-3ca4-894e-db77e160355e" {
		t.Errorf("UUIDv3 generated incorrectly: %s", u.String())
	}

	u1 := NewV3(NamespaceDNS, "golang.org")
	u2 := NewV3(NamespaceDNS, "golang.org")
	if !Equal(u1, u2) {
		t.Errorf("UUIDv3 generated different UUIDs for same namespace and name: %s and %s", u1, u2)
	}

	u3 := NewV3(NamespaceDNS, "example.com")
	if Equal(u1, u3) {
		t.Errorf("UUIDv3 generated same UUIDs for different names in same namespace: %s and %s", u1, u2)
	}

	u4 := NewV3(NamespaceURL, "golang.org")
	if Equal(u1, u4) {
		t.Errorf("UUIDv3 generated same UUIDs for sane names in different namespaces: %s and %s", u1, u4)
	}
}

func TestNewV4(t *testing.T) {
	u := NewV4()

	if u.Version() != 4 {
		t.Errorf("UUIDv4 generated with incorrect version: %d", u.Version())
	}

	if u.Variant() != VariantRFC4122 {
		t.Errorf("UUIDv4 generated with incorrect variant: %d", u.Variant())
	}
}

func TestNewV5(t *testing.T) {
	u := NewV5(NamespaceDNS, "www.example.com")

	if u.Version() != 5 {
		t.Errorf("UUIDv5 generated with incorrect version: %d", u.Version())
	}

	if u.Variant() != VariantRFC4122 {
		t.Errorf("UUIDv5 generated with incorrect variant: %d", u.Variant())
	}

	u = NewV5(NamespaceDNS, "python.org")

	if u.String() != "886313e1-3b8a-5372-9b90-0c9aee199e5d" {
		t.Errorf("UUIDv5 generated incorrectly: %s", u.String())
	}

	u1 := NewV5(NamespaceDNS, "golang.org")
	u2 := NewV5(NamespaceDNS, "golang.org")
	if !Equal(u1, u2) {
		t.Errorf("UUIDv5 generated different UUIDs for same namespace and name: %s and %s", u1, u2)
	}

	u3 := NewV5(NamespaceDNS, "example.com")
	if Equal(u1, u3) {
		t.Errorf("UUIDv5 generated same UUIDs for different names in same namespace: %s and %s", u1, u2)
	}

	u4 := NewV5(NamespaceURL, "golang.org")
	if Equal(u1, u4) {
		t.Errorf("UUIDv3 generated same UUIDs for sane names in different namespaces: %s and %s", u1, u4)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"html/template"
	"io/ioutil"
	"os"
	"os/exec"
	"regexp"
	"strings"
	"sync"
	"time"

	"github.com/fatih/color"

	"golang.org/x/crypto/ssh/terminal"
	yaml "gopkg.in/yaml.v2"
)

type marvin struct {
	Config struct {
		Relative  bool   `yaml:"relative"`
		Delemiter string `yaml:"delemiter"`
	}
	Tasks     map[string]string `yaml:"tasks"`
	Inventory struct {
		static    []map[string]string
		StaticRaw string            `yaml:"static"`
		Dynamic   map[string]string `yaml:"dynamic"`
	} `yaml:"inventory"`
	filtered []map[string]string
	lock     *sync.Mutex
}

func newMarvin(config, currentDirectory, query, task, args string) *marvin {
	m := &marvin{
		lock: &sync.Mutex{},
	}

	// set configuration defaults
	m.setConfigDefaults()

	// set task defaults
	m.setTaskDefaults()

	// set some default dynamic inventory
	m.setDynamicInventoryDefaults()

	err := yaml.Unmarshal([]byte(config), &m)
	if err != nil {
		speak(err.Error(), false)
		speak("marvin.yml> invalid", true)
	}

	if m.Config.Relative {
		os.Chdir(currentDirectory)
	}

	// stdin to static inventory
	if !terminal.IsTerminal(0) {
		stdin, _ := ioutil.ReadAll(os.Stdin)
		m.Inventory.StaticRaw += "\n" + string(stdin)
	}

	m.filter(query)

	if len(m.filtered) == 0 {
		speak("inventory> none matched your criteria", true)
	}
	m.task(task, args)
	return m
}

func (m *marvin) rawToInventory(raw string) []map[string]string {
	inventory := make([]map[string]string, 0)
	// convert strings to actual inventory
	for _, iRecord := range strings.Split(strings.TrimSpace(m.Inventory.StaticRaw), "\n") {
		for _, row := range strings.Split(iRecord, "\n") {
			i := make(map[string]string)
			if row == "" {
				continue
			}
			for id, kvs := range strings.Split(row, m.Config.Delemiter) {
				kv := strings.SplitN(kvs, ":", 2)
				if len(kv) == 1 {
					i["id"] = kv[0]
				} else {
					i[kv[0]] = strings.Join(kv[1:], m.Config.Delemiter)
					// always set an id
					if id == 0 {
						i["id"] = i[kv[0]]
					}
				}

				// regardless, lets add a raw
				i["raw"] = row
			}

			// add the inventory
			inventory = append(inventory, i)
		}
	}
	m.Inventory.static = inventory
	return m.Inventory.static
}

func (m *marvin) filter(queryString string) []map[string]string {
	var sKey, sValue string
	// kiss for now, replace * with .* and then regex match
	filtered := make([]map[string]string, 0)
	// figure out what we are searching for.
	q := strings.Split(queryString, ":")
	if len(q) == 2 {
		sKey, sValue = q[0], q[1]
		if sKey == "" {
			sKey = "id"
		}
		if sValue == "" {
			sValue = "*"
		}
	} else {
		sKey, sValue = "id", q[0]
	}

	if dynamicCmd, dynamicCmdExists := m.Inventory.Dynamic[sKey]; dynamicCmdExists {
		dInventoryOutput, dInventoryError := m.exec(dynamicCmd)
		if dInventoryError == nil && strings.TrimSpace(dInventoryOutput) != "" {
			// if no errors, add it
			m.lock.Lock()
			m.Inventory.StaticRaw += "\n"
			m.lock.Unlock()
			for _, row := range strings.Split(dInventoryOutput, "\n") {
				// add each record, with the inventory name
				m.lock.Lock()
				m.Inventory.StaticRaw += sKey + ":" + row + "\n"
				m.lock.Unlock()
			}
		}
	}

	var wg sync.WaitGroup
	if sKey == "id" || sKey == "raw" {
		// sigh, we need to generate ALL inventory because we just don't know
		for dInventoryName, dInventoryCmd := range m.Inventory.Dynamic {
			wg.Add(1)
			go func(dInventoryCmd, dInventoryName string) {
				m.lock.Lock()
				m.Inventory.StaticRaw += "\n"
				m.lock.Unlock()
				if dInventoryOutput, dInventoryError := m.exec(dInventoryCmd); dInventoryError == nil && strings.TrimSpace(dInventoryOutput) != "" {
					// no errors, sweet
					for _, row := range strings.Split(dInventoryOutput, "\n") {
						if row == "" {
							continue
						}
						// add each record, with the inventory name
						m.lock.Lock()
						m.Inventory.StaticRaw += dInventoryName + ":" + row + "\n"
						m.lock.Unlock()
					}
				}
				wg.Done()
			}(dInventoryCmd, dInventoryName)
		}
		wg.Wait()
	}

	// inventory should now be set ...
	m.rawToInventory(m.Inventory.StaticRaw)

	// replace
	sKey = strings.Replace(sKey, "*", ".*", -1)
	sValue = strings.Replace(sValue, "*", ".*", -1)

	for _, i := range m.Inventory.static {
		for k, v := range i {
			keyMatch, _ := regexp.MatchString(sKey, k)
			valueMatch, _ := regexp.MatchString(sValue, v)
			if keyMatch && valueMatch {
				filtered = append(filtered, i)
			}
		}
	}
	m.filtered = filtered
	return filtered
}

func (m *marvin) task(taskName, args string) {
	rawTask, exists := m.Tasks[taskName]
	var wg sync.WaitGroup
	if !exists {
		rawTask = "sh -c '" + taskName + " " + args + "'"
	}

	// first lets do an inventory check
	rawCommands := m.inventoryCheck(rawTask, m.filtered, args)

	// sweet, moving along
	// TODO: we are just going to spin them all up(we will figure out batching later)
	for cmdID, command := range rawCommands {
		wg.Add(1)
		go func(cmdID, command string) {

			output, execError := m.exec(command)

			// hopefully only one line :fingers_crossed
			if len(strings.Split(output, "\n")) > 1 {
				output = "\n" + output
			}

			if execError != nil {
				color.Red(cmdID + "> " + output)
			} else {
				color.Green(cmdID + "> " + output)
			}
			wg.Done()
		}(cmdID, command)
	}
	wg.Wait()
}

func (m *marvin) inventoryCheck(task string, filtered []map[string]string, args string) map[string]string {
	task = strings.Replace(task, "<", "<", -1)
	rawCommands := make(map[string]string, 0)
	for _, inventory := range filtered {
		// add defaults to filtered inventory
		inventory["args"] = args
		inventory["time"] = time.Now().String()
		cmd, cmdParseError := m.template(task, inventory)
		if cmdParseError != nil {
			speak(inventory["id"]+"> missing/invalid arguments", true)
		}
		rawCommands[inventory["id"]] = cmd
	}
	return rawCommands
}

func (m *marvin) template(task string, inventory map[string]string) (string, error) {
	template := template.Must(template.New("translate").Parse(task))
	b := new(bytes.Buffer)
	err := template.Execute(b, inventory)
	if err == nil {
		return b.String(), nil
	}
	return "", fmt.Errorf("id: " + inventory["id"])
}

func (m *marvin) exec(command string) (string, error) {
	cmd := exec.Command("sh", "-c", command)
	execOutput, execError := cmd.CombinedOutput()
	output := strings.TrimSpace(string(execOutput))
	output = strings.Trim(output, "\r\n")
	return output, execError
}

func (m *marvin) setDynamicInventoryDefaults() {
	m.Inventory.Dynamic = make(map[string]string)

	m.Inventory.Dynamic["file"] = "ls -R -1"
	m.Inventory.Dynamic["dir"] = "ls -d */ | cut -f1 -d'/'"
	m.Inventory.Dynamic["branch"] = "git branch | cut -c 3-"
	m.Inventory.Dynamic["docker"] = "docker ps --format \"{{ .Names }}\""
	m.Inventory.Dynamic["bookmark"] = `cat ~/Library/Application\ Support/Google/Chrome/Default/Bookmarks | grep -i http | sed "s/ //g" | sed "s/\"//g" | sed "s/url://g"`
	m.Inventory.Dynamic["ec2"] = `aws ec2 describe-instances --output=text | grep "TAGS$(printf '\t')Name" | grep -v " " | sed "s/TAGS$(printf '\t')Name$(printf '\t')//g"`
}

func (m *marvin) setTaskDefaults() {
	m.Tasks = make(map[string]string)
	// set default tasks
	m.Tasks["ssh"] = "ssh {{ .host }} {{ .args }}"
	m.Tasks["ls"] = "echo {{ .raw }}"
	m.Tasks["open"] = "open {{ .id }} && echo opening"
}

func (m *marvin) setConfigDefaults() {
	// delemiter
	m.Config.Delemiter = " "

	// relative?
	m.Config.Relative = true
}
<commit_msg>Added 'sh' to default tasks<commit_after>package main

import (
	"bytes"
	"fmt"
	"html/template"
	"io/ioutil"
	"os"
	"os/exec"
	"regexp"
	"strings"
	"sync"
	"time"

	"github.com/fatih/color"

	"golang.org/x/crypto/ssh/terminal"
	yaml "gopkg.in/yaml.v2"
)

type marvin struct {
	Config struct {
		Relative  bool   `yaml:"relative"`
		Delemiter string `yaml:"delemiter"`
	}
	Tasks     map[string]string `yaml:"tasks"`
	Inventory struct {
		static    []map[string]string
		StaticRaw string            `yaml:"static"`
		Dynamic   map[string]string `yaml:"dynamic"`
	} `yaml:"inventory"`
	filtered []map[string]string
	lock     *sync.Mutex
}

func newMarvin(config, currentDirectory, query, task, args string) *marvin {
	m := &marvin{
		lock: &sync.Mutex{},
	}

	// set configuration defaults
	m.setConfigDefaults()

	// set task defaults
	m.setTaskDefaults()

	// set some default dynamic inventory
	m.setDynamicInventoryDefaults()

	err := yaml.Unmarshal([]byte(config), &m)
	if err != nil {
		speak(err.Error(), false)
		speak("marvin.yml> invalid", true)
	}

	if m.Config.Relative {
		os.Chdir(currentDirectory)
	}

	// stdin to static inventory
	if !terminal.IsTerminal(0) {
		stdin, _ := ioutil.ReadAll(os.Stdin)
		m.Inventory.StaticRaw += "\n" + string(stdin)
	}

	m.filter(query)

	if len(m.filtered) == 0 {
		speak("inventory> none matched your criteria", true)
	}
	m.task(task, args)
	return m
}

func (m *marvin) rawToInventory(raw string) []map[string]string {
	inventory := make([]map[string]string, 0)
	// convert strings to actual inventory
	for _, iRecord := range strings.Split(strings.TrimSpace(m.Inventory.StaticRaw), "\n") {
		for _, row := range strings.Split(iRecord, "\n") {
			i := make(map[string]string)
			if row == "" {
				continue
			}
			for id, kvs := range strings.Split(row, m.Config.Delemiter) {
				kv := strings.SplitN(kvs, ":", 2)
				if len(kv) == 1 {
					i["id"] = kv[0]
				} else {
					i[kv[0]] = strings.Join(kv[1:], m.Config.Delemiter)
					// always set an id
					if id == 0 {
						i["id"] = i[kv[0]]
					}
				}

				// regardless, lets add a raw
				i["raw"] = row
			}

			// add the inventory
			inventory = append(inventory, i)
		}
	}
	m.Inventory.static = inventory
	return m.Inventory.static
}

func (m *marvin) filter(queryString string) []map[string]string {
	var sKey, sValue string
	// kiss for now, replace * with .* and then regex match
	filtered := make([]map[string]string, 0)
	// figure out what we are searching for.
	q := strings.Split(queryString, ":")
	if len(q) == 2 {
		sKey, sValue = q[0], q[1]
		if sKey == "" {
			sKey = "id"
		}
		if sValue == "" {
			sValue = "*"
		}
	} else {
		sKey, sValue = "id", q[0]
	}

	if dynamicCmd, dynamicCmdExists := m.Inventory.Dynamic[sKey]; dynamicCmdExists {
		dInventoryOutput, dInventoryError := m.exec(dynamicCmd)
		if dInventoryError == nil && strings.TrimSpace(dInventoryOutput) != "" {
			// if no errors, add it
			m.lock.Lock()
			m.Inventory.StaticRaw += "\n"
			m.lock.Unlock()
			for _, row := range strings.Split(dInventoryOutput, "\n") {
				// add each record, with the inventory name
				m.lock.Lock()
				m.Inventory.StaticRaw += sKey + ":" + row + "\n"
				m.lock.Unlock()
			}
		}
	}

	var wg sync.WaitGroup
	if sKey == "id" || sKey == "raw" {
		// sigh, we need to generate ALL inventory because we just don't know
		for dInventoryName, dInventoryCmd := range m.Inventory.Dynamic {
			wg.Add(1)
			go func(dInventoryCmd, dInventoryName string) {
				m.lock.Lock()
				m.Inventory.StaticRaw += "\n"
				m.lock.Unlock()
				if dInventoryOutput, dInventoryError := m.exec(dInventoryCmd); dInventoryError == nil && strings.TrimSpace(dInventoryOutput) != "" {
					// no errors, sweet
					for _, row := range strings.Split(dInventoryOutput, "\n") {
						if row == "" {
							continue
						}
						// add each record, with the inventory name
						m.lock.Lock()
						m.Inventory.StaticRaw += dInventoryName + ":" + row + "\n"
						m.lock.Unlock()
					}
				}
				wg.Done()
			}(dInventoryCmd, dInventoryName)
		}
		wg.Wait()
	}

	// inventory should now be set ...
	m.rawToInventory(m.Inventory.StaticRaw)

	// replace
	sKey = strings.Replace(sKey, "*", ".*", -1)
	sValue = strings.Replace(sValue, "*", ".*", -1)

	for _, i := range m.Inventory.static {
		for k, v := range i {
			keyMatch, _ := regexp.MatchString(sKey, k)
			valueMatch, _ := regexp.MatchString(sValue, v)
			if keyMatch && valueMatch {
				filtered = append(filtered, i)
			}
		}
	}
	m.filtered = filtered
	return filtered
}

func (m *marvin) task(taskName, args string) {
	rawTask, exists := m.Tasks[taskName]
	var wg sync.WaitGroup
	if !exists {
		rawTask = "sh -c '" + taskName + " " + args + "'"
	}

	// first lets do an inventory check
	rawCommands := m.inventoryCheck(rawTask, m.filtered, args)

	// sweet, moving along
	// TODO: we are just going to spin them all up(we will figure out batching later)
	for cmdID, command := range rawCommands {
		wg.Add(1)
		go func(cmdID, command string) {

			output, execError := m.exec(command)

			// hopefully only one line :fingers_crossed
			if len(strings.Split(output, "\n")) > 1 {
				output = "\n" + output
			}

			if execError != nil {
				color.Red(cmdID + "> " + output)
			} else {
				color.Green(cmdID + "> " + output)
			}
			wg.Done()
		}(cmdID, command)
	}
	wg.Wait()
}

func (m *marvin) inventoryCheck(task string, filtered []map[string]string, args string) map[string]string {
	task = strings.Replace(task, "<", "<", -1)
	rawCommands := make(map[string]string, 0)
	for _, inventory := range filtered {
		// add defaults to filtered inventory
		inventory["args"] = args
		inventory["time"] = time.Now().String()
		cmd, cmdParseError := m.template(task, inventory)
		if cmdParseError != nil {
			speak(inventory["id"]+"> missing/invalid arguments", true)
		}
		rawCommands[inventory["id"]] = cmd
	}
	return rawCommands
}

func (m *marvin) template(task string, inventory map[string]string) (string, error) {
	template := template.Must(template.New("translate").Parse(task))
	b := new(bytes.Buffer)
	err := template.Execute(b, inventory)
	if err == nil {
		return b.String(), nil
	}
	return "", fmt.Errorf("id: " + inventory["id"])
}

func (m *marvin) exec(command string) (string, error) {
	cmd := exec.Command("sh", "-c", command)
	execOutput, execError := cmd.CombinedOutput()
	output := strings.TrimSpace(string(execOutput))
	output = strings.Trim(output, "\r\n")
	return output, execError
}

func (m *marvin) setDynamicInventoryDefaults() {
	m.Inventory.Dynamic = make(map[string]string)

	m.Inventory.Dynamic["file"] = "ls -R -1"
	m.Inventory.Dynamic["dir"] = "ls -d */ | cut -f1 -d'/'"
	m.Inventory.Dynamic["branch"] = "git branch | cut -c 3-"
	m.Inventory.Dynamic["docker"] = "docker ps --format \"{{ .Names }}\""
	m.Inventory.Dynamic["bookmark"] = `cat ~/Library/Application\ Support/Google/Chrome/Default/Bookmarks | grep -i http | sed "s/ //g" | sed "s/\"//g" | sed "s/url://g"`
	m.Inventory.Dynamic["ec2"] = `aws ec2 describe-instances --output=text | grep "TAGS$(printf '\t')Name" | grep -v " " | sed "s/TAGS$(printf '\t')Name$(printf '\t')//g"`
}

func (m *marvin) setTaskDefaults() {
	m.Tasks = make(map[string]string)
	// set default tasks
	m.Tasks["ssh"] = "ssh {{ .host }} {{ .args }}"
	m.Tasks["ls"] = "echo {{ .raw }}"
	m.Tasks["open"] = "open {{ .id }} && echo opening"
	m.Tasks["sh"] = "sh -c \"{{ .args }}\""
}

func (m *marvin) setConfigDefaults() {
	// delemiter
	m.Config.Delemiter = " "

	// relative?
	m.Config.Relative = true
}
<|endoftext|>


<commit_before>package mathgl

import (
	"errors"
)

type Matrix struct {
	m,n int // an m x n matrix
	typ VecType
	dat []VecNum
}

func NewMatrix(m,n int, typ VecType) *Matrix {
	return &Matrix{m:m, n:n, typ: typ, dat: make([]VecNum,0,2) }
}

// [1, 1]
// [0, 1] Would be entered as a 2D array [[1,1],[0,1]] -- but converted to RMO
//
// This may seem confusing, but it's because it's easier to type out and visualize things in CMO
// So it's easier to type write your matrix as a slice in CMO, and pass it into this method
func MatrixOf(typ VecType, el [][]VecNum) (mat *Matrix, err error) {
	mat.typ = typ

	mat.m = len(el)
	mat.n = len(el[0])
	mat.dat = make([]VecNum, 0, mat.m * mat.n)

	// Row Major Order, like in OpenGL
	for i := 0; i < mat.n; i++ {
		for j := 0; j < mat.m; j++ {
			if !checkType(mat.typ, el[j][i]) {
				return nil, errors.New("Element type does not match matrix")
			}
			mat.dat = append(mat.dat, el[j][i])
		}
	}

	return mat, nil
}

// Slice-format data should be in Row Major Order
func MatrixFromSlice(typ VecType, el []VecNum, m,n int) (mat *Matrix, err error) {
	mat.typ = typ
	mat.m = m
	mat.n = n

	if mat.m * mat.n != len(el) {
		return nil, errors.New("Matrix dimensions do not match data passed in")
	}

	for _,e := range el {
		if !checkType(mat.typ, e) {
			return nil, errors.New("Type of at least one element does not match declared type")
		}
	}

	mat.dat = el

	return mat,nil
}

// Quick and dirty internal function to make a matrix without spending time checking types
func unsafeMatrixFromSlice(typ VecType, el []VecNum, m,n int) (mat *Matrix, err error) {
	mat.typ = typ
	mat.m = m
	mat.n = n

	/*if mat.m * mat.n != len(el) {
		return nil, errors.New("Matrix dimensions do not match data passed in")
	}

	for _,e := range el {
		if !checkType(mat.typ, e) {
			return nil, errors.New("Type of at least one element does not match declared type")
		}
	}*/

	mat.dat = el

	return mat,nil
}

// TODO: "Add" or "Append" data method

func (mat *Matrix) SetElement(i, j int, el VecNum) error {
	if i < mat.m || j < mat.n {
		return errors.New("Dimensions out of bounds")
	}

	if !checkType(mat.typ, el) {
		return errors.New("Type of element does not match matrix's type")
	}

	mat.dat[mat.m * j + i] = el

	return nil
}

func (mat Matrix) AsVector() (v Vector, err error) {
	if mat.m != 1 && mat.n != 1 {
		return v, errors.New("Matrix is not 1-dimensional in either direction.")
	}

	vPoint,err := VectorOf(mat.typ, mat.dat)
	if err != nil {
		return v, err
	}

	return *vPoint, nil
}

func (mat Matrix) ToScalar() VecNum {
	if mat.m != 1 || mat.n != 1 {
		return nil
	}

	/*switch mat.typ {
	case INT32:
		return mat.dat[0].(int32)
	case UINT32:
		return mat.dat[0].(uint32)
	case FLOAT32:
		return mat.dat[0].(float32)
	case FLOAT64:
		return mat.dat[0].(float64)
	}*/

	return mat.dat[0]
}

func (m1 Matrix) Add(m2 Matrix) (m3 Matrix) {
	if m1.typ != m2.typ || len(m1.dat) != len(m2.dat) {
		return
	}

	m3.typ = m1.typ
	m3.dat = make([]VecNum, len(m1.dat))

	for i := range m1.dat {
		m3.dat[i] = m1.dat[i].add(m2.dat[i])
		/*switch m1.typ {
		case INT32:
			m3.dat[i] = m1.dat[i].(int32) + m2.dat[i].(int32)
		case UINT32:
			m3.dat[i] = m1.dat[i].(uint32) + m2.dat[i].(uint32)
		case FLOAT32:
			m3.dat[i] = m1.dat[i].(float32) + m2.dat[i].(float32)
		case FLOAT64:
			m3.dat[i] = m1.dat[i].(float64) + m2.dat[i].(float64)
		}*/
	}

	return m3
}

func (m1 Matrix) Sub(m2 Matrix) (m3 Matrix) {
	if m1.typ != m2.typ || len(m1.dat) != len(m2.dat) {
		return
	}

	m3.typ = m1.typ
	m3.dat = make([]VecNum, len(m1.dat))

	for i := range m1.dat {
		m3.dat[i] = m1.dat[i].sub(m2.dat[i])
		/*switch m1.typ {
		case INT32:
			m3.dat[i] = m1.dat[i].(int32) - m2.dat[i].(int32)
		case UINT32:
			m3.dat[i] = m1.dat[i].(uint32) - m2.dat[i].(uint32)
		case FLOAT32:
			m3.dat[i] = m1.dat[i].(float32) - m2.dat[i].(float32)
		case FLOAT64:
			m3.dat[i] = m1.dat[i].(float64) - m2.dat[i].(float64)
		}*/
	}

	return m3
}

func (m1 Matrix) Mul(m2 Matrix) (m3 Matrix) {
	if m1.n != m2.m || m1.typ != m2.typ {
		return
	}
	dat := make([]VecNum, m1.m * m2.n)

	for j := 0; j < m2.n; j++ { // Columns of m2 and m3
		for i := 0; i < m1.m; i++ { // Rows of m1 and m3
			for k := 0; k < m1.n; k++ { // Columns of m1, rows of m2
				dat[j * m2.n + i] = dat[j * m2.n + i].add(m1.dat[k * m1.n + i].mul(m2.dat[j * m2.n + k])) // I think, needs testing
			}
		}
	}
	/*switch m1.typ {
	case INT32:
		for j := 0; j < m2.n; j++ { // Columns of m2 and m3
			for i := 0; i < m1.m; i++ { // Rows of m1 and m3
				for k := 0; k < m1.n; k++ { // Columns of m1, rows of m2
					dat[j * m2.n + i] = dat[j * m2.n + i].(int32) + m1.dat[k * m1.n + i].(int32) * m2.dat[j * m2.n + k].(int32) // I think, needs testing
				}
			}
		}
	case UINT32:
		for j := 0; j < m2.n; j++ { // Columns of m2 and m3
			for i := 0; i < m1.m; i++ { // Rows of m1 and m3
				for k := 0; k < m1.n; k++ { // Columns of m1, rows of m2
					dat[j * m2.n + i] = dat[j * m2.n + i].(uint32) + m1.dat[k * m1.n + i].(uint32) * m2.dat[j * m2.n + k].(uint32) // I think, needs testing
				}
			}
		}
	case FLOAT32:
		for j := 0; j < m2.n; j++ { // Columns of m2 and m3
			for i := 0; i < m1.m; i++ { // Rows of m1 and m3
				for k := 0; k < m1.n; k++ { // Columns of m1, rows of m2
					dat[j * m2.n + i] = dat[j * m2.n + i].(float32) + m1.dat[k * m1.n + i].(float32) * m2.dat[j * m2.n + k].(float32) // I think, needs testing
				}
			}
		}
	case FLOAT64:
		for j := 0; j < m2.n; j++ { // Columns of m2 and m3
			for i := 0; i < m1.m; i++ { // Rows of m1 and m3
				for k := 0; k < m1.n; k++ { // Columns of m1, rows of m2
					dat[j * m2.n + i] = dat[j * m2.n + i].(float64) + m1.dat[k * m1.n + i].(float64) * m2.dat[j * m2.n + k].(float64) // I think, needs testing
				}
			}
		}
	}*/

	mat,err := unsafeMatrixFromSlice(m1.typ, dat, m1.m, m2.n)
	if err != nil {
		return
	}

	return *mat
}

// INCOMPLETE DO NOT USE
// Need better function to make matrices for recursion
func (m1 Matrix) Det() interface{} {
	if m1.m != m1.n { // Determinants are only for square matrices
		return nil
	}

	return nil
}<commit_msg>Added support for building a matrix out of row vectors<commit_after>package mathgl

import (
	"errors"
)

type Matrix struct {
	m,n int // an m x n matrix
	typ VecType
	dat []VecNum
}

func NewMatrix(m,n int, typ VecType) *Matrix {
	return &Matrix{m:m, n:n, typ: typ, dat: make([]VecNum,0,2) }
}

// [1, 1]
// [0, 1] Would be entered as a 2D array [[1,1],[0,1]] -- but converted to RMO
//
// This may seem confusing, but it's because it's easier to type out and visualize things in CMO
// So it's easier to type write your matrix as a slice in CMO, and pass it into this method
func MatrixFromCols(typ VecType, el [][]VecNum) (mat *Matrix, err error) {
	mat.typ = typ

	mat.m = len(el)
	mat.n = len(el[0])
	mat.dat = make([]VecNum, 0, mat.m * mat.n)

	// Row Major Order, like in OpenGL
	for i := 0; i < mat.n; i++ {
		for j := 0; j < mat.m; j++ {
			if !checkType(mat.typ, el[j][i]) {
				return nil, errors.New("Element type does not match matrix")
			}
			mat.dat = append(mat.dat, el[j][i])
		}
	}

	return mat, nil
}

// This function is MatrixOf, except it takes a list of row "vectors" instead of row "vectors" (really slices)
func MatrixFromRows(typ VecType, el [][]VecNum) (mat *Matrix, err error) {
	mat.typ = typ

	mat.m = len(el)
	mat.n = len(el[0])
	mat.dat = make([]VecNum, 0, mat.m * mat.n)

	// Row Major Order, like in OpenGL
	for i := 0; i < mat.m; i++ {
		for j := 0; j < mat.n; j++ {
			if !checkType(mat.typ, el[j][i]) {
				return nil, errors.New("Element type does not match matrix")
			}
			mat.dat = append(mat.dat, el[j][i])
		}
	}

	return mat, nil
}

// Slice-format data should be in Row Major Order
func MatrixFromSlice(typ VecType, el []VecNum, m,n int) (mat *Matrix, err error) {
	mat.typ = typ
	mat.m = m
	mat.n = n

	if mat.m * mat.n != len(el) {
		return nil, errors.New("Matrix dimensions do not match data passed in")
	}

	for _,e := range el {
		if !checkType(mat.typ, e) {
			return nil, errors.New("Type of at least one element does not match declared type")
		}
	}

	mat.dat = el

	return mat,nil
}

// Quick and dirty internal function to make a matrix without spending time checking types
func unsafeMatrixFromSlice(typ VecType, el []VecNum, m,n int) (mat *Matrix, err error) {
	mat.typ = typ
	mat.m = m
	mat.n = n

	/*if mat.m * mat.n != len(el) {
		return nil, errors.New("Matrix dimensions do not match data passed in")
	}

	for _,e := range el {
		if !checkType(mat.typ, e) {
			return nil, errors.New("Type of at least one element does not match declared type")
		}
	}*/

	mat.dat = el

	return mat,nil
}

// TODO: "Add" or "Append" data method

func (mat *Matrix) SetElement(i, j int, el VecNum) error {
	if i < mat.m || j < mat.n {
		return errors.New("Dimensions out of bounds")
	}

	if !checkType(mat.typ, el) {
		return errors.New("Type of element does not match matrix's type")
	}

	mat.dat[mat.m * j + i] = el

	return nil
}

func (mat Matrix) AsVector() (v Vector, err error) {
	if mat.m != 1 && mat.n != 1 {
		return v, errors.New("Matrix is not 1-dimensional in either direction.")
	}

	vPoint,err := VectorOf(mat.typ, mat.dat)
	if err != nil {
		return v, err
	}

	return *vPoint, nil
}

func (mat Matrix) ToScalar() VecNum {
	if mat.m != 1 || mat.n != 1 {
		return nil
	}

	/*switch mat.typ {
	case INT32:
		return mat.dat[0].(int32)
	case UINT32:
		return mat.dat[0].(uint32)
	case FLOAT32:
		return mat.dat[0].(float32)
	case FLOAT64:
		return mat.dat[0].(float64)
	}*/

	return mat.dat[0]
}

func (m1 Matrix) Add(m2 Matrix) (m3 Matrix) {
	if m1.typ != m2.typ || len(m1.dat) != len(m2.dat) {
		return
	}

	m3.typ = m1.typ
	m3.dat = make([]VecNum, len(m1.dat))

	for i := range m1.dat {
		m3.dat[i] = m1.dat[i].add(m2.dat[i])
		/*switch m1.typ {
		case INT32:
			m3.dat[i] = m1.dat[i].(int32) + m2.dat[i].(int32)
		case UINT32:
			m3.dat[i] = m1.dat[i].(uint32) + m2.dat[i].(uint32)
		case FLOAT32:
			m3.dat[i] = m1.dat[i].(float32) + m2.dat[i].(float32)
		case FLOAT64:
			m3.dat[i] = m1.dat[i].(float64) + m2.dat[i].(float64)
		}*/
	}

	return m3
}

func (m1 Matrix) Sub(m2 Matrix) (m3 Matrix) {
	if m1.typ != m2.typ || len(m1.dat) != len(m2.dat) {
		return
	}

	m3.typ = m1.typ
	m3.dat = make([]VecNum, len(m1.dat))

	for i := range m1.dat {
		m3.dat[i] = m1.dat[i].sub(m2.dat[i])
		/*switch m1.typ {
		case INT32:
			m3.dat[i] = m1.dat[i].(int32) - m2.dat[i].(int32)
		case UINT32:
			m3.dat[i] = m1.dat[i].(uint32) - m2.dat[i].(uint32)
		case FLOAT32:
			m3.dat[i] = m1.dat[i].(float32) - m2.dat[i].(float32)
		case FLOAT64:
			m3.dat[i] = m1.dat[i].(float64) - m2.dat[i].(float64)
		}*/
	}

	return m3
}

func (m1 Matrix) Mul(m2 Matrix) (m3 Matrix) {
	if m1.n != m2.m || m1.typ != m2.typ {
		return
	}
	dat := make([]VecNum, m1.m * m2.n)

	for j := 0; j < m2.n; j++ { // Columns of m2 and m3
		for i := 0; i < m1.m; i++ { // Rows of m1 and m3
			for k := 0; k < m1.n; k++ { // Columns of m1, rows of m2
				dat[j * m2.n + i] = dat[j * m2.n + i].add(m1.dat[k * m1.n + i].mul(m2.dat[j * m2.n + k])) // I think, needs testing
			}
		}
	}
	/*switch m1.typ {
	case INT32:
		for j := 0; j < m2.n; j++ { // Columns of m2 and m3
			for i := 0; i < m1.m; i++ { // Rows of m1 and m3
				for k := 0; k < m1.n; k++ { // Columns of m1, rows of m2
					dat[j * m2.n + i] = dat[j * m2.n + i].(int32) + m1.dat[k * m1.n + i].(int32) * m2.dat[j * m2.n + k].(int32) // I think, needs testing
				}
			}
		}
	case UINT32:
		for j := 0; j < m2.n; j++ { // Columns of m2 and m3
			for i := 0; i < m1.m; i++ { // Rows of m1 and m3
				for k := 0; k < m1.n; k++ { // Columns of m1, rows of m2
					dat[j * m2.n + i] = dat[j * m2.n + i].(uint32) + m1.dat[k * m1.n + i].(uint32) * m2.dat[j * m2.n + k].(uint32) // I think, needs testing
				}
			}
		}
	case FLOAT32:
		for j := 0; j < m2.n; j++ { // Columns of m2 and m3
			for i := 0; i < m1.m; i++ { // Rows of m1 and m3
				for k := 0; k < m1.n; k++ { // Columns of m1, rows of m2
					dat[j * m2.n + i] = dat[j * m2.n + i].(float32) + m1.dat[k * m1.n + i].(float32) * m2.dat[j * m2.n + k].(float32) // I think, needs testing
				}
			}
		}
	case FLOAT64:
		for j := 0; j < m2.n; j++ { // Columns of m2 and m3
			for i := 0; i < m1.m; i++ { // Rows of m1 and m3
				for k := 0; k < m1.n; k++ { // Columns of m1, rows of m2
					dat[j * m2.n + i] = dat[j * m2.n + i].(float64) + m1.dat[k * m1.n + i].(float64) * m2.dat[j * m2.n + k].(float64) // I think, needs testing
				}
			}
		}
	}*/

	mat,err := unsafeMatrixFromSlice(m1.typ, dat, m1.m, m2.n)
	if err != nil {
		return
	}

	return *mat
}

// INCOMPLETE DO NOT USE
// Need better function to make matrices for recursion
func (m1 Matrix) Det() interface{} {
	if m1.m != m1.n { // Determinants are only for square matrices
		return nil
	}

	return nil
}<|endoftext|>