ting 0.3.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.travis.yml +13 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +235 -0
- data/LICENSE.txt +674 -0
- data/{README.rdoc → README.md} +43 -35
- data/Rakefile +28 -15
- data/TODO +16 -15
- data/examples/hello.rb +12 -12
- data/lib/ting.rb +36 -61
- data/lib/ting/conversion.rb +6 -5
- data/lib/ting/conversions.rb +88 -80
- data/lib/ting/conversions/hanyu.rb +5 -9
- data/lib/ting/converter.rb +30 -0
- data/lib/ting/data/comparison.csv +410 -410
- data/lib/ting/data/final.csv +12 -10
- data/lib/ting/data/initial.csv +8 -7
- data/lib/ting/data/paladiy.txt +421 -421
- data/lib/ting/data/rules.yaml +38 -27
- data/lib/ting/data/valid_pinyin.yaml +454 -453
- data/lib/ting/exception.rb +14 -17
- data/lib/ting/groundwork.rb +181 -177
- data/lib/ting/procable.rb +7 -0
- data/lib/ting/reader.rb +27 -0
- data/lib/ting/string.rb +0 -15
- data/lib/ting/tones.rb +65 -65
- data/lib/ting/tones/accents.rb +75 -69
- data/lib/ting/tones/ipa.rb +1 -1
- data/lib/ting/tones/no_tones.rb +7 -7
- data/lib/ting/tones/numbers.rb +25 -25
- data/lib/ting/tones/supernum.rb +1 -1
- data/lib/ting/version.rb +1 -1
- data/lib/ting/writer.rb +23 -0
- data/spec/jruby_csv_spec.rb +78 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/ting_spec.rb +19 -0
- data/test/test_comparison.rb +43 -35
- data/test/test_hanyu_coverage.rb +42 -37
- data/ting.gemspec +23 -0
- metadata +95 -71
- data/examples/cgiform/cgiform.rb +0 -24
- data/examples/cgiform/template.rhtml +0 -69
- data/lib/ting/support.rb +0 -19
data/lib/ting/tones/accents.rb
CHANGED
@@ -1,69 +1,75 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
module Ting
|
4
|
-
module Tones
|
5
|
-
class Accents < Tone
|
6
|
-
class <<self
|
7
|
-
|
8
|
-
UNICODE_TONE_GLYPHS={
|
9
|
-
:a=>[97, 257, 225, 462, 224],
|
10
|
-
:e=>[101, 275, 233, 283, 232],
|
11
|
-
:i=>[105, 299, 237, 464, 236],
|
12
|
-
:o=>[111, 333, 243, 466, 242],
|
13
|
-
:u=>[117, 363, 250, 468, 249],
|
14
|
-
:v=>[252, 470, 472, 474, 476]
|
15
|
-
}
|
16
|
-
|
17
|
-
def tone_glyph(letter,tone)
|
18
|
-
if (u=UNICODE_TONE_GLYPHS[letter.to_sym][tone%MAX_TONE])
|
19
|
-
[u].pack('U')
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def add_tone(syll, tone)
|
24
|
-
syll.
|
25
|
-
tone %= MAX_TONE
|
26
|
-
case syll
|
27
|
-
when /a/
|
28
|
-
syll.sub(/a/, tone_glyph(:a,tone))
|
29
|
-
when /e/
|
30
|
-
syll.sub(/e/, tone_glyph(:e,tone))
|
31
|
-
when /o/
|
32
|
-
syll.sub(/o/, tone_glyph(:o,tone))
|
33
|
-
when /(i|u|v)/
|
34
|
-
syll.sub($1, tone_glyph($1,tone))
|
35
|
-
|
36
|
-
syll
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Ting
|
4
|
+
module Tones
|
5
|
+
class Accents < Tone
|
6
|
+
class << self
|
7
|
+
|
8
|
+
UNICODE_TONE_GLYPHS={
|
9
|
+
:a=>[97, 257, 225, 462, 224],
|
10
|
+
:e=>[101, 275, 233, 283, 232],
|
11
|
+
:i=>[105, 299, 237, 464, 236],
|
12
|
+
:o=>[111, 333, 243, 466, 242],
|
13
|
+
:u=>[117, 363, 250, 468, 249],
|
14
|
+
:v=>[252, 470, 472, 474, 476]
|
15
|
+
}
|
16
|
+
|
17
|
+
def tone_glyph(letter,tone)
|
18
|
+
if (u=UNICODE_TONE_GLYPHS[letter.to_sym][tone%MAX_TONE])
|
19
|
+
[u].pack('U')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_tone(syll, tone)
|
24
|
+
syll = syll.sub('ü','v')
|
25
|
+
tone %= MAX_TONE
|
26
|
+
case syll
|
27
|
+
when /a/
|
28
|
+
syll.sub(/a/, tone_glyph(:a,tone))
|
29
|
+
when /e/
|
30
|
+
syll.sub(/e/, tone_glyph(:e,tone))
|
31
|
+
when /o/
|
32
|
+
syll.sub(/o/, tone_glyph(:o,tone))
|
33
|
+
when /(i|u|v)\z/
|
34
|
+
syll.sub($1, tone_glyph($1,tone)).sub('v', 'ü')
|
35
|
+
when /(i|u|v)/
|
36
|
+
syll.sub($1, tone_glyph($1,tone)).sub('v', 'ü')
|
37
|
+
else
|
38
|
+
syll
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def peek_tone(syll)
|
43
|
+
unpacked = syll.unpack('U*')
|
44
|
+
each_tone_glyph do |vowel, tones|
|
45
|
+
tone_glyph=unpacked.find {|t| tones.include?(t)}
|
46
|
+
normalize( tones.index(tone_glyph) ) if tone_glyph
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# returns [ tone number, syllable without tone ]
|
51
|
+
# e.g. ni3 => [ 3, 'ni' ]
|
52
|
+
def pop_tone(syll)
|
53
|
+
unpacked = syll.unpack('U*')
|
54
|
+
each_tone_glyph do |vowel, tones|
|
55
|
+
|
56
|
+
if tone_glyph = unpacked.find {|t| tones.include?(t)}
|
57
|
+
unpacked[unpacked.index(tone_glyph)] = vowel.to_s.unpack('U').first
|
58
|
+
break [normalize(tones.index(tone_glyph)), unpacked.pack('U*').sub('v', 'ü')]
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
def each_tone_glyph
|
66
|
+
[:a,:e,:i,:o,:u,:v].each do |v| #Order is significant
|
67
|
+
vowel, tones = v, UNICODE_TONE_GLYPHS[v]
|
68
|
+
yield vowel,tones
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/ting/tones/ipa.rb
CHANGED
data/lib/ting/tones/no_tones.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
module Ting
|
2
|
-
module Tones
|
3
|
-
class NoTones < Tone
|
4
|
-
end
|
5
|
-
end
|
6
|
-
end
|
7
|
-
|
1
|
+
module Ting
|
2
|
+
module Tones
|
3
|
+
class NoTones < Tone
|
4
|
+
end
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
data/lib/ting/tones/numbers.rb
CHANGED
@@ -1,25 +1,25 @@
|
|
1
|
-
module Ting
|
2
|
-
module Tones
|
3
|
-
class Numbers < Tone
|
4
|
-
class <<self
|
5
|
-
|
6
|
-
def add_tone(syll, tone)
|
7
|
-
syll + normalize(tone).to_s
|
8
|
-
end
|
9
|
-
|
10
|
-
def peek_tone(syll)
|
11
|
-
if syll =~ /(\d)\Z/
|
12
|
-
normalize Integer($1)
|
13
|
-
else
|
14
|
-
NEUTRAL_TONE
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def pop_tone(syll)
|
19
|
-
[ peek_tone(syll), syll[/\A\D+/] ]
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
1
|
+
module Ting
|
2
|
+
module Tones
|
3
|
+
class Numbers < Tone
|
4
|
+
class <<self
|
5
|
+
|
6
|
+
def add_tone(syll, tone)
|
7
|
+
syll + normalize(tone).to_s
|
8
|
+
end
|
9
|
+
|
10
|
+
def peek_tone(syll)
|
11
|
+
if syll =~ /(\d)\Z/
|
12
|
+
normalize Integer($1)
|
13
|
+
else
|
14
|
+
NEUTRAL_TONE
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def pop_tone(syll)
|
19
|
+
[ peek_tone(syll), syll[/\A\D+/] ]
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/ting/tones/supernum.rb
CHANGED
data/lib/ting/version.rb
CHANGED
data/lib/ting/writer.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module Ting
|
2
|
+
class Writer
|
3
|
+
include Procable
|
4
|
+
|
5
|
+
def initialize(conv, tone)
|
6
|
+
@conv = conv.to_s
|
7
|
+
@tone = Tones.const_get Ting.camelize(tone.to_s)
|
8
|
+
end
|
9
|
+
|
10
|
+
def generate(syll)
|
11
|
+
Array(syll).map do |s|
|
12
|
+
syllable = Conversions.unparse(@conv, s)
|
13
|
+
str = @tone.add_tone(syllable, s.tone)
|
14
|
+
str.capitalize! if s.capitalized?
|
15
|
+
str
|
16
|
+
end.join(' ')
|
17
|
+
end
|
18
|
+
|
19
|
+
alias :<< :generate
|
20
|
+
alias :unparse :generate
|
21
|
+
alias :call :generate
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'csv'
|
4
|
+
require 'rspec/autorun'
|
5
|
+
|
6
|
+
# Describes a problem with CSV parsing on JRuby, see output at the bottom.
|
7
|
+
#
|
8
|
+
# Version:
|
9
|
+
# jruby 1.7.2 (1.9.3p327) 2013-01-04 302c706 on Java HotSpot(TM) Server VM 1.7.0_15-b03 [linux-i386]
|
10
|
+
# Has since been fixed, verified with 1.7.11
|
11
|
+
|
12
|
+
describe "a problem with jruby?" do
|
13
|
+
let(:csv_full_contents) {
|
14
|
+
'"zhuyin","wadegiles","mps2","yale","tongyong","hanyu","gwoyeu1","gwoyeu2","gwoyeu3","gwoyeu4"
|
15
|
+
"ㄚ","a","a","a","a","a","a","ar","aa","ah"
|
16
|
+
"ㄞ","ai","ai","ai","ai","ai","ai","air","ae","ay"
|
17
|
+
"ㄢ","an","an","an","an","an","an","arn","aan","ann"
|
18
|
+
"ㄤ","ang","ang","ang","ang","ang","ang","arng","aang","anq"
|
19
|
+
"ㄠ","ao","au","au","ao","ao","au","aur","ao","aw"
|
20
|
+
"ㄅㄚ","pa","ba","ba","ba","ba","ba","bar","baa","bah"
|
21
|
+
"ㄅㄞ","pai","bai","bai","bai","bai","bai","bair","bae","bay"
|
22
|
+
"ㄅㄢ","pan","ban","ban","ban","ban","ban","barn","baan","bann"
|
23
|
+
"ㄅㄤ","pang","bang","bang","bang","bang","bang","barng","baang","banq"
|
24
|
+
"ㄅㄠ","pao","bau","bau","bao","bao","bau","baur","bao","baw"
|
25
|
+
"ㄅㄟ","pei","bei","bei","bei","bei","bei","beir","beei","bey"
|
26
|
+
"ㄅㄣ","pen","ben","ben","ben","ben","ben","bern","been","benn"
|
27
|
+
"ㄅㄥ","peng","beng","beng","beng","beng","beng","berng","beeng","benq"
|
28
|
+
"ㄅㄧ","pi","bi","bi","bi","bi","bi","byi","bii","bih"
|
29
|
+
"ㄅㄧㄢ","pien","bian","byan","bian","bian","bian","byan","bean","biann"
|
30
|
+
"ㄅㄧㄠ","piao","biau","byau","biao","biao","biau","byau","beau","biaw"
|
31
|
+
"ㄅㄧㄝ","pieh","bie","bye","bie","bie","bie","bye","biee","bieh"
|
32
|
+
"ㄅㄧㄣ","pin","bin","bin","bin","bin","bin","byn","biin","binn"
|
33
|
+
"ㄅㄧㄥ","ping","bing","bing","bing","bing","bing","byng","biing","binq"'
|
34
|
+
}
|
35
|
+
|
36
|
+
def lines(range)
|
37
|
+
csv_full_contents.split("\n")[range].join("\n")
|
38
|
+
end
|
39
|
+
|
40
|
+
it "this actually does raise an exception, so this spec fails" do
|
41
|
+
expect{ CSV.parse(csv_full_contents) }.to_not raise_exception
|
42
|
+
end
|
43
|
+
|
44
|
+
it "using the first 15 lines still works ok" do
|
45
|
+
expect{ CSV.parse(lines(0..15))}.to_not raise_exception
|
46
|
+
end
|
47
|
+
|
48
|
+
it "from line 16 on there's a problem" do
|
49
|
+
expect{ CSV.parse(lines(0..16))}.to_not raise_exception
|
50
|
+
end
|
51
|
+
|
52
|
+
it "but line 16 itself isn't the culprit" do
|
53
|
+
expect{ CSV.parse(lines(3..18))}.to_not raise_exception
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
# 1) a problem with jruby? this actually does raise an exception, so this spec fails
|
59
|
+
# Failure/Error: expect{ CSV.parse(csv_full_contents) }.to_not raise_exception
|
60
|
+
# expected no Exception, got #<ArgumentError: invalid byte sequence in UTF-8> with backtrace:
|
61
|
+
# # ./spec/jruby_csv_spec.rb:38:in `(root)'
|
62
|
+
# # ./spec/jruby_csv_spec.rb:38:in `(root)'
|
63
|
+
# # ./spec/jruby_csv_spec.rb:38:in `(root)'
|
64
|
+
|
65
|
+
# 2) a problem with jruby? from line 16 on there's a problem
|
66
|
+
# Failure/Error: expect{ CSV.parse(lines(0..16))}.to_not raise_exception
|
67
|
+
# expected no Exception, got #<ArgumentError: invalid byte sequence in UTF-8> with backtrace:
|
68
|
+
# # ./spec/jruby_csv_spec.rb:46:in `(root)'
|
69
|
+
# # ./spec/jruby_csv_spec.rb:46:in `(root)'
|
70
|
+
# # ./spec/jruby_csv_spec.rb:46:in `(root)'
|
71
|
+
|
72
|
+
# Finished in 0.111 seconds
|
73
|
+
# 4 examples, 2 failures
|
74
|
+
|
75
|
+
# Failed examples:
|
76
|
+
|
77
|
+
# rspec ./spec/jruby_csv_spec.rb:37 # a problem with jruby? this actually does raise an exception, so this spec fails
|
78
|
+
# rspec ./spec/jruby_csv_spec.rb:45 # a problem with jruby? from line 16 on there's a problem
|
data/spec/spec_helper.rb
ADDED
data/spec/ting_spec.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Ting do
|
5
|
+
let(:pinyin) { 'dao4 ke3 dao4 fei1 chang2 dao4'.force_encoding('UTF-8') }
|
6
|
+
let(:bopomofo) { 'ㄉㄠˋ ㄎㄜˇ ㄉㄠˋ ㄈㄟ ㄔㄤˊ ㄉㄠˋ'.force_encoding('UTF-8') }
|
7
|
+
|
8
|
+
it 'should convert from Hany Pinyin to Bopomofo' do
|
9
|
+
Ting.from(:hanyu, :numbers).to(:zhuyin, :marks).convert(pinyin).should == bopomofo
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should parse" do
|
13
|
+
Ting::Reader.new(:hanyu, :numbers).parse('Bei3').first.should == Ting::Syllable.new( Ting::Initial::Bo, Ting::Final::Ei, 3, true )
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should respect capitalization' do
|
17
|
+
Ting.from(:hanyu, :numbers).to(:hanyu, :accents).convert('Bei3 jing1').should == 'Běi jīng'
|
18
|
+
end
|
19
|
+
end
|
data/test/test_comparison.rb
CHANGED
@@ -1,35 +1,43 @@
|
|
1
|
-
require 'ting'
|
2
|
-
require 'test/unit'
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
def
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
1
|
+
require 'ting'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
# This test uses the chart from piyin.info to compare all implemented conversion types
|
5
|
+
# Since I can't find another reference of the hanyu pinyin 'lo', I have removed it from the table
|
6
|
+
|
7
|
+
class TestCompare < Test::Unit::TestCase
|
8
|
+
CHART_FILE = File.expand_path('../../lib/ting/data/comparison.csv', __FILE__)
|
9
|
+
COMPARE=[:hanyu, :wadegiles, :zhuyin, :tongyong]
|
10
|
+
|
11
|
+
# Both Rubinius and JRuby are having trouble parsing our otherwise valid UTF-8 CSV file.
|
12
|
+
# See https://github.com/jruby/jruby/issues/563 for the JRuby issue that logs the issue.
|
13
|
+
# So we do our own naive CSV parsing here.
|
14
|
+
CHART = begin
|
15
|
+
File.open(CHART_FILE, 'r:UTF-8').each_line.map do |line|
|
16
|
+
line.strip.split(',').map{|entry| entry[/\A"(.*)"\z/, 1]}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
# Test all combinations, included parsing/unparsing the same type
|
23
|
+
|
24
|
+
def test_do_comparisons
|
25
|
+
COMPARE.each do |from|
|
26
|
+
COMPARE.each do |to|
|
27
|
+
compare(from,to)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def compare(from, to)
|
33
|
+
reader = Ting.reader(from, :no_tones)
|
34
|
+
writer = Ting.writer(to, :no_tones)
|
35
|
+
|
36
|
+
ifrom = CHART[0].index from.to_s
|
37
|
+
ito = CHART[0].index to.to_s
|
38
|
+
|
39
|
+
CHART[1..-1].each do |vals|
|
40
|
+
assert_equal(vals[ito].strip, writer << (reader << vals[ifrom].strip), "Converting `#{vals[ifrom]}' from #{from} to #{to} value #{vals[ito]}")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/test/test_hanyu_coverage.rb
CHANGED
@@ -1,37 +1,42 @@
|
|
1
|
-
|
2
|
-
require '
|
3
|
-
require '
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
end
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'test/unit'
|
3
|
+
require 'ting'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
module HanyuCoverage
|
7
|
+
|
8
|
+
class Test_ParseUnparse < Test::Unit::TestCase
|
9
|
+
include Ting
|
10
|
+
def initialize(s)
|
11
|
+
super(s)
|
12
|
+
@reader = Ting.reader(:hanyu, :no_tones)
|
13
|
+
@writer = Ting.writer(:hanyu, :no_tones)
|
14
|
+
end
|
15
|
+
|
16
|
+
grid=YAML.load(File.open(File.expand_path('../../lib/ting/data/valid_pinyin.yaml', __FILE__), 'r:UTF-8').read)
|
17
|
+
grid.each do |fname, row|
|
18
|
+
row.each do |iname, hanyu|
|
19
|
+
hanyu=hanyu.force_encoding('UTF-8')
|
20
|
+
safe_hanyu = hanyu.gsub('ü','v').gsub('ê','_e')
|
21
|
+
|
22
|
+
define_method :"test_unparse_#{safe_hanyu}" do
|
23
|
+
assert_equal(
|
24
|
+
hanyu,
|
25
|
+
@writer.unparse(
|
26
|
+
Syllable.new(Initial.const_get(iname), Final.const_get(fname), Tones::NEUTRAL_TONE)
|
27
|
+
),
|
28
|
+
"Wrong hanyu for Initial::#{iname}+Final::#{fname}, expected `#{hanyu}` "
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
define_method :"test_parse_#{safe_hanyu}" do
|
33
|
+
ts=@reader.parse(hanyu).first
|
34
|
+
assert_not_nil(ts, "Reader<:hanyu, :no_tone>#parse('#{hanyu}') returned nil")
|
35
|
+
assert_equal(Initial.const_get(iname), ts.initial, "Wrong initial for `#{hanyu}`, expected Initial::#{iname}")
|
36
|
+
assert_equal(Final.const_get(fname), ts.final, "Wrong final for `#{hanyu}`, expected Final::#{fname}")
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|