Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ _testmain.go
out/
release/
go-exercism

# Intellij
/.idea
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ go:
install: true

before_install:
go get github.com/codegangsta/cli && go get github.com/stretchr/testify/assert
bin/deps
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think go get -t ./... suffice here. It would fetch all dependencies for each package.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, probably. I'll pull this in and then tweak that in a branch to make sure it works.


script:
- go test ./...
39 changes: 37 additions & 2 deletions api/iteration.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
package api

import (
"bytes"
"errors"
"io/ioutil"
"path/filepath"
"strings"

"golang.org/x/net/html/charset"
"golang.org/x/text/transform"
)

const (
mimeType = "text/plain"
)

var (
errUnidentifiable = errors.New("unable to identify track and problem")
errNoFiles = errors.New("no files submitted")
utf8BOM = []byte{0xef, 0xbb, 0xbf}
)

// Iteration represents a version of a particular exercise.
Expand Down Expand Up @@ -53,12 +62,13 @@ func NewIteration(dir string, filenames []string) (*Iteration, error) {
iter.Problem = segments[2]

for _, filename := range filenames {
b, err := ioutil.ReadFile(filename)
fileContents, err := readFileAsUTF8String(filename)
if err != nil {
return nil, err
}

path := filename[len(iter.RelativePath()):]
iter.Solution[path] = string(b)
iter.Solution[path] = *fileContents
}
return iter, nil
}
Expand All @@ -73,3 +83,28 @@ func (iter *Iteration) isValidFilepath(path string) bool {
}
return strings.HasPrefix(strings.ToLower(path), strings.ToLower(iter.Dir))
}

func readFileAsUTF8String(filename string) (*string, error) {
b, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}

encoding, _, _ := charset.DetermineEncoding(b, mimeType)
decoder := encoding.NewDecoder()
decodedBytes, _, err := transform.Bytes(decoder, b)
if err != nil {
return nil, err
}

// Drop the UTF-8 BOM that may have been added. This isn't necessary, and
// it's going to be written into another UTF-8 buffer anyway once it's JSON
// serialized.
//
// The standard recommends omitting the BOM. See
// http://www.unicode.org/versions/Unicode5.0.0/ch02.pdf
decodedBytes = bytes.TrimPrefix(decodedBytes, utf8BOM)

s := string(decodedBytes)
return &s, nil
}
23 changes: 17 additions & 6 deletions api/iteration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package api
import (
"path/filepath"
"runtime"
"strings"
"testing"
"unicode/utf8"
)

func TestNewIteration(t *testing.T) {
Expand All @@ -14,6 +16,8 @@ func TestNewIteration(t *testing.T) {
filepath.Join(dir, "python", "leap", "one.py"),
filepath.Join(dir, "python", "leap", "two.py"),
filepath.Join(dir, "python", "leap", "lib", "three.py"),
filepath.Join(dir, "python", "leap", "utf16le.py"),
filepath.Join(dir, "python", "leap", "utf16be.py"),
}

iter, err := NewIteration(dir, files)
Expand All @@ -28,18 +32,25 @@ func TestNewIteration(t *testing.T) {
t.Errorf("Expected problem to be leap, was %s", iter.Problem)
}

if len(iter.Solution) != 3 {
if len(iter.Solution) != 5 {
t.Fatalf("Expected solution to have 3 files, had %d", len(iter.Solution))
}

expected := map[string]string{
"one.py": "# one\n",
"two.py": "# two\n",
"lib/three.py": "# three\n",
"one.py": "# one",
"two.py": "# two",
filepath.Join("lib", "three.py"): "# three",
"utf16le.py": "# utf16le",
"utf16be.py": "# utf16be",
}

for filename, code := range expected {
if iter.Solution[filename] != code {
t.Errorf("Expected %s to contain %s, had %s", filename, code, iter.Solution[filename])
if !utf8.ValidString(iter.Solution[filename]) {
t.Errorf("Iteration content is not valid UTF-8 data: %s", iter.Solution[filename])
}

if !strings.HasPrefix(iter.Solution[filename], code) {
t.Errorf("Expected %s to contain `%s', had `%s'", filename, code, iter.Solution[filename])
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions bin/deps
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

LIBRARIES="\
github.com/codegangsta/cli \
github.com/stretchr/testify/assert \
golang.org/x/net/html/charset \
golang.org/x/text/transform"

go get $LIBRARIES
Binary file added fixtures/iteration/python/leap/utf16be.py
Binary file not shown.
Binary file added fixtures/iteration/python/leap/utf16le.py
Binary file not shown.