<commit_before>// Copyright 2017 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package check

import (
	"bytes"
	"fmt"
	"math/big"
	"reflect"
	"sort"
	"strings"
	"testing"

	"github.com/google/wuffs/lang/builtin"
	"github.com/google/wuffs/lang/parse"
	"github.com/google/wuffs/lang/render"

	a "github.com/google/wuffs/lang/ast"
	t "github.com/google/wuffs/lang/token"
)

func compareToWuffsfmt(tm *t.Map, tokens []t.Token, comments []string, src string) error {
	buf := &bytes.Buffer{}
	if err := render.Render(buf, tm, tokens, comments); err != nil {
		return err
	}
	got := strings.Split(buf.String(), "\n")
	want := strings.Split(src, "\n")
	for line := 1; len(got) != 0 || len(want) != 0; line++ {
		if len(got) == 0 {
			w := strings.TrimSpace(want[0])
			return fmt.Errorf("difference at line %d:\n%s\n%s", line, "", w)
		}
		if len(want) == 0 {
			g := strings.TrimSpace(got[0])
			return fmt.Errorf("difference at line %d:\n%s\n%s", line, g, "")
		}
		if g, w := strings.TrimSpace(got[0]), strings.TrimSpace(want[0]); g != w {
			return fmt.Errorf("difference at line %d:\n%s\n%s", line, g, w)
		}
		got = got[1:]
		want = want[1:]
	}
	return nil
}

func TestCheck(tt *testing.T) {
	const filename = "test.wuffs"
	src := strings.TrimSpace(`
		pri struct foo(
			i : base.i32,
		)

		pri func foo.bar() {
			var x : base.u8
			var y : base.i32
			var z : base.u64[..= 123]
			var a : array[4] base.u8
			var b : base.bool

			var p : base.i32
			var q : base.i32[0 ..= 8]

			x = 0
			x = 1 + (x * 0)
			y = -y - 1
			y = this.i
			b = not true

			y = x as base.i32

			assert true

			while.label p == q,
				pre true,
				inv true,
				post p <> q,
			{
				// Redundant, but shows the labeled jump syntax.
				continue.label
			}
		}
	`) + "\n"

	tm := &t.Map{}

	tokens, comments, err := t.Tokenize(tm, filename, []byte(src))
	if err != nil {
		tt.Fatalf("Tokenize: %v", err)
	}

	file, err := parse.Parse(tm, filename, tokens, nil)
	if err != nil {
		tt.Fatalf("Parse: %v", err)
	}

	if err := compareToWuffsfmt(tm, tokens, comments, src); err != nil {
		tt.Fatalf("compareToWuffsfmt: %v", err)
	}

	c, err := Check(tm, []*a.File{file}, nil)
	if err != nil {
		tt.Fatalf("Check: %v", err)
	}

	// There are 2 funcs in this package: the implicit foo.reset method, and<commit_msg>Fix lang/check test for endwhile syntax<commit_after>// Copyright 2017 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package check

import (
	"bytes"
	"fmt"
	"math/big"
	"reflect"
	"sort"
	"strings"
	"testing"

	"github.com/google/wuffs/lang/builtin"
	"github.com/google/wuffs/lang/parse"
	"github.com/google/wuffs/lang/render"

	a "github.com/google/wuffs/lang/ast"
	t "github.com/google/wuffs/lang/token"
)

func compareToWuffsfmt(tm *t.Map, tokens []t.Token, comments []string, src string) error {
	buf := &bytes.Buffer{}
	if err := render.Render(buf, tm, tokens, comments); err != nil {
		return err
	}
	got := strings.Split(buf.String(), "\n")
	want := strings.Split(src, "\n")
	for line := 1; len(got) != 0 || len(want) != 0; line++ {
		if len(got) == 0 {
			w := strings.TrimSpace(want[0])
			return fmt.Errorf("difference at line %d:\n%s\n%s", line, "", w)
		}
		if len(want) == 0 {
			g := strings.TrimSpace(got[0])
			return fmt.Errorf("difference at line %d:\n%s\n%s", line, g, "")
		}
		if g, w := strings.TrimSpace(got[0]), strings.TrimSpace(want[0]); g != w {
			return fmt.Errorf("difference at line %d:\n%s\n%s", line, g, w)
		}
		got = got[1:]
		want = want[1:]
	}
	return nil
}

func TestCheck(tt *testing.T) {
	const filename = "test.wuffs"
	src := strings.TrimSpace(`
		pri struct foo(
			i : base.i32,
		)

		pri func foo.bar() {
			var x : base.u8
			var y : base.i32
			var z : base.u64[..= 123]
			var a : array[4] base.u8
			var b : base.bool

			var p : base.i32
			var q : base.i32[0 ..= 8]

			x = 0
			x = 1 + (x * 0)
			y = -y - 1
			y = this.i
			b = not true

			y = x as base.i32

			assert true

			while.label p == q,
				pre true,
				inv true,
				post p <> q,
			{
				// Redundant, but shows the labeled jump syntax.
				continue.label
			} endwhile.label
		}
	`) + "\n"

	tm := &t.Map{}

	tokens, comments, err := t.Tokenize(tm, filename, []byte(src))
	if err != nil {
		tt.Fatalf("Tokenize: %v", err)
	}

	file, err := parse.Parse(tm, filename, tokens, nil)
	if err != nil {
		tt.Fatalf("Parse: %v", err)
	}

	if err := compareToWuffsfmt(tm, tokens, comments, src); err != nil {
		tt.Fatalf("compareToWuffsfmt: %v", err)
	}

	c, err := Check(tm, []*a.File{file}, nil)
	if err != nil {
		tt.Fatalf("Check: %v", err)
	}

	// There are 2 funcs in this package: the implicit foo.reset method, and
{'fraction_non_alphanumeric': 0.16382492529442785, 'fraction_numerical': 0.015468447881877307, 'mean_word_length': 2.9377162629757785, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, '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': '6166848', 'n_tokens_mistral': 2347, 'n_tokens_neox': 2098, 'n_words': 647}