Пример #1
0
func TestPretty(t *testing.T) {
	var b bytes.Buffer
	for i, inout := range [][2]string{
		{"{}", "{}"},
		{`{"a":1}`, `{"a": 1
}`},
		{`{"m":{"a":1,"c":"b","b":[3,2,1]}}`, `{"m": {"a": 1,
    "b": [3,2,1],
    "c": "b"
  }
}`},
	} {
		m := make(map[string]interface{})
		if err := json.Unmarshal([]byte(inout[0]), &m); err != nil {
			t.Fatalf("%d. cannot unmarshal test input string: %v", i, err)
		}
		b.Reset()
		if err := Pretty(&b, m, ""); err != nil {
			t.Errorf("%d. Pretty: %v", i, err)
			continue
		}
		if inout[1] != b.String() {
			t.Errorf("%d. got %s\n\tawaited\n%s\n\tdiff\n%s", i, b.String(), inout[1],
				diff.Diff(inout[1], b.String()))
		}
	}
}
func TestConvertMainModuleToTemplate(t *testing.T) {
	mod := intMainModule{
		Vars: []intVar{
			{"ch", "HandshakeChannel0"},
			{"__pid0_ch", "HandshakeChannel0Proxy(ch)"},
			{"proc1", "__pid0_ProcA(__pid0_ch)"},
		},
	}
	expected := []tmplModule{
		{
			Name: "main",
			Args: []string{},
			Vars: []tmplVar{
				{"ch", "HandshakeChannel0"},
				{"__pid0_ch", "HandshakeChannel0Proxy(ch)"},
				{"proc1", "__pid0_ProcA(__pid0_ch)"},
			},
		},
	}
	err, tmplMods := convertMainModuleToTemplate(mod)
	if err != nil {
		t.Fatalf("Unexpected error: %s", err)
	}
	expectPP := pp.PP(expected)
	actualPP := pp.PP(tmplMods)
	if expectPP != actualPP {
		t.Errorf("Unmatched\n%s\n", diff.Diff(expectPP, actualPP))
	}
}
Пример #3
0
// Compare returns a string containing a line-by-line unified diff of the
// values in got and want.  Compare includes unexported fields.
//
// Each line in the output is prefixed with '+', '-', or ' ' to indicate if it
// should be added to, removed from, or is correct for the "got" value with
// respect to the "want" value.
func Compare(got, want interface{}) string {
	diffOpt := &Config{
		Diffable:          true,
		IncludeUnexported: true,
	}

	return diff.Diff(diffOpt.Sprint(got), diffOpt.Sprint(want))
}
Пример #4
0
// Diff returns the line diff of the two JSON map[string]interface{}s.
func Diff(a map[string]interface{}, b map[string]interface{}) string {
	var bA, bB bytes.Buffer
	if err := Pretty(&bA, a, ""); err != nil {
		return "ERROR(a): " + err.Error()
	}
	if err := Pretty(&bB, b, ""); err != nil {
		return "ERROR(b): " + err.Error()
	}
	return diff.Diff(bA.String(), bB.String())
}
Пример #5
0
func TestConvertASTToNuSMV2(t *testing.T) {
	defs := []Def{
		ProcDef{
			Name: "ProcA",
			Parameters: []Parameter{
				{
					Name: "ch0",
					Type: BufferedChannelType{
						BufferSize: NumberExpr{Pos{}, "3"},
						Elems:      []Type{NamedType{"bool"}},
					},
				},
			},
			Stmts: []Stmt{
				VarDeclStmt{
					Name: "b",
					Type: NamedType{"int"},
				},
				SendStmt{
					Channel: IdentifierExpr{Pos{}, "ch0"},
					Args: []Expr{
						TrueExpr{Pos{}},
					},
				},
			},
		},
		InitBlock{
			Vars: []InitVar{
				ChannelVar{
					Name: "ch",
					Type: BufferedChannelType{
						BufferSize: NumberExpr{Pos{}, "3"},
						Elems:      []Type{NamedType{"bool"}},
					},
				},
				InstanceVar{
					Name:        "proc1",
					ProcDefName: "ProcA",
					Args: []Expr{
						IdentifierExpr{Pos{}, "ch"},
					},
				},
			},
		},
	}
	mod, err := ConvertASTToNuSMV(defs)
	if err != nil {
		t.Fatalf("Unexpected error: %s", err)
	}
	if mod != expectedResult2 {
		t.Errorf("Unmatched\n%s\n", diff.Diff(expectedResult2, mod))
	}
}
Пример #6
0
func TestNewApproach(test *testing.T) {
	prep, _ := vfmd.QuickPrep(strings.NewReader(newApproach_input))
	result, err := QuickParse(bytes.NewReader(prep), BlocksAndSpans, nil, nil)
	if err != nil {
		test.Fatal(err)
	}
	expected := newApproach_flatOutput
	if !reflect.DeepEqual(result, expected) {
		// TODO(akavel): spew.Dump?
		test.Errorf("expected vs. got DIFF:\n%s",
			diff.Diff(spew.Sdump(expected), spew.Sdump(result)))
	}
}
Пример #7
0
func TestMapToSlice(t *testing.T) {
	for i, tc := range []struct {
		in, await string
	}{
		{`SELECT NVL(MAX(F_dazon), :dazon) FROM T_spl_level
	         WHERE (F_spl_azon = :lev_azon OR
			        F_ssz = 0 AND F_lev_azon = :lev_azon)`,
			`SELECT NVL(MAX(F_dazon), :1) FROM T_spl_level
	         WHERE (F_spl_azon = :2 OR
			        F_ssz = 0 AND F_lev_azon = :3)`},
		{`DECLARE
  i1 PLS_INTEGER;
  i2 PLS_INTEGER;
  v001 BRUNO.DB_WEB_ELEKTR.KOTVENY_REC_TYP;

BEGIN
  v001.dijkod := :p002#dijkod;

  DB_web.sendpreoffer_31101(p_kotveny=>v001);

  :p002#dijkod := v001.dijkod;

END;
`,
			`DECLARE
  i1 PLS_INTEGER;
  i2 PLS_INTEGER;
  v001 BRUNO.DB_WEB_ELEKTR.KOTVENY_REC_TYP;

BEGIN
  v001.dijkod := :1;

  DB_web.sendpreoffer_31101(p_kotveny=>v001);

  :2 := v001.dijkod;

END;
`},
	} {

		got, _ := MapToSlice(tc.in, nil)
		d := diff.Diff(tc.await, got)
		if d != "" {
			t.Errorf("%d. diff:\n%s", i, d)
		}
	}
}
Пример #8
0
func TestToJSON(t *testing.T) {
	tests := []struct {
		s    Schema
		want string
	}{
		{
			s: Schema{
				Name: "UsersResponse",
				Type: "object",
				Children: []Schema{
					{
						Name: "nextPageToken",
						Type: "string",
					},
					{
						Name: "users",
						Type: "array",
						Children: []Schema{
							{
								Ref: "User",
							},
						},
					},
				},
			},
			want: "```" + `
{
    nextPageToken: string,
    users: [
        User
    ]
}
` + "```",
		},
	}

	for i, tt := range tests {
		got := tt.s.toJSON()
		if d := diff.Diff(got, tt.want); d != "" {
			t.Errorf("case %d: want != got: %s", i, d)
		}
	}
}
Пример #9
0
func TestGetFdf(t *testing.T) {
	var err error
	if Workdir, err = ioutil.TempDir("", "agostle-"); err != nil {
		t.Fatalf("tempdir for Workdir: %v", err)
	}
	defer os.RemoveAll(Workdir)

	s := time.Now()
	fp1, err := getFdf("testdata/f1040.pdf")
	t.Logf("PDF -> FDF vanilla route: %s", time.Since(s))
	if err != nil {
		t.Errorf("getFdf: %v", err)
	}
	if len(fp1.Fields) != 214 {
		t.Errorf("getFdf: got %d, awaited %d fields.", len(fp1.Fields), 214)
	}
	var buf1 bytes.Buffer
	if _, err = fp1.WriteTo(&buf1); err != nil {
		t.Errorf("WriteTo1: %v", err)
	}

	s = time.Now()
	fp2, err := getFdf("testdata/f1040.pdf")
	t.Logf("gob -> FDF route: %s", time.Since(s))
	if err != nil {
		t.Errorf("getFdf2: %v", err)
	}
	if !reflect.DeepEqual(fp1, fp2) {
		t.Errorf("getFdf2: got %#v, awaited %#v.", fp2, fp1)
	}
	var buf2 bytes.Buffer
	if _, err = fp2.WriteTo(&buf2); err != nil {
		t.Errorf("WroteTo2: %v", err)
	}
	if df := diff.Diff(buf1.String(), buf2.String()); df != "" {
		t.Errorf("DIFF: %s", df)
	}

	out, err := exec.Command("ls", "-l", Workdir).Output()
	if err == nil {
		t.Logf("ls -l %s:\n%s", Workdir, out)
	}
}
Пример #10
0
// DiffStrings json.Unmarshals the strings and diffs that.
func DiffStrings(a, b string) (string, error) {
	mA := make(map[string]interface{})
	if err := json.Unmarshal([]byte(a), &mA); err != nil {
		return "", err
	}
	var bA bytes.Buffer
	if err := Pretty(&bA, mA, ""); err != nil {
		return "", err
	}

	mB := make(map[string]interface{})
	if err := json.Unmarshal([]byte(b), &mB); err != nil {
		return "", err
	}
	var bB bytes.Buffer
	if err := Pretty(&bB, mB, ""); err != nil {
		return "", err
	}

	return diff.Diff(bA.String(), bB.String()), nil
}
Пример #11
0
func diffs() {
	// func Diff(old, new string) string
	// 行级比较,同"git diff"
	// new 跟 old 比较,
	// -old
	// +new
	// 	constitution := strings.TrimSpace(`
	// We the People of the United States, in Order to form a more perfect Union,
	// establish Justice, insure domestic Tranquility, provide for the common defence,
	// promote the general Welfare, and secure the Blessings of Liberty to ourselves
	// and our Posterity, do ordain and establish this Constitution for the United
	// States of America.
	// `)

	// 	got := strings.TrimSpace(`
	// :wq
	// We the People of the United States, in Order to form a more perfect Union,
	// establish Justice, insure domestic Tranquility, provide for the common defence,
	// and secure the Blessings of Liberty to ourselves
	// and our Posterity, do ordain and establish this Constitution for the United
	// States of America.
	// `)
	// 	P(diff.Diff(got, constitution))

	P(diff.Diff("old", "new"))

	// [ `run` | done: 2.495417ms ]
	// -old
	// +new
	/*

		Error loading syntax file "Packages/GoSublime/syntax/GoSublime-Go.tmLanguage":
		 Unable to open Packages/GoSublime/syntax/GoSublime-Go.tmLanguage
	*/

}
Пример #12
0
func TestUnpackObject_blob(t *testing.T) {
	is := is.New(t)
	tcases := []struct {
		Fname  string
		Object *Object
	}{

		// blobs
		{
			Fname: "tests/blob/1f7a7a472abf3dd9643fd615f6da379c4acb3e3a",
			Object: &Object{
				Type: BlobT,
				Size: 10,
				blob: newBlob([]byte("version 2\n")),
			},
		},
		{
			Fname: "tests/blob/d670460b4b4aece5915caf5c68d12f560a9fe3e4",
			Object: &Object{
				Type: BlobT,
				Size: 13,
				blob: newBlob([]byte("test content\n")),
			},
		},

		// trees
		{
			Fname: "tests/tree/3c4e9cd789d88d8d89c1073707c3585e41b0e614",
			Object: &Object{Type: TreeT, Size: 101,
				tree: []Tree{
					{"40000", "bak", shaFromStr("\xd82\x9f\xc1̓\x87\x80\xffݟ\x94\xe0\xd3d\xe0\xeat\xf5y")},
					{"100644", "new.txt", shaFromStr("\xfaI\xb0w\x97#\x91\xadX\x03pP\xf2\xa7_t\xe3g\x1e\x92")},
					{"100644", "test.txt", shaFromStr("\x1fzzG*\xbf=\xd9d?\xd6\x15\xf6\xda7\x9cJ\xcb>:")},
				},
			},
		},
		{
			Fname: "tests/tree/0155eb4229851634a0f03eb265b69f5a2d56f341",
			Object: &Object{Type: TreeT, Size: 71,
				tree: []Tree{
					{"100644", "new.txt", shaFromStr("\xfaI\xb0w\x97#\x91\xadX\x03pP\xf2\xa7_t\xe3g\x1e\x92")},
					{"100644", "test.txt", shaFromStr("\x1fzzG*\xbf=\xd9d?\xd6\x15\xf6\xda7\x9cJ\xcb>:")},
				},
			},
		},

		// commit
		{
			Fname: "tests/commit/de70159e4a5842aed0aae9380e3006e909c8feb4",
			Object: &Object{Type: CommitT, Size: 165,
				commit: &Commit{
					Tree:      "d8329fc1cc938780ffdd9f94e0d364e0ea74f579",
					Author:    &Stamp{Name: "Henry", Email: "*****@*****.**", When: time.Unix(1438988455, 0)},
					Committer: &Stamp{Name: "Henry", Email: "*****@*****.**", When: time.Unix(1438988455, 0)},
					Message:   "first commit",
				},
			},
		},
		{
			Fname: "tests/commit/ad8fdc888c6f6caed63af0fb08484901e4e7e41e",
			Object: &Object{Type: CommitT, Size: 165,
				commit: &Commit{
					Tree:      "d8329fc1cc938780ffdd9f94e0d364e0ea74f579",
					Author:    &Stamp{Name: "Henry", Email: "*****@*****.**", When: time.Unix(1438995813, 0)},
					Committer: &Stamp{Name: "Henry", Email: "*****@*****.**", When: time.Unix(1438995813, 0)},
					Message:   "first commit",
				},
			},
			// TODO(cryptix): add example with Parent
		},
	}

	for _, tc := range tcases {
		f, err := os.Open(tc.Fname)
		is.Nil(err)
		obj, err := DecodeObject(f)
		is.Nil(err)
		diff := diff.Diff(obj.String(), tc.Object.String())
		is.Equal(diff, "")
		is.Nil(f.Close())
	}
}
func TestConvertHandshakeChannelToTemplate(t *testing.T) {
	mod := intHandshakeChannel{
		Name:      "HandshakeChannel0",
		ValueType: []string{"boolean"},
		ZeroValue: []string{"FALSE"},
	}
	expected := []tmplModule{
		{
			Name: "HandshakeChannel0",
			Args: []string{},
			Vars: []tmplVar{
				{"filled", "boolean"},
				{"received", "boolean"},
				{"value_0", "boolean"},
			},
			Assigns: []tmplAssign{
				{"init(filled)", "FALSE"},
				{"init(received)", "FALSE"},
				{"init(value_0)", "FALSE"},
			},
		},
		{
			Name: "HandshakeChannel0Proxy",
			Args: []string{"ch"},
			Vars: []tmplVar{
				{"send_filled", "boolean"},
				{"send_leaving", "boolean"},
				{"recv_received", "boolean"},
				{"send_value_0", "boolean"},
			},
			Defs: []tmplAssign{
				{"ready", "ch.filled"},
				{"received", "ch.received"},
				{"value_0", "ch.value_0"},
			},
			Assigns: []tmplAssign{
				{"next(ch.filled)", strings.Join([]string{
					"case",
					"  send_filled : TRUE;",
					"  send_leaving : FALSE;",
					"  TRUE : ch.filled;",
					"esac",
				}, "\n")},
				{"next(ch.received)", strings.Join([]string{
					"case",
					"  send_filled : FALSE;",
					"  send_leaving : FALSE;",
					"  recv_received : TRUE;",
					"  TRUE : ch.received;",
					"esac",
				}, "\n")},
				{"next(ch.value_0)", strings.Join([]string{
					"case",
					"  send_filled : send_value_0;",
					"  TRUE : ch.value_0;",
					"esac",
				}, "\n")},
			},
		},
	}
	err, tmplMods := convertHandshakeChannelToTemplate(mod)
	if err != nil {
		t.Fatalf("Unexpected error: %s", err)
	}
	expectPP := pp.PP(expected)
	actualPP := pp.PP(tmplMods)
	if expectPP != actualPP {
		t.Errorf("Unmatched\n%s\n", diff.Diff(expectPP, actualPP))
	}
}
func TestConvertProcModuleToTemplate(t *testing.T) {
	mod := intProcModule{
		Name: "__pid0_ProcA",
		Args: []string{"ch0"},
		Vars: []intVar{
			{"b", "0..8"},
		},
		InitState: intState("state0"),
		Trans: []intTransition{
			{
				FromState: "state0",
				NextState: "state1",
				Condition: "",
			},
			{
				FromState: "state1",
				NextState: "state2",
				Condition: "!ch0.ready",
				Actions: []intAssign{
					{"ch0.send_filled", "TRUE"},
					{"ch0.send_value_0", "TRUE"},
				},
			},
		},
		Defaults: map[string]string{
			"ch0.send_filled":   "FALSE",
			"ch0.recv_received": "FALSE",
			"ch0.send_value_0":  "ch0.value_0",
		},
		Defs: []intAssign{},
	}
	expected := []tmplModule{
		{
			Name: "__pid0_ProcA",
			Args: []string{"ch0"},
			Vars: []tmplVar{
				{"state", "{state0, state1, state2}"},
				{"transition", "{notrans, trans0, trans1}"},
				{"b", "0..8"},
			},
			Trans: []string{
				"transition = trans0 -> (TRUE)",
				"transition = trans1 -> (!ch0.ready)",
			},
			Assigns: []tmplAssign{
				{"transition", strings.Join([]string{
					"case",
					"  state = state0 & ((TRUE)) : {trans0};",
					"  state = state1 & ((!ch0.ready)) : {trans1};",
					"  TRUE : notrans;",
					"esac",
				}, "\n")},
				{"init(state)", "state0"},
				{"next(state)", strings.Join([]string{
					"case",
					"  transition = trans0 : state1;",
					"  transition = trans1 : state2;",
					"  TRUE : state;",
					"esac",
				}, "\n")},
				{"ch0.send_filled", strings.Join([]string{
					"case",
					"  transition = trans1 : TRUE;",
					"  TRUE : FALSE;",
					"esac",
				}, "\n")},
				{"ch0.recv_received", strings.Join([]string{
					"case",
					"  TRUE : FALSE;",
					"esac",
				}, "\n")},
				{"ch0.send_value_0", strings.Join([]string{
					"case",
					"  transition = trans1 : TRUE;",
					"  TRUE : ch0.value_0;",
					"esac",
				}, "\n")},
			},
			Justice: "running",
		},
	}
	err, tmplMods := convertProcModuleToTemplate(mod)
	if err != nil {
		t.Fatalf("Unexpected error: %s", err)
	}
	expectPP := pp.PP(expected)
	actualPP := pp.PP(tmplMods)
	if expectPP != actualPP {
		t.Errorf("Unmatched\n%s\n", diff.Diff(expectPP, actualPP))
	}
}
Пример #15
0
func (s *ConfigSuite) TestArgs(c *C) {
	tcs := []struct {
		name      string
		cfg       string
		expect    *Config
		expectErr bool
		args      []string
		vars      map[string]string
	}{
		{
			name: "string param",
			cfg: `{
                 "params": [
                     {
                       "name": "string1",
                       "type": "String"
                     }
                  ]
               }`,
			expect: &Config{
				Params: []Param{
					&StringParam{paramCommon{name: "string1"}, str("val1")},
				},
			},
			args: []string{"--string1", "val1"},
			vars: map[string]string{"STRING1": "val1"},
		},
		{
			name: "check defaults",
			cfg: `{
                 "params": [
                     {
                       "name": "string1",
                       "type": "String",
                       "default": "default value"
                     }
                  ]
               }`,
			expect: &Config{
				Params: []Param{
					&StringParam{
						paramCommon{name: "string1", def: "default value"},
						str("default value")},
				},
			},
			args: []string{},
			vars: map[string]string{"STRING1": "default value"},
		},
		{
			name: "check missing required param",
			cfg: `{
                 "params": [
                     {
                       "name": "string1",
                       "type": "String",
                       "required": true
                     }
                  ]
               }`,
			expectErr: true,
			args:      []string{},
		},
		{
			name: "check key values",
			cfg: `{
                 "params": [
                     {
                       "name": "volume",
                       "env": "PREFIX_VOLUME",
                       "type": "KeyVal",
                       "spec": {
                           "keys": [
                               {"name": "src", "type":"Path"},
                               {"name": "dst", "type":"Path"}
                           ]
                        }
                     }
                  ]
               }`,
			args: []string{"--volume", "/tmp/hello:/var/hello"},
			vars: map[string]string{"PREFIX_VOLUME": "/tmp/hello:/var/hello"},
			expect: &Config{
				Params: []Param{
					&KVParam{
						paramCommon{name: "volume", env: "PREFIX_VOLUME"},
						"",
						[]Param{
							&PathParam{paramCommon{name: "src"}, nil},
							&PathParam{paramCommon{name: "dst"}, nil},
						},
						[]Param{
							&PathParam{paramCommon{name: "src"}, str("/tmp/hello")},
							&PathParam{paramCommon{name: "dst"}, str("/var/hello")},
						},
					},
				},
			},
		},
		{
			name: "list of key values",
			cfg: `{
                 "params": [
                     {
                         "type": "List",
                         "name": "mounts",
                         "spec": {
                            "name": "volume",
                            "type": "KeyVal",
                            "spec": {
                              "keys": [
                                  {"name": "src", "type":"Path"},
                                  {"name": "dst", "type":"Path"}
                              ]
                            }
                        }
                     }
                  ]
               }`,
			args: []string{"--volume", "/tmp/hello:/var/hello"},
			vars: map[string]string{"VOLUME": "/tmp/hello:/var/hello"},
			expect: &Config{
				Params: []Param{
					&ListParam{
						paramCommon{name: "mounts"},
						&KVParam{
							paramCommon{name: "volume"},
							"",
							[]Param{
								&PathParam{paramCommon{name: "src"}, nil},
								&PathParam{paramCommon{name: "dst"}, nil},
							},
							nil,
						},
						[]Param{
							&KVParam{
								paramCommon{name: "volume"},
								"",
								[]Param{
									&PathParam{paramCommon{name: "src"}, nil},
									&PathParam{paramCommon{name: "dst"}, nil},
								},
								[]Param{
									&PathParam{paramCommon{name: "src"}, str("/tmp/hello")},
									&PathParam{paramCommon{name: "dst"}, str("/var/hello")},
								},
							},
						},
					},
				},
			},
		},
	}
	for i, tc := range tcs {
		comment := Commentf(
			"test #%d (%v) cfg=%v, args=%v", i+1, tc.name, tc.cfg, tc.args)
		cfg, err := ParseJSON(strings.NewReader(tc.cfg))
		c.Assert(err, IsNil, comment)

		if tc.expectErr {
			c.Assert(cfg.ParseArgs(tc.args), NotNil)
			continue
		}

		// make sure all the values have been parsed
		c.Assert(cfg.ParseArgs(tc.args), IsNil)
		c.Assert(len(cfg.Params), Equals, len(tc.expect.Params))
		for i, _ := range cfg.Params {
			comment := Commentf(
				"test #%d (%v) cfg=%v, args=%v\n%v",
				i+1, tc.name, tc.cfg, tc.args,
				diff.Diff(
					fmt.Sprintf("%# v", pretty.Formatter(cfg.Params[i])),
					fmt.Sprintf("%# v", pretty.Formatter(tc.expect.Params[i]))),
			)
			c.Assert(cfg.Params[i], DeepEquals, tc.expect.Params[i], comment)
		}

		// make sure args are equivalent to the passed arguments
		if len(tc.args) != 0 {
			args := cfg.Args()
			c.Assert(args, DeepEquals, tc.args, comment)
		}

		// make sure vars are what we expect them to be
		if len(tc.vars) != 0 {
			c.Assert(cfg.EnvVars(), DeepEquals, tc.vars, comment)
		}
	}
}
Пример #16
0
func TestProviderConfigMarshal(t *testing.T) {
	tests := []struct {
		cfg  ProviderConfig
		want string
	}{
		{
			cfg: ProviderConfig{
				Issuer: &url.URL{Scheme: "https", Host: "auth.example.com"},
				AuthEndpoint: &url.URL{
					Scheme: "https", Host: "auth.example.com", Path: "/auth",
				},
				TokenEndpoint: &url.URL{
					Scheme: "https", Host: "auth.example.com", Path: "/token",
				},
				UserInfoEndpoint: &url.URL{
					Scheme: "https", Host: "auth.example.com", Path: "/userinfo",
				},
				KeysEndpoint: &url.URL{
					Scheme: "https", Host: "auth.example.com", Path: "/jwk",
				},
				ResponseTypesSupported:  []string{oauth2.ResponseTypeCode},
				SubjectTypesSupported:   []string{SubjectTypePublic},
				IDTokenSigningAlgValues: []string{jose.AlgRS256},
			},
			// spacing must match json.MarshalIndent(cfg, "", "\t")
			want: `{
	"issuer": "https://auth.example.com",
	"authorization_endpoint": "https://auth.example.com/auth",
	"token_endpoint": "https://auth.example.com/token",
	"userinfo_endpoint": "https://auth.example.com/userinfo",
	"jwks_uri": "https://auth.example.com/jwk",
	"response_types_supported": [
		"code"
	],
	"subject_types_supported": [
		"public"
	],
	"id_token_signing_alg_values_supported": [
		"RS256"
	]
}`,
		},
		{
			cfg: ProviderConfig{
				Issuer: &url.URL{Scheme: "https", Host: "auth.example.com"},
				AuthEndpoint: &url.URL{
					Scheme: "https", Host: "auth.example.com", Path: "/auth",
				},
				TokenEndpoint: &url.URL{
					Scheme: "https", Host: "auth.example.com", Path: "/token",
				},
				UserInfoEndpoint: &url.URL{
					Scheme: "https", Host: "auth.example.com", Path: "/userinfo",
				},
				KeysEndpoint: &url.URL{
					Scheme: "https", Host: "auth.example.com", Path: "/jwk",
				},
				RegistrationEndpoint: &url.URL{
					Scheme: "https", Host: "auth.example.com", Path: "/register",
				},
				ScopesSupported:         DefaultScope,
				ResponseTypesSupported:  []string{oauth2.ResponseTypeCode},
				ResponseModesSupported:  DefaultResponseModesSupported,
				GrantTypesSupported:     []string{oauth2.GrantTypeAuthCode},
				SubjectTypesSupported:   []string{SubjectTypePublic},
				IDTokenSigningAlgValues: []string{jose.AlgRS256},
				ServiceDocs:             &url.URL{Scheme: "https", Host: "example.com", Path: "/docs"},
			},
			// spacing must match json.MarshalIndent(cfg, "", "\t")
			want: `{
	"issuer": "https://auth.example.com",
	"authorization_endpoint": "https://auth.example.com/auth",
	"token_endpoint": "https://auth.example.com/token",
	"userinfo_endpoint": "https://auth.example.com/userinfo",
	"jwks_uri": "https://auth.example.com/jwk",
	"registration_endpoint": "https://auth.example.com/register",
	"scopes_supported": [
		"openid",
		"email",
		"profile"
	],
	"response_types_supported": [
		"code"
	],
	"response_modes_supported": [
		"query",
		"fragment"
	],
	"grant_types_supported": [
		"authorization_code"
	],
	"subject_types_supported": [
		"public"
	],
	"id_token_signing_alg_values_supported": [
		"RS256"
	],
	"service_documentation": "https://example.com/docs"
}`,
		},
	}

	for i, tt := range tests {
		got, err := json.MarshalIndent(&tt.cfg, "", "\t")
		if err != nil {
			t.Errorf("case %d: failed to marshal config: %v", i, err)
			continue
		}
		if d := diff.Diff(string(got), string(tt.want)); d != "" {
			t.Errorf("case %d: expected did not match result: %s", i, d)
		}

		var cfg ProviderConfig
		if err := json.Unmarshal(got, &cfg); err != nil {
			t.Errorf("case %d: could not unmarshal marshal response: %v", i, err)
			continue
		}

		if d := pretty.Compare(tt.cfg, cfg); d != "" {
			t.Errorf("case %d: config did not survive JSON marshaling round trip: %s", i, d)
		}
	}

}
Пример #17
0
func TestHTMLFiles(test *testing.T) {
	const dir = "testdata/tests"
	cases := []struct {
		path string
	}{
		{"block_level/atx_header/blank_text.md"},
		{"block_level/atx_header/enclosed_blank_text.md"},
		{"block_level/atx_header/hash_in_text.md"},
		{"block_level/atx_header/left_only.md"},
		{"block_level/atx_header/left_right.md"},
		{"block_level/atx_header/more_than_six_hashes.md"},
		{"block_level/atx_header/space_in_text.md"},
		{"block_level/blockquote/containing_atx_header.md"},
		{"block_level/blockquote/containing_blockquote.md"},
		{"block_level/blockquote/containing_codeblock.md"},
		{"block_level/blockquote/containing_hr.md"},
		{"block_level/blockquote/containing_list.md"},
		{"block_level/blockquote/containing_setext_header.md"},
		{"block_level/blockquote/followed_by_atx_header.md"},
		{"block_level/blockquote/followed_by_codeblock.md"},
		{"block_level/blockquote/followed_by_hr.md"},
		{"block_level/blockquote/followed_by_list.md"},
		{"block_level/blockquote/followed_by_para.md"},
		{"block_level/blockquote/followed_by_setext_header.md"},
		{"block_level/blockquote/indented_differently1.md"},
		{"block_level/blockquote/indented_differently2.md"},
		{"block_level/blockquote/many_level_nesting.md"},
		{"block_level/blockquote/many_lines.md"},
		{"block_level/blockquote/many_lines_lazy.md"},
		{"block_level/blockquote/many_paras.md"},
		{"block_level/blockquote/many_paras_2blank.md"},
		{"block_level/blockquote/many_paras_2blank_lazy.md"},
		{"block_level/blockquote/many_paras_2blank_lazy2.md"},
		{"block_level/blockquote/many_paras_lazy.md"},
		{"block_level/blockquote/many_paras_lazy2.md"},
		{"block_level/blockquote/no_space_after_gt.md"},
		{"block_level/blockquote/one_line.md"},
		{"block_level/blockquote/space_before_gt.md"},
		{"block_level/codeblock/followed_by_para.md"},
		{"block_level/codeblock/html_escaping.md"},
		{"block_level/codeblock/many_lines.md"},
		{"block_level/codeblock/more_than_four_leading_space.md"},
		{"block_level/codeblock/one_blank_line_bw_codeblocks.md"},
		{"block_level/codeblock/one_line.md"},
		{"block_level/codeblock/two_blank_lines_bw_codeblocks.md"},
		{"block_level/codeblock/vs_atx_header.md"},
		{"block_level/codeblock/vs_blockquote.md"},
		{"block_level/codeblock/vs_hr.md"},
		{"block_level/codeblock/vs_list.md"},
		{"block_level/horizontal_rule/end_with_space.md"},
		{"block_level/horizontal_rule/followed_by_block.md"},
		{"block_level/horizontal_rule/loose.md"},
		{"block_level/horizontal_rule/sparse.md"},
		{"block_level/horizontal_rule/start_with_space.md"},
		{"block_level/horizontal_rule/tight.md"},
		{"block_level/ordered_list/all_items_loose.md"},
		{"block_level/ordered_list/all_items_tight.md"},
		{"block_level/ordered_list/all_items_tight_even_with_blanks.md"},
		{"block_level/ordered_list/at_end_of_parent_without_blank_line.md"},
		{"block_level/ordered_list/bw_unordered_lists.md"},
		{"block_level/ordered_list/followed_by_hr.md"},
		{"block_level/ordered_list/followed_by_list.md"},
		{"block_level/ordered_list/indent_and_sub_blocks.md"},
		{"block_level/ordered_list/list_ends_with_2blanks.md"},
		{"block_level/ordered_list/many_level_nesting.md"},
		{"block_level/ordered_list/many_lines.md"},
		{"block_level/ordered_list/many_lines_lazy.md"},
		{"block_level/ordered_list/many_paras.md"},
		{"block_level/ordered_list/many_paras_2blank.md"},
		{"block_level/ordered_list/many_paras_2blank_lazy.md"},
		{"block_level/ordered_list/many_paras_lazy.md"},
		{"block_level/ordered_list/no_space_after_number.md"},
		{"block_level/ordered_list/no_space_before_number.md"},
		{"block_level/ordered_list/numbering_from_two.md"},
		{"block_level/ordered_list/numbering_not_in_order.md"},
		{"block_level/ordered_list/numbers_left_aligned.md"},
		{"block_level/ordered_list/numbers_right_aligned.md"},
		{"block_level/ordered_list/numbers_wiggly.md"},
		{"block_level/ordered_list/one_line.md"},
		{"block_level/ordered_list/some_items_loose.md"},
		{"block_level/ordered_list/space_before_number.md"},
		{"block_level/ordered_list/three_paras_loose.md"},
		{"block_level/ordered_list/three_paras_tight.md"},
		{"block_level/ordered_list/two_paras_loose.md"},
		{"block_level/ordered_list/with_atx_header.md"},
		{"block_level/ordered_list/with_blockquote.md"},
		{"block_level/ordered_list/with_codeblock.md"},
		{"block_level/ordered_list/with_para.md"},
		{"block_level/ordered_list/with_setext_header.md"},
		{"block_level/paragraph/followed_by_atx_header.md"},
		{"block_level/paragraph/followed_by_blockquote.md"},
		{"block_level/paragraph/followed_by_codeblock.md"},
		{"block_level/paragraph/followed_by_horizontal_rule.md"},
		{"block_level/paragraph/followed_by_list.md"},
		{"block_level/paragraph/followed_by_setext_header.md"},
		{"block_level/paragraph/simple_para.md"},
		{"block_level/paragraph/two_paras_1blank.md"},
		{"block_level/paragraph/two_paras_2blank.md"},
		{"block_level/setext_header/blank_text.md"},
		{"block_level/setext_header/enclosed_space_in_underline.md"},
		{"block_level/setext_header/leading_space_in_text.md"},
		{"block_level/setext_header/leading_space_in_underline.md"},
		{"block_level/setext_header/simple.md"},
		{"block_level/setext_header/trailing_space_in_underline.md"},
		{"block_level/setext_header/vs_atx_header.md"},
		{"block_level/setext_header/vs_blockquote.md"},
		{"block_level/setext_header/vs_codeblock.md"},
		{"block_level/setext_header/vs_list.md"},
		{"block_level/unordered_list/all_items_loose.md"},
		{"block_level/unordered_list/all_items_tight.md"},
		{"block_level/unordered_list/all_items_tight_even_with_blanks.md"},
		{"block_level/unordered_list/at_end_of_parent_without_blank_line.md"},
		{"block_level/unordered_list/bw_ordered_lists.md"},
		{"block_level/unordered_list/changing_bullet.md"},
		{"block_level/unordered_list/changing_starter_string.md"},
		{"block_level/unordered_list/different_bullet_chars.md"},
		{"block_level/unordered_list/followed_by_hr.md"},
		{"block_level/unordered_list/followed_by_list.md"},
		{"block_level/unordered_list/indent_and_sub_blocks.md"},
		{"block_level/unordered_list/list_ends_with_2blanks.md"},
		{"block_level/unordered_list/many_level_nesting.md"},
		{"block_level/unordered_list/many_lines.md"},
		{"block_level/unordered_list/many_lines_lazy.md"},
		{"block_level/unordered_list/many_paras.md"},
		{"block_level/unordered_list/many_paras_2blank.md"},
		{"block_level/unordered_list/many_paras_2blank_lazy.md"},
		{"block_level/unordered_list/many_paras_lazy.md"},
		{"block_level/unordered_list/no_space_after_bullet.md"},
		{"block_level/unordered_list/no_space_before_bullet.md"},
		{"block_level/unordered_list/one_line.md"},
		{"block_level/unordered_list/some_items_loose.md"},
		{"block_level/unordered_list/space_before_bullet.md"},
		{"block_level/unordered_list/three_paras_loose.md"},
		{"block_level/unordered_list/three_paras_tight.md"},
		{"block_level/unordered_list/two_paras_loose.md"},
		{"block_level/unordered_list/with_atx_header.md"},
		{"block_level/unordered_list/with_blockquote.md"},
		{"block_level/unordered_list/with_codeblock.md"},
		{"block_level/unordered_list/with_para.md"},
		{"block_level/unordered_list/with_setext_header.md"},

		{"span_level/automatic_links/ending_with_punctuation.md"},
		{"span_level/automatic_links/mail_url_in_angle_brackets.md"},
		{"span_level/automatic_links/web_url_in_angle_brackets.md"},
		{"span_level/automatic_links/web_url_without_angle_brackets.md"},
		{"span_level/code/end_of_codespan.md"},
		{"span_level/code/multiline.md"},
		{"span_level/code/vs_emph.md"},
		{"span_level/code/vs_image.md"},
		{"span_level/code/vs_link.md"},
		{"span_level/code/well_formed.md"},
		{"span_level/emphasis/emphasis_tag_combinations.md"},
		{"span_level/emphasis/intertwined.md"},
		{"span_level/emphasis/intraword.md"},
		{"span_level/emphasis/nested_homogenous.md"},
		{"span_level/emphasis/opening_and_closing_tags.md"},
		{"span_level/emphasis/simple.md"},
		{"span_level/emphasis/within_whitespace.md"},
		{"span_level/image/direct_link.md"},
		{"span_level/image/direct_link_with_2separating_spaces.md"},
		{"span_level/image/direct_link_with_separating_newline.md"},
		{"span_level/image/direct_link_with_separating_space.md"},
		{"span_level/image/incomplete.md"},
		{"span_level/image/link_text_with_newline.md"},
		{"span_level/image/link_with_parenthesis.md"},
		{"span_level/image/multiple_ref_id_definitions.md"},
		{"span_level/image/nested_images.md"},
		{"span_level/image/ref_case_sensitivity.md"},
		{"span_level/image/ref_id_matching.md"},
		{"span_level/image/ref_link.md"},
		{"span_level/image/ref_link_empty.md"},
		{"span_level/image/ref_link_self.md"},
		{"span_level/image/ref_link_with_2separating_spaces.md"},
		{"span_level/image/ref_link_with_separating_newline.md"},
		{"span_level/image/ref_link_with_separating_space.md"},
		{"span_level/image/ref_resolution_within_other_blocks.md"},
		{"span_level/image/square_brackets_in_link_or_ref.md"},
		{"span_level/image/two_consecutive_refs.md"},
		{"span_level/image/unused_ref.md"},
		{"span_level/image/url_escapes.md"},
		{"span_level/image/url_in_angle_brackets.md"},
		{"span_level/image/url_special_chars.md"},
		{"span_level/image/url_whitespace.md"},
		{"span_level/image/vs_code.md"},
		{"span_level/image/vs_emph.md"},
		{"span_level/image/within_link.md"},
		{"span_level/link/direct_link.md"},
		{"span_level/link/direct_link_with_2separating_spaces.md"},
		{"span_level/link/direct_link_with_separating_newline.md"},
		{"span_level/link/direct_link_with_separating_space.md"},
		{"span_level/link/incomplete.md"},
		{"span_level/link/link_text_with_newline.md"},
		{"span_level/link/link_title.md"},
		{"span_level/link/link_with_parenthesis.md"},
		{"span_level/link/multiple_ref_id_definitions.md"},
		{"span_level/link/nested_links.md"},
		{"span_level/link/ref_case_sensitivity.md"},
		{"span_level/link/ref_id_matching.md"},
		{"span_level/link/ref_link.md"},
		{"span_level/link/ref_link_empty.md"},
		{"span_level/link/ref_link_self.md"},
		{"span_level/link/ref_link_with_2separating_spaces.md"},
		{"span_level/link/ref_link_with_separating_newline.md"},
		{"span_level/link/ref_link_with_separating_space.md"},
		{"span_level/link/ref_resolution_within_other_blocks.md"},
		{"span_level/link/square_brackets_in_link_or_ref.md"},
		{"span_level/link/two_consecutive_refs.md"},
		{"span_level/link/unused_ref.md"},
		{"span_level/link/url_escapes.md"},
		{"span_level/link/url_in_angle_brackets.md"},
		{"span_level/link/url_special_chars.md"},
		{"span_level/link/url_whitespace.md"},
		{"span_level/link/vs_code.md"},
		{"span_level/link/vs_emph.md"},
		{"span_level/link/vs_image.md"},

		{"text_processing/utf8/invalid_unicode.md"},
		{"text_processing/utf8/multibyte_chars.md"},
		{"text_processing/utf8/not_enough_continuation_bytes.md"},
		{"text_processing/utf8/overlong_encoding.md"},
		{"text_processing/utf8/stray_continuation_bytes.md"},
		{"text_processing/utf8_bom/code_block_with_bom.md"},
		{"text_processing/utf8_bom/eof_with_incomplete_bom.md"},
		{"text_processing/utf8_bom/list_with_bom.md"},
		{"text_processing/utf8_bom/text_with_bom.md"},
	}

	// Patches to what I believe are bugs in the original testdata, when
	// confronted with the spec.
	replacer := strings.NewReplacer(
		"'>'", "'>'",
		"'", "'",
		`"/>`, `" />`,
		// TODO(akavel): consider fixing (?) below line in our code
		""", """,
		// TODO(akavel): ...do something sensible so that this doesn't fail the diff.Diff?...
		"%5C", "%5c",
		// TODO(akavel): mitigate this somehow? or not? X|
		`<img src="url)"`, `<img src="url%29"`,
		`<img src="url("`, `<img src="url%28"`,
		`<a href="url)"`, `<a href="url%29"`,
		`<a href="url("`, `<a href="url%28"`,
		// TODO(akavel): I assume html/template has this ok, but need to verify at some point
		`<img src="url*#$%%5E&amp;%5C%7E"`, `<img src="url*#$%25%5e&amp;%5c~"`,
		`<a href="url*#$%%5E&amp;%5C%7E"`, `<a href="url*#$%25%5e&amp;%5c~"`,
		// TODO(akavel): or not TODO? HTML entities currently not supported, incl. in URLs
		`<a href="http://g&ouml;&ouml;gle.com">`, `<a href="http://g&amp;ouml;&amp;ouml;gle.com">`,
		`<img src="http://g&ouml;&ouml;gle.com"`, `<img src="http://g&amp;ouml;&amp;ouml;gle.com"`,
		// Various newline/space fixes in the testcases.
		"\n<li>\n    Parent list\n\n    <ol>", "\n<li>Parent list<ol>",
		"<code>Code block included in list\n</code>", "<code> Code block included in list\n</code>",
		"And another\n\n<p>Another para", "And another<p>Another para",
		"<li>Level 1\n<ol>", "<li>Level 1<ol>",
		"<li>Level 2\n<p>", "<li>Level 2<p>",
		"<li>Level 3\n<p>", "<li>Level 3<p>",
		"Level 4\n<ul>", "Level 4<ul>",
		"<li>Level 2\n<ol>", "<li>Level 2<ol>",
		"And another\n<p>", "And another<p>",
		"<li>Parent list\n    <ul>", "<li>Parent list<ul>",
		"<li>Third list\n<ul>", "<li>Third list<ul>",
		"<pre><code>Code block included in list</code></pre>", "<pre><code>Code block included in list\n</code></pre>",
		"<pre><code>Code block not included in list</code></pre>", "<pre><code>Code block not included in list\n</code></pre>",
		"<li>Level 1\n<ul>", "<li>Level 1<ul>",
		"<li>Level 2\n<ul>", "<li>Level 2<ul>",
	)

	for _, c := range cases {
		test.Log(c.path)
		subdir, fname := path.Split(c.path)
		fname = strings.TrimSuffix(fname, ".md")
		data, err := ioutil.ReadFile(filepath.Join(dir, c.path))
		if err != nil {
			test.Error(err)
			continue
		}
		expectedOutput, err := ioutil.ReadFile(
			filepath.Join(dir, subdir, "expected", fname+".html"))
		if err != nil {
			test.Error(err)
			continue
		}
		prep, _ := QuickPrep(bytes.NewReader(data))
		blocks, err := mdblock.QuickParse(bytes.NewReader(prep), mdblock.BlocksAndSpans, nil, nil)
		if err != nil {
			test.Errorf("case %s error: %s", c.path, err)
			continue
		}

		buf := bytes.NewBuffer(nil)
		err = QuickHTML(buf, blocks)
		if err != nil {
			test.Error(err)
			continue
		}
		html := simplifyHtml(buf.Bytes())
		expectedOutput = []byte(replacer.Replace(string(simplifyHtml(expectedOutput))))
		if !bytes.Equal(html, expectedOutput) {
			test.Errorf("case %s blocks:\n%s",
				c.path, spew.Sdump(blocks))
			test.Errorf("case %s expected vs. got DIFF:\n%s",
				c.path, diff.Diff(string(expectedOutput), string(html)))
		}
	}
}
Пример #18
0
func TestSplitFdf(t *testing.T) {
	fdf := []byte(`%FDF-1.2
%âăĎÓ
1 0 obj
<<
/FDF
<<
/Fields [
<<
/V ()
/T (Forgalmi rendszámRow4)
>>
<<
/V ()
/T (Forgalmi rendszámRow3)
>>
<<
/V ()
/T (Forgalmi rendszámRow2)
>>
<<
/V ()
/T (Az Ön gépjárművének forgalmi rendszáma)
>>
<<
/V ()
/T (Forgalmi rendszámRow1)
>>
<<
/V ()
/T (neve_2)
>>
<<
/V ()
/T (neve_3)
>>
<<
/V ()
/T (neve)
>>
<<
/V ()
/T (neve_4)
>>
<<
/V ()
/T (házszám)
>>
<<
/V ()
/T (SérülésRow1)
>>
<<
/V ()
/T (SérülésRow2)
>>
<<
/V ()
/T (SérülésRow3)
>>
<<
/V ()
/T (címe_2)
>>
<<
/V ()
/T (címe_3)
>>
<<
/V ()
/T (címe_4)
>>
<<
/V ()
/T (Cím telefonszámRow3)
>>
<<
/V ()
/T (Cím telefonszámRow2)
>>
<<
/V ()
/T (Cím telefonszámRow1)
>>
<<
/V ()
/T (Email)
>>
<<
/V ()
/T (NévRow1)
>>
<<
/V ()
/T (NévRow2)
>>
<<
/V ()
/T (NévRow3)
>>
<<
/V ()
/T (ututca)
>>
<<
/V ()
/T (Text21)
>>
<<
/V ()
/T (címe)
>>
<<
/V ()
/T (Text22)
>>
<<
/V ()
/T (Text23)
>>
<<
/V ()
/T (Text24)
>>
<<
/V ()
/T (Text25)
>>
<<
/V ()
/T (Text26)
>>
<<
/V ()
/T (Text27)
>>
<<
/V ()
/T (Tett intézkedés kérjük csatolja az igazoló dokumentumot)
>>
<<
/V ()
/T (Lakott területen kívül)
>>
<<
/V ()
/T (biztosítónál)
>>
<<
/V ()
/T (évhónap)
>>
<<
/V ()
/T (Sérülések leírásaRow6)
>>
<<
/V ()
/T (Sérülések leírásaRow5)
>>
<<
/V ()
/T (Sérülések leírásaRow4)
>>
<<
/V ()
/T (Sérülések leírásaRow3)
>>
<<
/V ()
/T (Sérülések leírásaRow2)
>>
<<
/V ()
/T (Sérülések leírásaRow1)
>>
<<
/V ()
/T (Milyen minôségben vezette a gépjárművet kérjük szíveskedjen az igazoló dokumentumot is csatolni pl kölcsönadási szerzôdés stb)
>>
<<
/V ()
/T (kerület)
>>
<<
/V ()
/T (város)
>>
<<
/V ()
/T (TípusRow1)
>>
<<
/V ()
/T (TípusRow2)
>>
<<
/V ()
/T (út)
>>
<<
/V ()
/T (TípusRow3)
>>
<<
/V ()
/T (TípusRow4)
>>
<<
/V ()
/T (TípusRow5)
>>
<<
/V ()
/T (undefined_2)
>>
<<
/V ()
/T (TípusRow6)
>>
<<
/V ()
/T (undefined_3)
>>
<<
/V ()
/T (undefined_4)
>>
<<
/V /
/T (Check Box20)
>>
<<
/V ()
/T (Kelt)
>>
<<
/V ()
/T (Cím)
>>
<<
/V ()
/T (Járműszerelvény esetén a pótkocsi forgalmi rendszáma)
>>
<<
/V ()
/T (óraperc)
>>
<<
/V ()
/T (Telefon)
>>
<<
/V /
/T (Check Box19)
>>
<<
/V /
/T (Check Box18)
>>
<<
/V /
/T (Check Box17)
>>
<<
/V ()
/T (A baleset helye)
>>
<<
/V /
/T (Check Box16)
>>
<<
/V ()
/T (Forgalmi rendszámRow6)
>>
<<
/V /
/T (Check Box15)
>>
<<
/V ()
/T (Forgalmi rendszámRow5)
>>]
>>
>>
endobj
trailer

<<
/Root 1 0 R
>>
%%EOF
`)

	fp := splitFdf(fdf)
	if len(fp.Parts) != 64 {
		t.Errorf("wanted 64 parts, got %d", len(fp.Parts))
	}
	if len(fp.Fields) != 63 {
		t.Errorf("wanted 63 fields, got %d", len(fp.Fields))
	}
	t.Logf("splitted=%q (%d)", fp, len(fp.Parts))

	if err := fp.Set("A baleset helye", "Kiskunbürgözd"); err != nil {
		t.Errorf("Set: %v", err)
	}

	var buf bytes.Buffer
	if _, err := fp.WriteTo(&buf); err != nil {
		t.Errorf("WriteTo: %v", err)
	}

	df := diff.Diff(buf.String(), `%FDF-1.2
%âăĎÓ
1 0 obj
<<
/FDF
<<
/Fields [
<<
/V ()
/T (Forgalmi rendszámRow4)
>>
<<
/V ()
/T (Forgalmi rendszámRow3)
>>
<<
/V ()
/T (Forgalmi rendszámRow2)
>>
<<
/V ()
/T (Az Ön gépjárművének forgalmi rendszáma)
>>
<<
/V ()
/T (Forgalmi rendszámRow1)
>>
<<
/V ()
/T (neve_2)
>>
<<
/V ()
/T (neve_3)
>>
<<
/V ()
/T (neve)
>>
<<
/V ()
/T (neve_4)
>>
<<
/V ()
/T (házszám)
>>
<<
/V ()
/T (SérülésRow1)
>>
<<
/V ()
/T (SérülésRow2)
>>
<<
/V ()
/T (SérülésRow3)
>>
<<
/V ()
/T (címe_2)
>>
<<
/V ()
/T (címe_3)
>>
<<
/V ()
/T (címe_4)
>>
<<
/V ()
/T (Cím telefonszámRow3)
>>
<<
/V ()
/T (Cím telefonszámRow2)
>>
<<
/V ()
/T (Cím telefonszámRow1)
>>
<<
/V ()
/T (Email)
>>
<<
/V ()
/T (NévRow1)
>>
<<
/V ()
/T (NévRow2)
>>
<<
/V ()
/T (NévRow3)
>>
<<
/V ()
/T (ututca)
>>
<<
/V ()
/T (Text21)
>>
<<
/V ()
/T (címe)
>>
<<
/V ()
/T (Text22)
>>
<<
/V ()
/T (Text23)
>>
<<
/V ()
/T (Text24)
>>
<<
/V ()
/T (Text25)
>>
<<
/V ()
/T (Text26)
>>
<<
/V ()
/T (Text27)
>>
<<
/V ()
/T (Tett intézkedés kérjük csatolja az igazoló dokumentumot)
>>
<<
/V ()
/T (Lakott területen kívül)
>>
<<
/V ()
/T (biztosítónál)
>>
<<
/V ()
/T (évhónap)
>>
<<
/V ()
/T (Sérülések leírásaRow6)
>>
<<
/V ()
/T (Sérülések leírásaRow5)
>>
<<
/V ()
/T (Sérülések leírásaRow4)
>>
<<
/V ()
/T (Sérülések leírásaRow3)
>>
<<
/V ()
/T (Sérülések leírásaRow2)
>>
<<
/V ()
/T (Sérülések leírásaRow1)
>>
<<
/V ()
/T (Milyen minôségben vezette a gépjárművet kérjük szíveskedjen az igazoló dokumentumot is csatolni pl kölcsönadási szerzôdés stb)
>>
<<
/V ()
/T (kerület)
>>
<<
/V ()
/T (város)
>>
<<
/V ()
/T (TípusRow1)
>>
<<
/V ()
/T (TípusRow2)
>>
<<
/V ()
/T (út)
>>
<<
/V ()
/T (TípusRow3)
>>
<<
/V ()
/T (TípusRow4)
>>
<<
/V ()
/T (TípusRow5)
>>
<<
/V ()
/T (undefined_2)
>>
<<
/V ()
/T (TípusRow6)
>>
<<
/V ()
/T (undefined_3)
>>
<<
/V ()
/T (undefined_4)
>>
<<
/V /
/T (Check Box20)
>>
<<
/V ()
/T (Kelt)
>>
<<
/V ()
/T (Cím)
>>
<<
/V ()
/T (Járműszerelvény esetén a pótkocsi forgalmi rendszáma)
>>
<<
/V ()
/T (óraperc)
>>
<<
/V ()
/T (Telefon)
>>
<<
/V /
/T (Check Box19)
>>
<<
/V /
/T (Check Box18)
>>
<<
/V /
/T (Check Box17)
>>
<<
/V (`+"\xfe\xff\x00K\x00i\x00s\x00k\x00u\x00n\x00b\x00\xfc\x00r\x00g\x00\xf6\x00z\x00d"+`)
/T (A baleset helye)
>>
<<
/V /
/T (Check Box16)
>>
<<
/V ()
/T (Forgalmi rendszámRow6)
>>
<<
/V /
/T (Check Box15)
>>
<<
/V ()
/T (Forgalmi rendszámRow5)
>>]
>>
>>
endobj
trailer

<<
/Root 1 0 R
>>
%%EOF
`)
	if df != "" {
		t.Errorf("mismatch: %s", df)
	}
}
Пример #19
0
func TestConvertASTToIntModuleForSend(t *testing.T) {
	return // FIXME:
	sendWithTagSource := `
		fault send(ch channel { bool }) @omission {
			// do nothing
		}

		proc SendProc(ch channel { bool }) {
			send(ch, true) @omission
		}

		init {
			ch: channel { bool },
			sp: SendProc(ch),
		}
	`
	expected := []intModule{
		intHandshakeChannel{
			Name:      "HandshakeChannel0",
			ValueType: []string{"boolean"},
			ZeroValue: []string{"FALSE"},
		},
		intProcModule{
			Name: "__pid0_SendProc",
			Args: []string{"__orig_ch"},
			Vars: []intVar{
				{"ch", "HandshakeChannel0Proxy(__orig_ch)"},
			},
			InitState: intState("state0"),
			Trans: []intTransition{
				{
					FromState: "state0",
					NextState: "state2",
					Condition: "",
					Actions:   []intAssign(nil),
				},
				{
					FromState: "state2",
					NextState: "state3",
					Condition: "!(ch.ready)",
					Actions: []intAssign{
						{"ch.send_filled", "TRUE"},
						{"ch.send_value_0", "TRUE"},
					},
				},
				{
					FromState: "state3",
					NextState: "state4",
					Condition: "(ch.ready) & (ch.received)",
					Actions: []intAssign{
						{"ch.send_leaving", "TRUE"},
					},
				},
				{
					FromState: "state4",
					NextState: "state1",
					Condition: "",
					Actions:   []intAssign(nil),
				},
				{
					FromState: "state0",
					NextState: "state5",
					Condition: "",
					Actions:   []intAssign(nil),
				},
				{
					FromState: "state5",
					NextState: "state6",
					Condition: "!(ch.ready)",
					Actions: []intAssign{
						{"ch.send_filled", "TRUE"},
						{"ch.send_value_0", "TRUE"},
					},
				},
				{
					FromState: "state6",
					NextState: "state7",
					Condition: "(ch.ready) & (ch.received)",
					Actions: []intAssign{
						{"ch.send_leaving", "TRUE"},
					},
				},
				{
					FromState: "state7",
					NextState: "state1",
					Condition: "",
					Actions:   []intAssign(nil),
				},
			},
			Defaults: map[string]string{
				"ch.send_leaving":  "FALSE",
				"ch.send_filled":   "FALSE",
				"ch.recv_received": "FALSE",
				"ch.send_value_0":  "ch.value_0",
			},
			Defs: []intAssign(nil),
		},
		intMainModule{
			Vars: []intVar{
				{"ch", "HandshakeChannel0"},
				{"sp", "process __pid0_SendProc(ch)"},
			},
		},
	}

	scanner := new(parsing.Scanner)
	scanner.Init([]rune(sendWithTagSource), 0)
	defs := parsing.Parse(scanner)

	err, intMods := astToIr1(defs)
	if err != nil {
		t.Fatalf("Unexpected error: %s", err)
	}
	actualPP := pp.PP(intMods)
	expectPP := pp.PP(expected)
	if actualPP != expectPP {
		t.Errorf("Unmatched\n%s\n", diff.Diff(expectPP, actualPP))
	}
}
Пример #20
0
func TestConvertASTToIntModule(t *testing.T) {
	return // FIXME: pending because it fails

	defs := []Def{
		ProcDef{
			Name: "ProcA",
			Parameters: []Parameter{
				{
					Name: "ch0",
					Type: HandshakeChannelType{
						Elems: []Type{NamedType{"bool"}},
					},
				},
			},
			Stmts: []Stmt{
				VarDeclStmt{
					Name: "b",
					Type: NamedType{"int"},
				},
				SendStmt{
					Channel: IdentifierExpr{Pos{}, "ch0"},
					Args: []Expr{
						TrueExpr{Pos{}},
					},
				},
			},
		},
		InitBlock{
			Vars: []InitVar{
				ChannelVar{
					Name: "ch",
					Type: HandshakeChannelType{
						Elems: []Type{NamedType{"bool"}},
					},
				},
				InstanceVar{
					Name:        "proc1",
					ProcDefName: "ProcA",
					Args: []Expr{
						IdentifierExpr{Pos{}, "ch"},
					},
				},
			},
		},
	}
	expected := []intModule{
		intHandshakeChannel{
			Name:      "HandshakeChannel0",
			ValueType: []string{"boolean"},
			ZeroValue: []string{"FALSE"},
		},
		intProcModule{
			Name: "__pid0_ProcA",
			Args: []string{"__orig_ch0"},
			Vars: []intVar{
				{"ch0", "HandshakeChannel0Proxy(__orig_ch0)"},
				{"b", "0..1"},
			},
			InitState: intState("state0"),
			Trans: []intTransition{
				{
					FromState: "state0",
					NextState: "state1",
					Condition: "",
				},
				{
					FromState: "state1",
					NextState: "state2",
					Condition: "!(ch0.ready)",
					Actions: []intAssign{
						{"ch0.send_filled", "TRUE"},
						{"ch0.send_value_0", "TRUE"},
					},
				},
				{
					FromState: "state2",
					NextState: "state3",
					Condition: "(ch0.ready) & (ch0.received)",
					Actions: []intAssign{
						{"ch0.send_leaving", "TRUE"},
					},
				},
			},
			Defaults: map[string]string{
				"ch0.send_leaving":  "FALSE",
				"ch0.send_filled":   "FALSE",
				"ch0.recv_received": "FALSE",
				"ch0.send_value_0":  "ch0.value_0",
				"next(b)":           "b",
			},
			Defs: []intAssign{},
		},
		intMainModule{
			Vars: []intVar{
				{"ch", "HandshakeChannel0"},
				{"proc1", "process __pid0_ProcA(ch)"},
			},
		},
	}
	err, intMods := astToIr1(defs)
	if err != nil {
		t.Fatalf("Unexpected error: %s", err)
	}
	expectPP := pp.PP(expected)
	actualPP := pp.PP(intMods)
	if expectPP != actualPP {
		t.Errorf("Unmatched\n%s\n", diff.Diff(expectPP, actualPP))
	}
}
Пример #21
0
func TestSpan(test *testing.T) {
	cases := []spanCase{
		lines(`automatic_links/angle_brackets_in_link.md`, spans{
			md.AutomaticLink{URL: `http://exampl`, Text: `http://exampl`},
			// TODO(akavel): below is expected by testdata/, but
			// invalid according to spec, because preceding "<" is
			// not a 'word-separator' character (it has unicode
			// general class Sm - "Symbol, math"); try to resolve
			// this with the spec author.
			// {bb("http://exampl"), md.AutomaticLink{URL: `http://exampl`, Text: `http://exampl`}},
		}),
		lines("automatic_links/ending_with_punctuation.md", spans{
			md.AutomaticLink{URL: "http://example.net", Text: "http://example.net"},
			md.AutomaticLink{URL: "http://example.net/", Text: "http://example.net/"},
			md.AutomaticLink{URL: "http://example.net", Text: "http://example.net"},
			md.AutomaticLink{URL: "http://example.net/", Text: "http://example.net/"},

			md.AutomaticLink{URL: "http://example.net,", Text: "http://example.net,"},
			md.AutomaticLink{URL: "http://example.net/,", Text: "http://example.net/,"},
			md.AutomaticLink{URL: "http://example.net)", Text: "http://example.net)"},
			md.AutomaticLink{URL: "http://example.net/)", Text: "http://example.net/)"},
		}),
		lines("automatic_links/mail_url_in_angle_brackets.md", spans{
			md.AutomaticLink{URL: "mailto:[email protected]", Text: "mailto:[email protected]"},
			md.AutomaticLink{URL: "mailto:[email protected]", Text: "*****@*****.**"},
		}),
		lines("automatic_links/mail_url_without_angle_brackets.md", spans{
			// NOTE(akavel): below line is unexpected according to
			// testdata/, but from spec this seems totally expected,
			// so I added it
			md.AutomaticLink{URL: "mailto:[email protected]", Text: "mailto:[email protected]"},
		}),
		lines("automatic_links/url_schemes.md", spans{
			md.AutomaticLink{URL: "http://example.net", Text: "http://example.net"},
			md.AutomaticLink{URL: "http://example.net", Text: "http://example.net"},
			md.AutomaticLink{URL: "file:///tmp/tmp.html", Text: "file:///tmp/tmp.html"},
			md.AutomaticLink{URL: "file:///tmp/tmp.html", Text: "file:///tmp/tmp.html"},
			md.AutomaticLink{URL: "feed://example.net/rss.xml", Text: "feed://example.net/rss.xml"},
			md.AutomaticLink{URL: "feed://example.net/rss.xml", Text: "feed://example.net/rss.xml"},
			md.AutomaticLink{URL: "googlechrome://example.net/", Text: "googlechrome://example.net/"},
			md.AutomaticLink{URL: "googlechrome://example.net/", Text: "googlechrome://example.net/"},
			md.Code{bb("<>")},
			// NOTE(akavel): below line is unexpected according to
			// testdata/, but from spec this seems totally expected,
			// so I added it
			md.AutomaticLink{URL: "mailto:[email protected]", Text: "mailto:[email protected]"},
			md.AutomaticLink{URL: "mailto:[email protected]", Text: "mailto:[email protected]"},
		}),
		lines("automatic_links/url_special_chars.md", spans{
			md.AutomaticLink{URL: `http://example.net/*#$%^&\~/blah`, Text: `http://example.net/*#$%^&\~/blah`},
			md.AutomaticLink{URL: `http://example.net/*#$%^&\~)/blah`, Text: `http://example.net/*#$%^&\~)/blah`},
			// NOTE(akavel): testdata expects below commented entry,
			// but this seems wrong compared to spec; I've added
			// fixed entry
			// {bb(`http://example.net/blah/`), md.AutomaticLink{URL: `http://example.net/blah/`, Text: `http://example.net/blah/`}},
			md.AutomaticLink{URL: `http://example.net/blah/*#$%^&\~`, Text: `http://example.net/blah/*#$%^&\~`},
			md.AutomaticLink{URL: `http://example.net/blah/*#$%^&\~)`, Text: `http://example.net/blah/*#$%^&\~)`},
		}),
		lines("automatic_links/web_url_in_angle_brackets.md", spans{
			md.AutomaticLink{URL: "http://example.net/path/", Text: "http://example.net/path/"},
			md.AutomaticLink{URL: "https://example.net/path/", Text: "https://example.net/path/"},
			md.AutomaticLink{URL: "ftp://example.net/path/", Text: "ftp://example.net/path/"},
		}),
		lines("automatic_links/web_url_without_angle_brackets.md", spans{
			md.AutomaticLink{URL: "http://example.net/path/", Text: "http://example.net/path/"},
			md.AutomaticLink{URL: "https://example.net/path/", Text: "https://example.net/path/"},
			md.AutomaticLink{URL: "ftp://example.net/path/", Text: "ftp://example.net/path/"},
		}),
		lines("code/end_of_codespan.md", spans{
			md.Code{bb("code span")},
			md.Code{bb("code span` ends")},
			md.Code{bb("code span`` ends")},
			md.Code{bb("code span`` ``ends")},
			md.Code{bb(`code span\`)},
		}),
		blocks("code/multiline.md", spans{
			md.Code{bb("code span\ncan span multiple\nlines")},
		}),
		lines("code/vs_emph.md", spans{
			md.Code{bb("code containing *em* text")},
			md.Code{bb("code containing **strong** text")},
			md.Code{bb("code containing _em_ text")},
			md.Code{bb("code containing __strong__ text")},

			md.Emphasis{Level: 1},
			md.Code{bb("code")},
			md.End{},
			md.Emphasis{Level: 2},
			md.Code{bb("code")},
			md.End{},
			md.Emphasis{Level: 1},
			md.Code{bb("code")},
			md.End{},
			md.Emphasis{Level: 2},
			md.Code{bb("code")},
			md.End{},

			md.Code{bb("code *intertwined")},
			md.Code{bb("with em* text")},
			md.Code{bb("code **intertwined")},
			md.Code{bb("with strong** text")},
			md.Code{bb("code _intertwined")},
			md.Code{bb("with em_ text")},
			md.Code{bb("code __intertwined")},
			md.Code{bb("with strong__ text")},
		}),
		lines("code/vs_image.md", spans{
			md.Code{bb("code containing ![image](url)")},
			md.Code{bb("code containing ![image][ref]")},
			md.Code{bb("code containing ![ref]")},

			md.Code{bb("containing code")},
			md.Code{bb("containing code")},
			md.Link{ReferenceID: "ref", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
			md.Code{bb("containing code")},

			md.Code{bb("code ![intertwined")},
			md.Code{bb("intertwined](with) image")},
			md.Code{bb("code ![intertwined")},
			md.Link{ReferenceID: "ref", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
			md.Code{bb("intertwined with][ref] image")},
			md.Code{bb("code ![intertwined")},
			md.Code{bb("with] image")},
		}, head(30)),
		lines("code/vs_link.md", spans{
			md.Code{bb("code containing [link](url)")},
			md.Code{bb("code containing [link][ref]")},
			md.Code{bb("code containing [ref]")},

			md.Link{URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}},
			md.Code{bb("containing code")},

			md.End{},
			md.Link{ReferenceID: "ref", RawEnd: md.Raw{{-1, bb("][ref]")}}},
			md.Code{bb("containing code")},
			md.End{},
			md.Link{ReferenceID: "link `containing code`", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Code{bb("containing code")},
			md.End{},

			md.Code{bb("code [intertwined")},
			md.Code{bb("intertwined](with) link")},
			md.Code{bb("code [intertwined")},
			md.Link{ReferenceID: "ref", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
			md.Code{bb("intertwined with][ref] link")},
			md.Code{bb("code [intertwined")},
			md.Code{bb("with] link")},
		}, head(30)),
		lines("code/well_formed.md", spans{
			md.Code{bb("code span")},
			md.Code{bb("code ` span")},
			md.Code{bb("` code span")},
			md.Code{bb("code span `")},
			md.Code{bb("`code span`")},
		}),
		lines("emphasis/emphasis_tag_combinations.md", spans{
			emB("*"), emB("__"), emE("__"), emE("*"),
			emB("_"), emB("**"), emE("**"), emE("_"),
			emB("***"), emE("***"),
			emB("**"), emB("*"), emE("*"), emE("**"),
			emB("*"), emB("*"), emB("*"), emE("*"), emE("*"), emE("*"),
			emB("*"), emB("**"), emE("**"), emE("*"),

			emB("_"), emB("__"), emE("__"), emE("_"),
			emB("_"), emB("_"), emB("_"), emE("_"), emE("_"), emE("_"),
			emB("__"), emB("_"), emE("_"), emE("__"),
		}),
		lines("emphasis/intertwined.md", spans{
			emB("*"), emE("*"),
			emB("**"), emE("**"),
			emB("*"), emB("*"), emB("*"), emE("*"), emE("*"), emE("*"),
			emB("*"), emB("*"), emB("*"), emE("*"), emE("*"), emE("*"),

			emB("_"), emE("_"),
			emB("__"), emE("__"),
			emB("_"), emB("_"), emB("_"), emE("_"), emE("_"), emE("_"),
			emB("_"), emB("_"), emB("_"), emE("_"), emE("_"), emE("_"),
		}),
		lines("emphasis/intraword.md", spans{}),
		lines("emphasis/nested_homogenous.md", spans{
			emB("*"), emB("*"), emE("*"), emE("*"),
			emB("**"), emB("**"), emE("**"), emE("**"),
			emB("_"), emB("_"), emE("_"), emE("_"),
			emB("__"), emB("__"), emE("__"), emE("__"),
		}),
		lines("emphasis/opening_and_closing_tags.md", spans{}),
		lines("emphasis/simple.md", spans{
			emB("*"), emE("*"), emB("**"), emE("**"),
			emB("_"), emE("_"), emB("__"), emE("__"),
		}),
		lines("emphasis/within_whitespace.md", spans{}),
		lines("emphasis/with_punctuation.md", spans{
			emB("*"), emE("*"),
			emB("*"), emE("*"),
			emB("*"), emE("*"),
			emB("*"), emE("*"),

			emB("_"), emE("_"), emB("_"), emE("_"),
			// NOTE(akavel): link below not expected in testdata
			// because it's not defined below; but we leave this to
			// user.
			md.Link{ReferenceID: "_", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
			emB("_"), emE("_"), emB("_"), emE("_"),
			// NOTE(akavel): link below not expected in testdata
			// because it's not defined below; but we leave this to
			// user.
			md.Link{ReferenceID: "_", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
		}),
		lines("image/direct_link.md", spans{
			md.Image{AltText: "image", URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}},
			md.Image{AltText: "image", URL: "url", Title: "title", RawEnd: md.Raw{{-1, bb(`](url "title")`)}}},
		}),
		lines("image/direct_link_with_2separating_spaces.md", spans{
			md.Image{AltText: "linking", URL: "/img.png", RawEnd: md.Raw{{-1, bb("]  (/img.png)")}}},
		}),
		blocks("image/direct_link_with_separating_newline.md", spans{
			md.Image{AltText: "link", URL: "/img.png", RawEnd: md.Raw{{-1, bb("]\n(/img.png)")}}},
		}),
		lines("image/direct_link_with_separating_space.md", spans{
			md.Image{AltText: "link", URL: "http://example.net/img.png", RawEnd: md.Raw{{-1, bb("] (http://example.net/img.png)")}}},
		}),
		lines("image/image_title.md", spans{
			md.Image{AltText: "link", URL: "url", Title: `title`, RawEnd: md.Raw{{-1, bb(`](url "title")`)}}},
			md.Image{AltText: "link", URL: "url", Title: `title`, RawEnd: md.Raw{{-1, bb(`](url 'title')`)}}},
			// TODO(akavel): unquote contents of Title when
			// processing? doesn't seem noted in spec, send fix for
			// spec?
			md.Image{AltText: "link", URL: "url", Title: `title 'with' "quotes"`, RawEnd: md.Raw{{-1, bb(`](url "title 'with' \"quotes\"")`)}}},
			md.Image{AltText: "link", URL: "url", Title: `title 'with' "quotes"`, RawEnd: md.Raw{{-1, bb(`](url 'title \'with\' "quotes"')`)}}},
			md.Image{AltText: "link", URL: "url", Title: `title with (brackets)`, RawEnd: md.Raw{{-1, bb(`](url "title with (brackets)")`)}}},
			md.Image{AltText: "link", URL: "url", Title: `title with (brackets)`, RawEnd: md.Raw{{-1, bb(`](url 'title with (brackets)')`)}}},

			md.Image{ReferenceID: "ref id1", AltText: "ref id1", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{ReferenceID: "ref id2", AltText: "ref id2", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{ReferenceID: "ref id3", AltText: "ref id3", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{ReferenceID: "ref id4", AltText: "ref id4", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{ReferenceID: "ref id5", AltText: "ref id5", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{ReferenceID: "ref id6", AltText: "ref id6", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{ReferenceID: "ref id7", AltText: "ref id7", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{ReferenceID: "ref id8", AltText: "ref id8", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{ReferenceID: "ref id9", AltText: "ref id9", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{ReferenceID: "ref id10", AltText: "ref id10", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{ReferenceID: "ref id11", AltText: "ref id11", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{ReferenceID: "ref id12", AltText: "ref id12", RawEnd: md.Raw{{-1, bb("]")}}},
		}, head(19)),
		lines("image/incomplete.md", spans{
			md.Image{ReferenceID: "ref undefined", AltText: "ref undefined", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{ReferenceID: "ref 1", AltText: "ref 1", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{ReferenceID: "ref undefined", AltText: "ref undefined", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{ReferenceID: "ref 1", AltText: "ref 1", RawEnd: md.Raw{{-1, bb("]")}}},
		}, head(8)),
		blocks("image/link_text_with_newline.md", spans{
			md.Image{AltText: "link\ntext", URL: "url1", RawEnd: md.Raw{{-1, bb("](url1)")}}},
			md.Image{ReferenceID: "ref id", AltText: "ref\nid", RawEnd: md.Raw{{-1, bb("][]")}}},
			md.Image{ReferenceID: "ref id", AltText: "ref\nid", RawEnd: md.Raw{{-1, bb("]")}}},
		}, head(9)),
		lines("image/link_with_parenthesis.md", spans{
			md.Image{URL: "url", AltText: "bad link", RawEnd: md.Raw{{-1, bb("](url)")}}},
			md.Image{URL: `url\`, AltText: "bad link", RawEnd: md.Raw{{-1, bb(`](url\)`)}}},
			md.Image{URL: `url)`, AltText: "link", Title: "title", RawEnd: md.Raw{{-1, bb(`](<url)> "title")`)}}},
		}),
		// NOTE(akavel): below test is not really interesting for us
		// here now.
		// lines("image/multiple_ref_id_definitions.md", spans{}),
		lines("image/nested_images.md", spans{
			md.Image{AltText: "link2", URL: "url2", RawEnd: md.Raw{{-1, bb("](url2)")}}},
		}),
		// NOTE(akavel): below test is not really interesting for us
		// here now.
		// lines("image/ref_case_sensitivity.md", spans{}),
		blocks("image/ref_id_matching.md", spans{
			md.Image{ReferenceID: "ref id", AltText: "link", RawEnd: md.Raw{{-1, bb("][ref id]")}}},
			md.Image{ReferenceID: "ref id", AltText: "link", RawEnd: md.Raw{{-1, bb("][ref   id]")}}},
			md.Image{ReferenceID: "ref id", AltText: "link", RawEnd: md.Raw{{-1, bb("][  ref id  ]")}}},
			md.Image{ReferenceID: "ref id", AltText: "link", RawEnd: md.Raw{{-1, bb("][ref\n   id]")}}},
			md.Image{ReferenceID: "ref id", AltText: "ref id", RawEnd: md.Raw{{-1, bb("][]")}}},
			md.Image{ReferenceID: "ref id", AltText: "ref   id", RawEnd: md.Raw{{-1, bb("][]")}}},
			md.Image{ReferenceID: "ref id", AltText: "  ref id  ", RawEnd: md.Raw{{-1, bb("][]")}}},
			md.Image{ReferenceID: "ref id", AltText: "ref\n   id", RawEnd: md.Raw{{-1, bb("][]")}}},
			md.Image{ReferenceID: "ref id", AltText: "ref id", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{ReferenceID: "ref id", AltText: "ref   id", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{ReferenceID: "ref id", AltText: "  ref id  ", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{ReferenceID: "ref id", AltText: "ref\n   id", RawEnd: md.Raw{{-1, bb("]")}}},
		}, head(18)),
		// NOTE(akavel): below tests are not really interesting for us
		// here now.
		// lines("image/ref_link.md", spans{}),
		// lines("image/ref_link_empty.md", spans{}),
		// lines("image/ref_link_self.md", spans{}),
		lines("image/ref_link_with_2separating_spaces.md", spans{
			md.Image{AltText: "link", ReferenceID: "ref", RawEnd: md.Raw{{-1, bb("]  [ref]")}}},
		}, head(2)),
		blocks("image/ref_link_with_separating_newline.md", spans{
			md.Image{AltText: "link", ReferenceID: "ref", RawEnd: md.Raw{{-1, bb("]\n[ref]")}}},
		}, head(3)),
		lines("image/ref_link_with_separating_space.md", spans{
			md.Image{AltText: "link", ReferenceID: "ref", RawEnd: md.Raw{{-1, bb("] [ref]")}}},
		}, head(2)),
		// NOTE(akavel): below test is not really interesting for us
		// here now.
		// lines("image/ref_resolution_within_other_blocks.md", spans{}),
		lines("image/square_brackets_in_link_or_ref.md", spans{
			md.Link{ReferenceID: "1", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
			md.Link{ReferenceID: "2", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
			md.Image{ReferenceID: "2", AltText: "2", RawEnd: md.Raw{{-1, bb("]")}}},
			// TODO(akavel): make sure we handled escaping properly in cases below
			md.Image{URL: "url", AltText: `link[1]`, RawEnd: md.Raw{{-1, bb(`](url)`)}}},
			md.Image{URL: "url", AltText: `link[2]`, RawEnd: md.Raw{{-1, bb(`](url)`)}}},
			md.Image{URL: "url", AltText: `link![2]`, RawEnd: md.Raw{{-1, bb(`](url)`)}}},
			md.Link{ReferenceID: "2", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
			md.Image{ReferenceID: "link", AltText: "link", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Link{ReferenceID: "3", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
			md.Image{ReferenceID: "link", AltText: "link", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Link{ReferenceID: "4", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
			// TODO(akavel): make sure we handled escaping properly in cases below
			md.Image{ReferenceID: `ref\[3\]`, AltText: `link`, RawEnd: md.Raw{{-1, bb(`][ref\[3\]]`)}}},
			md.Image{ReferenceID: `ref\[4\]`, AltText: `link`, RawEnd: md.Raw{{-1, bb(`][ref\[4\]]`)}}},
			md.Image{ReferenceID: "link", AltText: "link", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Link{ReferenceID: "5", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
			md.Image{ReferenceID: "ref", AltText: "link", RawEnd: md.Raw{{-1, bb("][ref]")}}},
			md.Image{ReferenceID: `ref\[5`, AltText: `link`, RawEnd: md.Raw{{-1, bb(`][ref\[5]`)}}},
			md.Image{ReferenceID: `ref\]6`, AltText: `link`, RawEnd: md.Raw{{-1, bb(`][ref\]6]`)}}},
		}, head(16)),
		lines("image/two_consecutive_refs.md", spans{
			md.Image{ReferenceID: "two", AltText: "one", RawEnd: md.Raw{{-1, bb("][two]")}}},
			md.Link{ReferenceID: "three", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
			md.Image{ReferenceID: "four", AltText: "one", RawEnd: md.Raw{{-1, bb("][four]")}}},
			md.Link{ReferenceID: "three", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
		}, head(4)),
		// NOTE(akavel): below test is not really interesting for us
		// here now.
		// image/unused_ref.md
		lines("image/url_escapes.md", spans{
			md.Image{AltText: "link", URL: `url\_\:\$\?`, RawEnd: md.Raw{{-1, bb(`](url\_\:\$\?)`)}}},
			md.Image{AltText: "link", URL: `http://g&ouml;&ouml;gle.com`, RawEnd: md.Raw{{-1, bb(`](http://g&ouml;&ouml;gle.com)`)}}},
		}, head(2)),
		lines("image/url_in_angle_brackets.md", spans{
			md.Image{AltText: "link", URL: "url", RawEnd: md.Raw{{-1, bb(`](<url>)`)}}},
			md.Image{AltText: "link", URL: "url(", RawEnd: md.Raw{{-1, bb(`](<url(>)`)}}},
			md.Image{AltText: "link", URL: "url)", RawEnd: md.Raw{{-1, bb(`](<url)>)`)}}},
			md.Image{AltText: "link", URL: "url)", Title: "title", RawEnd: md.Raw{{-1, bb(`](<url)> "title")`)}}},
		}, head(4)),
		lines("image/url_special_chars.md", spans{
			md.Image{AltText: "link", URL: `url*#$%^&\~`, RawEnd: md.Raw{{-1, bb(`](url*#$%^&\~)`)}}},
			md.Image{ReferenceID: "ref id1", AltText: "link", RawEnd: md.Raw{{-1, bb("][ref id1]")}}},
			md.Image{ReferenceID: "ref id1", AltText: "ref id1", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{ReferenceID: "link", AltText: "link", RawEnd: md.Raw{{-1, bb("]")}}},
		}, head(8)),
		blocks("image/url_whitespace.md", spans{
			md.Image{AltText: "link", ReferenceID: "link", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{AltText: "link", ReferenceID: "link", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{AltText: "link", URL: "url1", RawEnd: md.Raw{{-1, bb("](<url 1>)")}}},
			md.Image{AltText: "link", URL: "url1", RawEnd: md.Raw{{-1, bb("](<url \n   1>)")}}},
		}, head(6)),
		lines("image/vs_code.md", spans{
			md.Code{bb("code")},
			md.Code{bb("containing ![image](url)")},
			md.Code{bb("containing ![image][ref]")},
			md.Link{ReferenceID: "ref", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
			md.Code{bb("intertwined](url) with code")},
			md.Code{bb("intertwined ![with code")},
		}),
		lines("image/vs_emph.md", spans{
			md.Image{URL: "url", AltText: "image containing *em* text", RawEnd: md.Raw{{-1, bb("](url)")}}},
			md.Image{URL: "url", AltText: "image containing **strong** text", RawEnd: md.Raw{{-1, bb("](url)")}}},
			md.Image{URL: "url", AltText: "image containing _em_ text", RawEnd: md.Raw{{-1, bb("](url)")}}},
			md.Image{URL: "url", AltText: "image containing __strong__ text", RawEnd: md.Raw{{-1, bb("](url)")}}},

			emB("*"),
			md.Image{AltText: "image", URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}},
			emE("*"),
			emB("**"),
			md.Image{AltText: "image", URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}},
			emE("**"),
			emB("_"),
			md.Image{AltText: "image", URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}},
			emE("_"),
			emB("__"),
			md.Image{AltText: "image", URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}},
			emE("__"),

			md.Image{URL: "url", AltText: "image *intertwined", RawEnd: md.Raw{{-1, bb("](url)")}}},
			md.Image{URL: "url", AltText: "with em* text", RawEnd: md.Raw{{-1, bb("](url)")}}},
			md.Image{URL: "url", AltText: "image **intertwined", RawEnd: md.Raw{{-1, bb("](url)")}}},
			md.Image{URL: "url", AltText: "with strong** text", RawEnd: md.Raw{{-1, bb("](url)")}}},
			md.Image{URL: "url", AltText: "image _intertwined", RawEnd: md.Raw{{-1, bb("](url)")}}},
			md.Image{URL: "url", AltText: "with em_ text", RawEnd: md.Raw{{-1, bb("](url)")}}},
			md.Image{URL: "url", AltText: "image __intertwined", RawEnd: md.Raw{{-1, bb("](url)")}}},
			md.Image{URL: "url", AltText: "with strong__ text", RawEnd: md.Raw{{-1, bb("](url)")}}},
		}),
		lines("image/within_link.md", spans{
			md.Link{ReferenceID: "![kitten 1]", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{ReferenceID: "kitten 1", AltText: "kitten 1", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
			md.Link{ReferenceID: "![kitten 2]", RawEnd: md.Raw{{-1, bb("]")}}},
			md.Image{ReferenceID: "kitten 2", AltText: "kitten 2", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
		}, head(5)),
		lines("link/direct_link.md", spans{
			md.Link{URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}},
			md.End{},
			md.Link{URL: "url", Title: "title", RawEnd: md.Raw{{-1, bb(`](url "title")`)}}},
			md.End{},
		}),
		lines("link/direct_link_with_2separating_spaces.md", spans{
			md.Link{URL: "/example.html", RawEnd: md.Raw{{-1, bb("]  (/example.html)")}}},
			md.End{},
		}),
		blocks("link/direct_link_with_separating_newline.md", spans{
			md.Link{URL: "/example.html", RawEnd: md.Raw{{-1, bb("]\n(/example.html)")}}},
			md.End{},
		}),
		lines("link/direct_link_with_separating_space.md", spans{
			md.Link{URL: "http://example.net", RawEnd: md.Raw{{-1, bb("] (http://example.net)")}}},
			md.End{},
		}),
		lines("link/incomplete.md", spans{
			md.Link{ReferenceID: "ref undefined", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
			md.Link{ReferenceID: "ref 1", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
			md.Link{ReferenceID: "ref undefined", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
			md.Link{ReferenceID: "ref 1", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
		}, head(8)),
		blocks("link/link_text_with_newline.md", spans{
			md.Link{URL: "url1", RawEnd: md.Raw{{-1, bb("](url1)")}}},
			md.End{},
			md.Link{ReferenceID: "ref id", RawEnd: md.Raw{{-1, bb("][]")}}},
			md.End{},
			md.Link{ReferenceID: "ref id", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
		}, head(9)),
		lines("link/link_title.md", spans{
			md.Link{URL: "url", Title: "title", RawEnd: md.Raw{{-1, bb(`](url "title")`)}}},
			md.End{},
			md.Link{URL: "url", Title: "title", RawEnd: md.Raw{{-1, bb(`](url 'title')`)}}},
			md.End{},
			md.Link{URL: "url", Title: `title 'with' "quotes"`, RawEnd: md.Raw{{-1, bb(`](url "title 'with' \"quotes\"")`)}}},
			md.End{},
			md.Link{URL: "url", Title: `title 'with' "quotes"`, RawEnd: md.Raw{{-1, bb(`](url 'title \'with\' "quotes"')`)}}},
			md.End{},
			md.Link{URL: "url", Title: "title with (brackets)", RawEnd: md.Raw{{-1, bb(`](url "title with (brackets)")`)}}},
			md.End{},
			md.Link{URL: "url", Title: "title with (brackets)", RawEnd: md.Raw{{-1, bb(`](url 'title with (brackets)')`)}}},
			md.End{},
		}, head(6)),
		lines("link/link_with_parenthesis.md", spans{
			md.Link{URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}},
			md.End{},
			md.Link{URL: `url\`, RawEnd: md.Raw{{-1, bb(`](url\)`)}}},
			md.End{},
			md.Link{URL: `url)`, Title: "title", RawEnd: md.Raw{{-1, bb(`](<url)> "title")`)}}},
			md.End{},
		}),
		// NOTE(akavel): below test is not really interesting for us
		// here now.
		// link/multiple_ref_id_definitions.md
		lines("link/nested_links.md", spans{
			md.Link{URL: "url2", RawEnd: md.Raw{{-1, bb("](url2)")}}},
			md.End{},
		}),
		// NOTE(akavel): below test is not really interesting for us
		// here now.
		// link/ref_case_sensitivity.md
		blocks("link/ref_id_matching.md", spans{
			md.Link{ReferenceID: "ref id", RawEnd: md.Raw{{-1, bb("][ref id]")}}}, md.End{},
			md.Link{ReferenceID: "ref id", RawEnd: md.Raw{{-1, bb("][ref   id]")}}}, md.End{},
			md.Link{ReferenceID: "ref id", RawEnd: md.Raw{{-1, bb("][  ref id  ]")}}}, md.End{},
			md.Link{ReferenceID: "ref id", RawEnd: md.Raw{{-1, bb("][ref\n   id]")}}}, md.End{},

			md.Link{ReferenceID: "ref id", RawEnd: md.Raw{{-1, bb("][]")}}}, md.End{},
			md.Link{ReferenceID: "ref id", RawEnd: md.Raw{{-1, bb("][]")}}}, md.End{},
			md.Link{ReferenceID: "ref id", RawEnd: md.Raw{{-1, bb("][]")}}}, md.End{},
			md.Link{ReferenceID: "ref id", RawEnd: md.Raw{{-1, bb("][]")}}}, md.End{},

			md.Link{ReferenceID: "ref id", RawEnd: md.Raw{{-1, bb("]")}}}, md.End{},
			md.Link{ReferenceID: "ref id", RawEnd: md.Raw{{-1, bb("]")}}}, md.End{},
			md.Link{ReferenceID: "ref id", RawEnd: md.Raw{{-1, bb("]")}}}, md.End{},
			md.Link{ReferenceID: "ref id", RawEnd: md.Raw{{-1, bb("]")}}}, md.End{},
		}, head(18)),
		// NOTE(akavel): below tests are not really interesting for us
		// here now.
		// link/ref_link.md
		// link/ref_link_empty.md
		// link/ref_link_self.md
		lines("link/ref_link_with_2separating_spaces.md", spans{
			md.Link{ReferenceID: "ref", RawEnd: md.Raw{{-1, bb("]  [ref]")}}},
			md.End{},
		}, head(2)),
		blocks("link/ref_link_with_separating_newline.md", spans{
			md.Link{ReferenceID: "ref", RawEnd: md.Raw{{-1, bb("]\n[ref]")}}},
			md.End{},
		}, head(3)),
		lines("link/ref_link_with_separating_space.md", spans{
			md.Link{ReferenceID: "ref", RawEnd: md.Raw{{-1, bb("] [ref]")}}},
			md.End{},
		}, head(2)),
		// NOTE(akavel): below test is not really interesting for us
		// here now.
		// link/ref_resolution_within_other_blocks.md
		lines("link/square_brackets_in_link_or_ref.md", spans{
			md.Link{ReferenceID: "1", RawEnd: md.Raw{{-1, bb("]")}}}, md.End{},
			md.Link{ReferenceID: "2", RawEnd: md.Raw{{-1, bb("]")}}}, md.End{},
			md.Link{URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}}, md.End{},
			md.Link{URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}}, md.End{},
			md.Link{ReferenceID: "link", RawEnd: md.Raw{{-1, bb("]")}}}, md.End{},
			md.Link{ReferenceID: "3", RawEnd: md.Raw{{-1, bb("]")}}}, md.End{},
			md.Link{ReferenceID: "link", RawEnd: md.Raw{{-1, bb("]")}}}, md.End{},
			md.Link{ReferenceID: "4", RawEnd: md.Raw{{-1, bb("]")}}}, md.End{},
			md.Link{ReferenceID: `ref\[3\]`, RawEnd: md.Raw{{-1, bb(`][ref\[3\]]`)}}}, md.End{},
			md.Link{ReferenceID: `ref\[4\]`, RawEnd: md.Raw{{-1, bb(`][ref\[4\]]`)}}}, md.End{},
			md.Link{ReferenceID: "link", RawEnd: md.Raw{{-1, bb("]")}}}, md.End{},
			md.Link{ReferenceID: "5", RawEnd: md.Raw{{-1, bb("]")}}}, md.End{},
			md.Link{ReferenceID: "ref", RawEnd: md.Raw{{-1, bb("][ref]")}}}, md.End{},
			md.Link{ReferenceID: `ref\[5`, RawEnd: md.Raw{{-1, bb(`][ref\[5]`)}}}, md.End{},
			md.Link{ReferenceID: `ref\]6`, RawEnd: md.Raw{{-1, bb(`][ref\]6]`)}}}, md.End{},
		}, head(13)),
		lines("link/two_consecutive_refs.md", spans{
			md.Link{ReferenceID: `two`, RawEnd: md.Raw{{-1, bb(`][two]`)}}}, md.End{},
			md.Link{ReferenceID: `three`, RawEnd: md.Raw{{-1, bb(`]`)}}}, md.End{},
			md.Link{ReferenceID: `four`, RawEnd: md.Raw{{-1, bb(`][four]`)}}}, md.End{},
			md.Link{ReferenceID: `three`, RawEnd: md.Raw{{-1, bb(`]`)}}}, md.End{},
		}, head(4)),
		// NOTE(akavel): below test is not really interesting for us
		// here now.
		// link/unused_ref.md
		lines("link/url_escapes.md", spans{
			// TODO(akavel): make sure we handled escaping properly in cases below
			md.Link{URL: `url\_\:\$\?`, RawEnd: md.Raw{{-1, bb(`](url\_\:\$\?)`)}}}, md.End{},
			md.Link{URL: `http://g&ouml;&ouml;gle.com`, RawEnd: md.Raw{{-1, bb(`](http://g&ouml;&ouml;gle.com)`)}}}, md.End{},
		}, head(2)),
		lines("link/url_in_angle_brackets.md", spans{
			md.Link{URL: `url`, RawEnd: md.Raw{{-1, bb(`](<url>)`)}}}, md.End{},
			md.Link{URL: `url(`, RawEnd: md.Raw{{-1, bb(`](<url(>)`)}}}, md.End{},
			md.Link{URL: `url)`, RawEnd: md.Raw{{-1, bb(`](<url)>)`)}}}, md.End{},
			md.Link{URL: `url)`, Title: "title", RawEnd: md.Raw{{-1, bb(`](<url)> "title")`)}}}, md.End{},
		}, head(4)),
		lines("link/url_special_chars.md", spans{
			md.Link{URL: `url*#$%^&\~`, RawEnd: md.Raw{{-1, bb(`](url*#$%^&\~)`)}}}, md.End{},
			md.Link{ReferenceID: "ref id1", RawEnd: md.Raw{{-1, bb(`][ref id1]`)}}}, md.End{},
			md.Link{ReferenceID: "ref id1", RawEnd: md.Raw{{-1, bb(`]`)}}}, md.End{},
			md.Link{ReferenceID: "link", RawEnd: md.Raw{{-1, bb(`]`)}}}, md.End{},
		}, head(8)),
		blocks("link/url_whitespace.md", spans{
			md.Link{ReferenceID: "link", RawEnd: md.Raw{{-1, bb(`]`)}}}, md.End{},
			md.Link{ReferenceID: "link", RawEnd: md.Raw{{-1, bb(`]`)}}}, md.End{},
			md.Link{URL: "url1", RawEnd: md.Raw{{-1, bb("](<url 1>)")}}}, md.End{},
			md.Link{URL: "url1", RawEnd: md.Raw{{-1, bb("](<url \n   1>)")}}}, md.End{},
		}, head(6)),
		lines("link/vs_code.md", spans{
			md.Link{URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}},
			md.Code{bb("code")},
			md.End{},
			md.Code{bb("containing [link](url)")},
			md.Code{bb("containing [link][ref]")},
			md.Link{ReferenceID: "ref", RawEnd: md.Raw{{-1, bb("]")}}},
			md.End{},
			md.Code{bb("intertwined](url) with code")},
			md.Code{bb("intertwined [with code")},
		}),
		lines("link/vs_emph.md", spans{
			md.Link{URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}},
			emB("*"), emE("*"),
			md.End{},
			md.Link{URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}},
			emB("**"), emE("**"),
			md.End{},
			md.Link{URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}},
			emB("_"), emE("_"),
			md.End{},
			md.Link{URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}},
			emB("__"), emE("__"),
			md.End{},

			emB("*"),
			md.Link{URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}}, md.End{},
			emE("*"),
			emB("**"),
			md.Link{URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}}, md.End{},
			emE("**"),
			emB("_"),
			md.Link{URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}}, md.End{},
			emE("_"),
			emB("__"),
			md.Link{URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}}, md.End{},
			emE("__"),

			md.Link{URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}}, md.End{},
			emB("*"), emE("*"),
			md.Link{URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}}, md.End{},
			emB("**"), emE("**"),
			md.Link{URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}}, md.End{},
			emB("_"), emE("_"),
			md.Link{URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}}, md.End{},
			emB("__"), emE("__"),
		}),
		lines("link/vs_image.md", spans{
			md.Link{URL: "url", RawEnd: md.Raw{{-1, bb("](url)")}}},
			md.Image{AltText: "image", URL: "/image.jpg", RawEnd: md.Raw{{-1, bb("](/image.jpg)")}}},
			md.End{},
		}),
	}
	for _, c := range cases {
		fmt.Printf("\ncase %s\n", c.fname)
		tags := []md.Tag{}
		for _, b := range c.blocks {
			tags = append(tags, Parse(b, nil)...)
		}
		spans := []md.Tag{}
		for _, t := range tags {
			if _, ok := t.(md.Prose); !ok {
				spans = append(spans, t)
			}
		}
		if !reflect.DeepEqual(c.spans, spans) {
			test.Errorf("case %s expected vs. got DIFF:\n%s",
				c.fname,
				diff.Diff(spew.Sdump(c.spans), spew.Sdump(spans)))
		}
	}
}
Пример #22
0
func TestFiles(test *testing.T) {
	type block struct {
		n   int
		tag string
	}
	type blocks []block
	cases := []struct {
		path string
		blocks
	}{
		{
			"atx_header/blank_text.md",
			blocks{
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
			},
		},
		{
			"atx_header/enclosed_blank_text.md",
			blocks{
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
			},
		},
		{
			"atx_header/hash_in_text.md",
			blocks{
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
			},
		},
		{
			"atx_header/left_only.md",
			blocks{
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
			},
		},
		{
			"atx_header/left_right.md",
			blocks{
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
			},
		},
		{
			"atx_header/more_than_six_hashes.md",
			blocks{
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
			},
		},
		{
			"atx_header/space_in_text.md",
			blocks{
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
			},
		},
		{
			"atx_header/span_in_text.md",
			blocks{
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
			},
		},
		{
			"blockquote/containing_atx_header.md",
			blocks{{6, "md.QuoteBlock"}},
		},
		{
			"blockquote/containing_blockquote.md",
			blocks{{7, "md.QuoteBlock"}},
		},
		{
			"blockquote/containing_codeblock.md",
			blocks{{12, "md.QuoteBlock"}},
		},
		{
			"blockquote/containing_hr.md",
			blocks{{6, "md.QuoteBlock"}},
		},
		{
			"blockquote/containing_list.md",
			blocks{{20, "md.QuoteBlock"}},
		},
		{
			"blockquote/containing_setext_header.md",
			blocks{{9, "md.QuoteBlock"}},
		},
		{
			"blockquote/followed_by_atx_header.md",
			blocks{
				{3, "md.QuoteBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{3, "md.QuoteBlock"},
			},
		},
		{
			"blockquote/followed_by_codeblock.md",
			blocks{
				{3, "md.QuoteBlock"},
				{1, "md.CodeBlock"},
				{1, "md.NullBlock"},
				{3, "md.QuoteBlock"},
			},
		},
		{
			"blockquote/followed_by_hr.md",
			blocks{
				{3, "md.QuoteBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{2, "md.QuoteBlock"},
				{1, "md.HorizontalRuleBlock"},
			},
		},
		{
			"blockquote/followed_by_list.md",
			blocks{
				{3, "md.QuoteBlock"},
				{2, "md.OrderedListBlock"},
				{7, "md.QuoteBlock"},
				{2, "md.UnorderedListBlock"},
				{7, "md.QuoteBlock"},
				{2, "md.UnorderedListBlock"},
				{7, "md.QuoteBlock"},
				{2, "md.UnorderedListBlock"},
				{3, "md.QuoteBlock"},
			},
		},
		{
			"blockquote/followed_by_para.md",
			blocks{
				{3, "md.QuoteBlock"},
				{2, "md.ParagraphBlock"},
				{3, "md.QuoteBlock"},
			},
		},
		{
			"blockquote/followed_by_setext_header.md",
			blocks{
				{3, "md.QuoteBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{4, "md.QuoteBlock"},
			},
		},
		{
			"blockquote/indented_differently1.md",
			blocks{{6, "md.QuoteBlock"}},
		},
		{
			"blockquote/indented_differently2.md",
			blocks{{11, "md.QuoteBlock"}},
		},
		{
			"blockquote/many_level_nesting.md",
			blocks{
				{2, "md.ParagraphBlock"},
				{26, "md.QuoteBlock"},
				{1, "md.ParagraphBlock"},
			},
		},
		{
			"blockquote/many_lines.md",
			blocks{{3, "md.QuoteBlock"}},
		},
		{
			"blockquote/many_lines_lazy.md",
			blocks{{3, "md.QuoteBlock"}},
		},
		{
			"blockquote/many_paras.md",
			blocks{{11, "md.QuoteBlock"}},
		},
		{
			"blockquote/many_paras_2blank.md",
			blocks{{13, "md.QuoteBlock"}},
		},
		{
			"blockquote/many_paras_2blank_lazy.md",
			blocks{
				{4, "md.QuoteBlock"},
				{1, "md.NullBlock"},
				{4, "md.QuoteBlock"},
				{1, "md.NullBlock"},
				{3, "md.QuoteBlock"},
			},
		},
		{
			"blockquote/many_paras_2blank_lazy2.md",
			blocks{
				{4, "md.QuoteBlock"},
				{1, "md.NullBlock"},
				{4, "md.QuoteBlock"},
				{1, "md.NullBlock"},
				{3, "md.QuoteBlock"},
			},
		},
		{
			"blockquote/many_paras_lazy.md",
			blocks{{11, "md.QuoteBlock"}},
		},
		{
			"blockquote/many_paras_lazy2.md",
			blocks{{11, "md.QuoteBlock"}},
		},
		{
			"blockquote/no_space_after_gt.md",
			blocks{
				{2, "md.ParagraphBlock"},
				{2, "md.QuoteBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.QuoteBlock"},
			},
		},
		{
			"blockquote/one_line.md",
			blocks{{1, "md.QuoteBlock"}},
		},
		{
			"blockquote/space_before_gt.md",
			blocks{
				{2, "md.ParagraphBlock"},
				{2, "md.QuoteBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.QuoteBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.QuoteBlock"},
				{2, "md.ParagraphBlock"},
				{1, "md.CodeBlock"},
			},
		},
		{
			"codeblock/followed_by_para.md",
			blocks{
				{2, "md.ParagraphBlock"},
				{2, "md.CodeBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.CodeBlock"},
				{1, "md.NullBlock"},
				{1, "md.ParagraphBlock"},
			},
		},
		{
			"codeblock/html_escaping.md",
			blocks{
				{2, "md.ParagraphBlock"},
				{1, "md.CodeBlock"},
				{1, "md.NullBlock"},
			},
		},
		{
			"codeblock/many_lines.md",
			blocks{{3, "md.CodeBlock"}},
		},
		{
			"codeblock/more_than_four_leading_space.md",
			blocks{
				{1, "md.CodeBlock"},
				{1, "md.NullBlock"},
				{2, "md.ParagraphBlock"},
				{3, "md.CodeBlock"},
			},
		},
		{
			"codeblock/one_blank_line_bw_codeblocks.md",
			blocks{{7, "md.CodeBlock"}},
		},
		{
			"codeblock/one_line.md",
			blocks{{1, "md.CodeBlock"}},
		},
		{
			"codeblock/two_blank_lines_bw_codeblocks.md",
			blocks{
				{3, "md.CodeBlock"},
				{1, "md.NullBlock"},
				{1, "md.NullBlock"},
				{3, "md.CodeBlock"},
			},
		},
		{
			"codeblock/vs_atx_header.md",
			blocks{
				{1, "md.CodeBlock"},
				{1, "md.NullBlock"},
				{2, "md.ParagraphBlock"},
				{1, "md.CodeBlock"},
				{1, "md.NullBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.CodeBlock"},
			},
		},
		{
			"codeblock/vs_blockquote.md",
			blocks{
				{1, "md.CodeBlock"},
				{1, "md.NullBlock"},
				{2, "md.ParagraphBlock"},
				{1, "md.CodeBlock"},
				{1, "md.NullBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.CodeBlock"},
			},
		},
		{
			"codeblock/vs_hr.md",
			blocks{
				{2, "md.ParagraphBlock"},
				{1, "md.CodeBlock"},
				{1, "md.NullBlock"},
			},
		},
		{
			"codeblock/vs_list.md",
			blocks{
				{2, "md.ParagraphBlock"},
				{2, "md.CodeBlock"},
				{1, "md.NullBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.CodeBlock"},
				{1, "md.NullBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.CodeBlock"},
				{1, "md.NullBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.CodeBlock"},
				{1, "md.NullBlock"},
			},
		},
		{
			"horizontal_rule/end_with_space.md",
			blocks{
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
			},
		},
		{
			"horizontal_rule/followed_by_block.md",
			blocks{
				{1, "md.HorizontalRuleBlock"},
				{2, "md.ParagraphBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{2, "md.QuoteBlock"},
				{1, "md.HorizontalRuleBlock"},
				{2, "md.OrderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{2, "md.UnorderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{2, "md.UnorderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.CodeBlock"},
				{1, "md.NullBlock"},

				{1, "md.HorizontalRuleBlock"},
				{2, "md.ParagraphBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{2, "md.QuoteBlock"},
				{1, "md.HorizontalRuleBlock"},
				{2, "md.OrderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{2, "md.UnorderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{2, "md.UnorderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.CodeBlock"},
				{1, "md.NullBlock"},

				{1, "md.HorizontalRuleBlock"},
				{2, "md.ParagraphBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{2, "md.QuoteBlock"},
				{1, "md.HorizontalRuleBlock"},
				{2, "md.OrderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{2, "md.UnorderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{2, "md.UnorderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.CodeBlock"},
				{1, "md.NullBlock"},
			},
		},
		{
			"horizontal_rule/loose.md",
			blocks{
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
			},
		},
		{
			"horizontal_rule/sparse.md",
			blocks{
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
			},
		},
		{
			"horizontal_rule/start_with_space.md",
			blocks{
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
			},
		},
		{
			"horizontal_rule/tight.md",
			blocks{
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.HorizontalRuleBlock"},
			},
		},
		{
			"ordered_list/all_items_loose.md",
			blocks{{7, "md.OrderedListBlock"}},
		},
		{
			"ordered_list/all_items_tight.md",
			blocks{{4, "md.OrderedListBlock"}},
		},
		{
			"ordered_list/all_items_tight_even_with_blanks.md",
			blocks{{7, "md.OrderedListBlock"}},
		},
		{
			"ordered_list/at_end_of_parent_without_blank_line.md",
			blocks{
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{8, "md.UnorderedListBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{5, "md.OrderedListBlock"},
			},
		},
		{
			"ordered_list/bw_unordered_lists.md",
			blocks{
				{3, "md.UnorderedListBlock"},
				{3, "md.OrderedListBlock"},
				{3, "md.UnorderedListBlock"},
			},
		},
		{
			"ordered_list/followed_by_hr.md",
			blocks{
				{4, "md.OrderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{5, "md.OrderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{6, "md.OrderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
			},
		},
		{
			"ordered_list/followed_by_list.md",
			blocks{
				{4, "md.OrderedListBlock"},
				{2, "md.UnorderedListBlock"},
				{5, "md.OrderedListBlock"},
				{2, "md.UnorderedListBlock"},
				{6, "md.OrderedListBlock"},
				{1, "md.UnorderedListBlock"},
			},
		},
		{
			"ordered_list/indent_and_sub_blocks.md",
			blocks{
				{6, "md.OrderedListBlock"},
				{2, "md.ParagraphBlock"},
				{6, "md.OrderedListBlock"},
				{2, "md.QuoteBlock"},
				{6, "md.OrderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{6, "md.OrderedListBlock"},
				{2, "md.UnorderedListBlock"},
				{12, "md.OrderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{2, "md.OrderedListBlock"},
				{1, "md.CodeBlock"},
				{1, "md.NullBlock"},
			},
		},
		{
			"ordered_list/list_ends_with_2blanks.md",
			blocks{
				{4, "md.OrderedListBlock"},
				{1, "md.NullBlock"},
				{10, "md.OrderedListBlock"},
				{1, "md.NullBlock"},
				{1, "md.CodeBlock"},
			},
		},
		{
			"ordered_list/many_level_nesting.md",
			blocks{
				{2, "md.ParagraphBlock"},
				{22, "md.OrderedListBlock"},
				{1, "md.ParagraphBlock"},
			},
		},
		{
			"ordered_list/many_lines.md",
			blocks{{5, "md.OrderedListBlock"}},
		},
		{
			"ordered_list/many_lines_lazy.md",
			blocks{{5, "md.OrderedListBlock"}},
		},
		{
			"ordered_list/many_paras.md",
			blocks{{9, "md.OrderedListBlock"}},
		},
		{
			"ordered_list/many_paras_2blank.md",
			blocks{
				{5, "md.OrderedListBlock"},
				{1, "md.NullBlock"},
				{4, "md.ParagraphBlock"},
			},
		},
		{
			"ordered_list/many_paras_2blank_lazy.md",
			blocks{
				{5, "md.OrderedListBlock"},
				{1, "md.NullBlock"},
				{4, "md.ParagraphBlock"},
			},
		},
		{
			"ordered_list/many_paras_lazy.md",
			blocks{{9, "md.OrderedListBlock"}},
		},
		{
			"ordered_list/no_space_after_number.md",
			blocks{
				{2, "md.ParagraphBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.ParagraphBlock"},
				{1, "md.ParagraphBlock"},
			},
		},
		{
			"ordered_list/no_space_before_number.md",
			blocks{
				{2, "md.ParagraphBlock"},
				{2, "md.OrderedListBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.OrderedListBlock"},
				{2, "md.ParagraphBlock"},
				{1, "md.OrderedListBlock"},
			},
		},
		{
			"ordered_list/numbering_from_two.md",
			blocks{{11, "md.OrderedListBlock"}},
		},
		{
			"ordered_list/numbering_not_in_order.md",
			blocks{{12, "md.OrderedListBlock"}},
		},
		{
			"ordered_list/numbers_left_aligned.md",
			blocks{{12, "md.OrderedListBlock"}},
		},
		{
			"ordered_list/numbers_right_aligned.md",
			blocks{{12, "md.OrderedListBlock"}},
		},
		{
			"ordered_list/numbers_wiggly.md",
			blocks{{12, "md.OrderedListBlock"}},
		},
		{
			"ordered_list/one_line.md",
			blocks{{3, "md.OrderedListBlock"}},
		},
		{
			"ordered_list/some_items_loose.md",
			blocks{
				{2, "md.ParagraphBlock"},
				{6, "md.OrderedListBlock"},
				{2, "md.ParagraphBlock"},
				{8, "md.OrderedListBlock"},
				{2, "md.ParagraphBlock"},
				{10, "md.OrderedListBlock"},
				{2, "md.ParagraphBlock"},
				{6, "md.OrderedListBlock"},
				{1, "md.ParagraphBlock"},
			},
		},
		{
			"ordered_list/space_before_number.md",
			blocks{
				{2, "md.ParagraphBlock"},
				{2, "md.OrderedListBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.OrderedListBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.OrderedListBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.OrderedListBlock"},
				{2, "md.ParagraphBlock"},
				{1, "md.CodeBlock"},
				{1, "md.NullBlock"},
			},
		},
		{
			"ordered_list/three_paras_loose.md",
			blocks{{15, "md.OrderedListBlock"}},
		},
		{
			"ordered_list/three_paras_tight.md",
			blocks{{13, "md.OrderedListBlock"}},
		},
		{
			"ordered_list/two_paras_loose.md",
			blocks{{11, "md.OrderedListBlock"}},
		},
		{
			"ordered_list/with_atx_header.md",
			blocks{
				{16, "md.OrderedListBlock"},
				{1, "md.AtxHeaderBlock"},
			},
		},
		{
			"ordered_list/with_blockquote.md",
			blocks{
				{8, "md.OrderedListBlock"},
				{1, "md.QuoteBlock"},
			},
		},
		{
			"ordered_list/with_codeblock.md",
			blocks{
				{8, "md.OrderedListBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.OrderedListBlock"},
				{1, "md.CodeBlock"},
			},
		},
		{
			"ordered_list/with_para.md",
			blocks{
				{10, "md.OrderedListBlock"},
				{1, "md.ParagraphBlock"},
			},
		},
		{
			"ordered_list/with_setext_header.md",
			blocks{
				{25, "md.OrderedListBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{10, "md.OrderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{3, "md.OrderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{3, "md.OrderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{3, "md.OrderedListBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
			},
		},
		// {
		// "paragraph/blanks_within_html_comment.md",
		// blocks{
		// },
		// },
		{
			"paragraph/followed_by_atx_header.md",
			blocks{
				{3, "md.ParagraphBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{3, "md.ParagraphBlock"},
			},
		},
		{
			"paragraph/followed_by_blockquote.md",
			blocks{
				{3, "md.ParagraphBlock"},
				{3, "md.QuoteBlock"},
				{4, "md.ParagraphBlock"},
			},
		},
		{
			"paragraph/followed_by_codeblock.md",
			blocks{
				{3, "md.ParagraphBlock"},
				{2, "md.CodeBlock"},
				{1, "md.NullBlock"},
				{4, "md.ParagraphBlock"},
			},
		},
		{
			"paragraph/followed_by_horizontal_rule.md",
			blocks{
				{3, "md.ParagraphBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{1, "md.NullBlock"},
				{2, "md.ParagraphBlock"},
				{1, "md.HorizontalRuleBlock"},
			},
		},
		{
			"paragraph/followed_by_list.md",
			blocks{
				{3, "md.ParagraphBlock"},
				{2, "md.UnorderedListBlock"},
				{4, "md.ParagraphBlock"},
				{3, "md.ParagraphBlock"},
				{2, "md.OrderedListBlock"},
				{4, "md.ParagraphBlock"},
			},
		},
		{
			"paragraph/followed_by_setext_header.md",
			blocks{
				{3, "md.ParagraphBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{4, "md.ParagraphBlock"},
			},
		},
		{
			"paragraph/simple_para.md",
			blocks{{3, "md.ParagraphBlock"}},
		},
		{
			"paragraph/two_paras_1blank.md",
			blocks{
				{3, "md.ParagraphBlock"},
				{2, "md.ParagraphBlock"},
			},
		},
		{
			"paragraph/two_paras_2blank.md",
			blocks{
				{3, "md.ParagraphBlock"},
				{1, "md.NullBlock"},
				{2, "md.ParagraphBlock"},
			},
		},
		{
			"setext_header/blank_text.md",
			blocks{
				{2, "md.ParagraphBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.ParagraphBlock"},
				{1, "md.HorizontalRuleBlock"},
			},
		},
		{
			"setext_header/enclosed_space_in_underline.md",
			blocks{
				{3, "md.ParagraphBlock"},
				{1, "md.ParagraphBlock"},
				{1, "md.HorizontalRuleBlock"},
			},
		},
		{
			"setext_header/leading_space_in_text.md",
			blocks{
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
			},
		},
		{
			"setext_header/leading_space_in_underline.md",
			blocks{
				{3, "md.ParagraphBlock"},
				{1, "md.ParagraphBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
			},
		},
		{
			"setext_header/simple.md",
			blocks{
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
			},
		},
		{
			"setext_header/span_in_text.md",
			blocks{
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
			},
		},
		{
			"setext_header/trailing_space_in_underline.md",
			blocks{
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
			},
		},
		{
			"setext_header/vs_atx_header.md",
			blocks{
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
			},
		},
		{
			"setext_header/vs_blockquote.md",
			blocks{
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
			},
		},
		{
			"setext_header/vs_codeblock.md",
			blocks{
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
			},
		},
		{
			"setext_header/vs_list.md",
			blocks{
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{2, "md.SetextHeaderBlock"},
			},
		},
		{
			"unordered_list/all_items_loose.md",
			blocks{{7, "md.UnorderedListBlock"}},
		},
		{
			"unordered_list/all_items_tight.md",
			blocks{{4, "md.UnorderedListBlock"}},
		},
		{
			"unordered_list/all_items_tight_even_with_blanks.md",
			blocks{{7, "md.UnorderedListBlock"}},
		},
		{
			"unordered_list/at_end_of_parent_without_blank_line.md",
			blocks{
				{1, "md.NullBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{8, "md.UnorderedListBlock"},
				{1, "md.AtxHeaderBlock"},
				{1, "md.NullBlock"},
				{5, "md.UnorderedListBlock"},
			},
		},
		{
			"unordered_list/bw_ordered_lists.md",
			blocks{
				{3, "md.OrderedListBlock"},
				{3, "md.UnorderedListBlock"},
				{3, "md.OrderedListBlock"},
			},
		},
		{
			"unordered_list/changing_bullet.md",
			blocks{
				{3, "md.UnorderedListBlock"},
				{3, "md.UnorderedListBlock"},
				{3, "md.UnorderedListBlock"},
			},
		},
		{
			"unordered_list/changing_starter_string.md",
			blocks{
				{4, "md.UnorderedListBlock"},
				{2, "md.UnorderedListBlock"},
				{4, "md.UnorderedListBlock"},
				{2, "md.UnorderedListBlock"},
				{1, "md.UnorderedListBlock"},
				{2, "md.OrderedListBlock"},
				{1, "md.UnorderedListBlock"},
			},
		},
		{
			"unordered_list/different_bullet_chars.md",
			blocks{
				{2, "md.ParagraphBlock"},
				{2, "md.UnorderedListBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.UnorderedListBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.UnorderedListBlock"},
			},
		},
		{
			"unordered_list/followed_by_hr.md",
			blocks{
				{4, "md.UnorderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{5, "md.UnorderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{6, "md.UnorderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
			},
		},
		{
			"unordered_list/followed_by_list.md",
			blocks{
				{4, "md.UnorderedListBlock"},
				{2, "md.UnorderedListBlock"},
				{5, "md.UnorderedListBlock"},
				{2, "md.UnorderedListBlock"},
				{6, "md.UnorderedListBlock"},
				{1, "md.UnorderedListBlock"},

				{4, "md.UnorderedListBlock"},
				{2, "md.OrderedListBlock"},
				{5, "md.UnorderedListBlock"},
				{2, "md.OrderedListBlock"},
				{6, "md.UnorderedListBlock"},
				{1, "md.OrderedListBlock"},
			},
		},
		{
			"unordered_list/indent_and_sub_blocks.md",
			blocks{
				{6, "md.UnorderedListBlock"},
				{2, "md.ParagraphBlock"},
				{6, "md.UnorderedListBlock"},
				{2, "md.QuoteBlock"},
				{6, "md.UnorderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{6, "md.UnorderedListBlock"},
				{2, "md.UnorderedListBlock"},
				{6, "md.UnorderedListBlock"},
				{2, "md.OrderedListBlock"},
				{6, "md.UnorderedListBlock"},
				{1, "md.CodeBlock"},
				{1, "md.NullBlock"},
			},
		},
		{
			"unordered_list/list_ends_with_2blanks.md",
			blocks{
				{4, "md.UnorderedListBlock"},
				{1, "md.NullBlock"},
				{10, "md.UnorderedListBlock"},
				{1, "md.NullBlock"},
				{1, "md.CodeBlock"},
			},
		},
		{
			"unordered_list/many_level_nesting.md",
			blocks{
				{2, "md.ParagraphBlock"},
				{22, "md.UnorderedListBlock"},
				{1, "md.ParagraphBlock"},
			},
		},
		{
			"unordered_list/many_lines.md",
			blocks{{5, "md.UnorderedListBlock"}},
		},
		{
			"unordered_list/many_lines_lazy.md",
			blocks{{5, "md.UnorderedListBlock"}},
		},
		{
			"unordered_list/many_paras.md",
			blocks{{9, "md.UnorderedListBlock"}},
		},
		{
			"unordered_list/many_paras_2blank.md",
			blocks{
				{5, "md.UnorderedListBlock"},
				{1, "md.NullBlock"},
				{4, "md.ParagraphBlock"},
			},
		},
		{
			"unordered_list/many_paras_2blank_lazy.md",
			blocks{
				{5, "md.UnorderedListBlock"},
				{1, "md.NullBlock"},
				{4, "md.ParagraphBlock"},
			},
		},
		{
			"unordered_list/many_paras_lazy.md",
			blocks{{9, "md.UnorderedListBlock"}},
		},
		{
			"unordered_list/no_space_after_bullet.md",
			blocks{
				{2, "md.ParagraphBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.ParagraphBlock"},
				{1, "md.ParagraphBlock"},
			},
		},
		{
			"unordered_list/no_space_before_bullet.md",
			blocks{
				{2, "md.ParagraphBlock"},
				{2, "md.UnorderedListBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.UnorderedListBlock"},
				{2, "md.ParagraphBlock"},
				{1, "md.UnorderedListBlock"},
			},
		},
		{
			"unordered_list/one_line.md",
			blocks{{3, "md.UnorderedListBlock"}},
		},
		{
			"unordered_list/some_items_loose.md",
			blocks{
				{2, "md.ParagraphBlock"},
				{6, "md.UnorderedListBlock"},
				{2, "md.ParagraphBlock"},
				{8, "md.UnorderedListBlock"},
				{2, "md.ParagraphBlock"},
				{10, "md.UnorderedListBlock"},
				{2, "md.ParagraphBlock"},
				{6, "md.UnorderedListBlock"},
				{1, "md.ParagraphBlock"},
			},
		},
		{
			"unordered_list/space_before_bullet.md",
			blocks{
				{2, "md.ParagraphBlock"},
				{2, "md.UnorderedListBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.UnorderedListBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.UnorderedListBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.UnorderedListBlock"},
				{2, "md.ParagraphBlock"},
				{1, "md.CodeBlock"},
				{1, "md.NullBlock"},
			},
		},
		{
			"unordered_list/three_paras_loose.md",
			blocks{{15, "md.UnorderedListBlock"}},
		},
		{
			"unordered_list/three_paras_tight.md",
			blocks{{13, "md.UnorderedListBlock"}},
		},
		{
			"unordered_list/two_paras_loose.md",
			blocks{{11, "md.UnorderedListBlock"}},
		},
		{
			"unordered_list/with_atx_header.md",
			blocks{
				{16, "md.UnorderedListBlock"},
				{1, "md.AtxHeaderBlock"},
			},
		},
		{
			"unordered_list/with_blockquote.md",
			blocks{
				{8, "md.UnorderedListBlock"},
				{1, "md.QuoteBlock"},
			},
		},
		{
			"unordered_list/with_codeblock.md",
			blocks{
				{8, "md.UnorderedListBlock"},
				{2, "md.ParagraphBlock"},
				{2, "md.UnorderedListBlock"},
				{1, "md.CodeBlock"},
			},
		},
		{
			"unordered_list/with_para.md",
			blocks{
				{10, "md.UnorderedListBlock"},
				{1, "md.ParagraphBlock"},
			},
		},
		{
			"unordered_list/with_setext_header.md",
			blocks{
				{25, "md.UnorderedListBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
				{10, "md.UnorderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{3, "md.UnorderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{3, "md.UnorderedListBlock"},
				{1, "md.HorizontalRuleBlock"},
				{1, "md.NullBlock"},
				{3, "md.UnorderedListBlock"},
				{2, "md.SetextHeaderBlock"},
				{1, "md.NullBlock"},
			},
		},
	}

Cases:
	for _, c := range cases {
		// test.Logf("case %s", c.path)
		data, err := ioutil.ReadFile(filepath.Join(dir, c.path))
		if err != nil {
			test.Error(err)
			continue
		}
		prep, _ := vfmd.QuickPrep(bytes.NewReader(data))
		result, err := QuickParse(bytes.NewReader(prep), TopBlocks, nil, nil)

		if err != nil {
			test.Error(err)
			continue Cases
		}

		summary := blocks{}
		for _, b := range result {
			if _, ok := b.(md.End); ok {
				continue
			}
			type getRawer interface {
				GetRaw() md.Region
			}
			if b, ok := b.(getRawer); ok {
				summary = append(summary, block{
					n:   len(b.GetRaw()),
					tag: fmt.Sprintf("%T", b),
				})
			}
		}

		if !reflect.DeepEqual(summary, c.blocks) {
			test.Errorf("case %s expected vs. got DIFF:\n%s",
				c.path, diff.Diff(spew.Sdump(c.blocks), spew.Sdump(summary)))
		}
	}
}
Пример #23
0
// Compare returns a string containing a line-by-line unified diff of the
// values in got and want according to the cfg.
func (cfg *Config) Compare(got, want interface{}) string {
	diffCfg := *cfg
	diffCfg.Diffable = true
	return diff.Diff(cfg.Sprint(got), cfg.Sprint(want))
}