<commit_before>/*
 * Copyright (c) 2013 <NAME> <<EMAIL>>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package goapp

import (
	"appengine"
	"appengine/datastore"
	"appengine/memcache"
	"fmt"
	"github.com/mjibson/goon"
	"net/http"
)

func init() {
	http.HandleFunc("/", Main)
}

func Main(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	n := goon.NewGoon(r)

	// key tests

	noid := NoId{}
	if _, err := n.Key(noid); err == nil {
		fmt.Fprintln(w, "expected error on noid")
	}

	var keyTests = []keyTest{
		keyTest{
			HasId{Id: 1},
			datastore.NewKey(c, "HasId", "", 1, nil),
		},
		keyTest{
			HasKind{Id: 1, Kind: "OtherKind"},
			datastore.NewKey(c, "OtherKind", "", 1, nil),
		},
		keyTest{
			HasDefaultKind{Id: 1, Kind: "OtherKind"},
			datastore.NewKey(c, "OtherKind", "", 1, nil),
		},
		keyTest{
			HasDefaultKind{Id: 1},
			datastore.NewKey(c, "DefaultKind", "", 1, nil),
		},
	}

	for _, kt := range keyTests {
		if k, err := n.Key(kt.obj); err != nil {
			fmt.Fprintln(w, "error:", err.Error())
		} else if !k.Equal(kt.key) {
			fmt.Fprintln(w, "keys not equal")
		}
	}

	// datastore tests

	initTest(c)
	if err := n.Get(&HasId{Id: 0}); err == nil {
		fmt.Fprintln(w, "ds: expected error")
	}
	if err := n.Get(&HasId{Id: 1}); err != datastore.ErrNoSuchEntity {
		fmt.Fprintln(w, "ds: expected no such entity")
	}
	// run twice to make sure autocaching works correctly
	if err := n.Get(&HasId{Id: 1}); err != datastore.ErrNoSuchEntity {
		fmt.Fprintln(w, "ds: expected no such entity")
	}

	fmt.Fprintln(w, "done")
}

func initTest(c appengine.Context) {
	keys, _ := datastore.NewQuery("HasId").KeysOnly().GetAll(c, nil)
	datastore.DeleteMulti(c, keys)
	memcache.Flush(c)
}

type keyTest struct {
	obj interface{}
	key *datastore.Key
}

type NoId struct {
}

type HasId struct {
	Id   int64 `datastore:"-" goon:"id"`
	Name string
}

type HasKind struct {
	Id   int64  `datastore:"-" goon:"id"`<commit_msg>Get and Put tests<commit_after>/*
 * Copyright (c) 2013 <NAME> <<EMAIL>>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package goapp

import (
	"appengine"
	"appengine/datastore"
	"appengine/memcache"
	"fmt"
	"github.com/mjibson/goon"
	"net/http"
	"time"
)

func init() {
	http.HandleFunc("/", Main)
}

func Main(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	n := goon.NewGoon(r)

	// key tests

	noid := NoId{}
	if _, err := n.Key(noid); err == nil {
		fmt.Fprintln(w, "expected error on noid")
	}

	var keyTests = []keyTest{
		keyTest{
			HasId{Id: 1},
			datastore.NewKey(c, "HasId", "", 1, nil),
		},
		keyTest{
			HasKind{Id: 1, Kind: "OtherKind"},
			datastore.NewKey(c, "OtherKind", "", 1, nil),
		},
		keyTest{
			HasDefaultKind{Id: 1, Kind: "OtherKind"},
			datastore.NewKey(c, "OtherKind", "", 1, nil),
		},
		keyTest{
			HasDefaultKind{Id: 1},
			datastore.NewKey(c, "DefaultKind", "", 1, nil),
		},
	}

	for _, kt := range keyTests {
		if k, err := n.Key(kt.obj); err != nil {
			fmt.Fprintln(w, "error:", err.Error())
		} else if !k.Equal(kt.key) {
			fmt.Fprintln(w, "keys not equal")
		}
	}

	// datastore tests

	initTest(c)
	if err := n.Get(&HasId{Id: 0}); err == nil {
		fmt.Fprintln(w, "ds: expected error")
	}
	if err := n.Get(&HasId{Id: 1}); err != datastore.ErrNoSuchEntity {
		fmt.Fprintln(w, "ds: expected no such entity")
	}
	// run twice to make sure autocaching works correctly
	if err := n.Get(&HasId{Id: 1}); err != datastore.ErrNoSuchEntity {
		fmt.Fprintln(w, "ds: expected no such entity")
	}
	es := []*HasId{
		{Id: 1, Name: "one"},
		{Id: 2, Name: "two"},
	}
	nes := []*HasId{
		{Id: 1},
		{Id: 2},
	}
	if err := n.GetMulti(es); err == nil {
		fmt.Fprintln(w, "ds: expected error")
	} else if !goon.NotFound(err, 0) {
		fmt.Fprintln(w, "ds: not found error 0")
	} else if !goon.NotFound(err, 1) {
		fmt.Fprintln(w, "ds: not found error 1")
	} else if goon.NotFound(err, 2) {
		fmt.Fprintln(w, "ds: not found error 2")
	}
	if err := n.PutMulti(es); err != nil {
		fmt.Fprintln(w, "put: unexpected error")
	}
	if err := n.GetMulti(nes); err != nil {
		fmt.Fprintln(w, "put: unexpected error")
	} else if es[0] != nes[0] || es[1] != nes[1] {
		fmt.Fprintln(w, "put: bad results")
	} else {
		nesk0, _ := n.Key(nes[0])
		if !nesk0.Equal(datastore.NewKey(c, "HasId", "", 1, nil)) {
			fmt.Fprintln(w, "put: bad key")
		}
		nesk1, _ := n.Key(nes[1])
		if !nesk1.Equal(datastore.NewKey(c, "HasId", "", 2, nil)) {
			fmt.Fprintln(w, "put: bad key")
		}
	}
	// force partial fetch from memcache and then datastore
	memcache.Flush(c)
	if err := n.Get(nes[0]); err != nil {
		fmt.Fprintln(w, "get: unexpected error")
	}
	if err := n.GetMulti(nes); err != nil {
		fmt.Fprintln(w, "get: unexpected error")
	}

	fmt.Fprintln(w, "done", time.Now())
}

func initTest(c appengine.Context) {
	keys, _ := datastore.NewQuery("HasId").KeysOnly().GetAll(c, nil)
	datastore.DeleteMulti(c, keys)
	memcache.Flush(c)
}

type keyTest struct {
	obj interface{}
	key *datastore.Key
}

type NoId struct {
}

type HasId struct {
	Id   int64 `datastore:"-" goon:"id"`
	Name string
}

type HasKind struct {
	Id   int64  `datastore:"-" goon:"id"`
{'fraction_non_alphanumeric': 0.1577083012474973, 'fraction_numerical': 0.009394732789157555, 'mean_word_length': 3.7194767441860463, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6300192', 'n_tokens_mistral': 2622, 'n_tokens_neox': 2416, 'n_words': 717}