lingo 1.8.2 → 1.8.3

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.
Files changed (76) hide show
  1. data/ChangeLog +33 -0
  2. data/README +6 -5
  3. data/Rakefile +6 -4
  4. data/{lib/lingo/cachable.rb → bin/lingosrv} +30 -58
  5. data/bin/lingoweb +30 -0
  6. data/de.lang +2 -13
  7. data/en/lingo-irr.txt +266 -0
  8. data/en/lingo-wdn.txt +37319 -0
  9. data/en.lang +2 -15
  10. data/lib/lingo/app.rb +82 -0
  11. data/lib/lingo/attendee/abbreviator.rb +22 -26
  12. data/lib/lingo/attendee/debugger.rb +8 -4
  13. data/lib/lingo/attendee/decomposer.rb +0 -1
  14. data/lib/lingo/attendee/dehyphenizer.rb +2 -2
  15. data/lib/lingo/attendee/multi_worder.rb +20 -13
  16. data/lib/lingo/attendee/noneword_filter.rb +2 -7
  17. data/lib/lingo/attendee/sequencer.rb +43 -19
  18. data/lib/lingo/attendee/stemmer/porter.rb +2 -2
  19. data/lib/lingo/attendee/stemmer.rb +1 -1
  20. data/lib/lingo/attendee/synonymer.rb +1 -9
  21. data/lib/lingo/attendee/text_reader.rb +42 -29
  22. data/lib/lingo/attendee/text_writer.rb +3 -6
  23. data/lib/lingo/attendee/tokenizer.rb +87 -69
  24. data/lib/lingo/attendee/variator.rb +7 -5
  25. data/lib/lingo/attendee/vector_filter.rb +11 -11
  26. data/lib/lingo/attendee/word_searcher.rb +1 -9
  27. data/lib/lingo/attendee.rb +24 -105
  28. data/lib/lingo/buffered_attendee.rb +2 -9
  29. data/lib/lingo/call.rb +18 -13
  30. data/lib/lingo/cli.rb +5 -10
  31. data/lib/lingo/config.rb +40 -7
  32. data/lib/lingo/ctl.rb +69 -57
  33. data/lib/lingo/database/hash_store.rb +9 -4
  34. data/lib/lingo/database/sdbm_store.rb +4 -7
  35. data/lib/lingo/database/source/multi_key.rb +1 -1
  36. data/lib/lingo/database/source/multi_value.rb +1 -1
  37. data/lib/lingo/database/source.rb +2 -20
  38. data/lib/lingo/database.rb +30 -19
  39. data/lib/lingo/debug.rb +79 -0
  40. data/lib/lingo/{core_ext.rb → language/char.rb} +43 -42
  41. data/lib/lingo/language/dictionary.rb +38 -46
  42. data/lib/lingo/language/grammar.rb +40 -57
  43. data/lib/lingo/language/lexical.rb +4 -7
  44. data/lib/lingo/language/lexical_hash.rb +17 -35
  45. data/lib/lingo/language/token.rb +4 -0
  46. data/lib/lingo/language/word.rb +7 -8
  47. data/lib/lingo/language/word_form.rb +4 -4
  48. data/lib/lingo/language.rb +2 -1
  49. data/lib/lingo/srv/config.ru +4 -0
  50. data/lib/lingo/srv/lingosrv.cfg +14 -0
  51. data/lib/lingo/{reportable.rb → srv.rb} +59 -61
  52. data/lib/lingo/version.rb +1 -1
  53. data/lib/lingo/web/config.ru +4 -0
  54. data/lib/lingo/web/lingoweb.cfg +14 -0
  55. data/lib/lingo/web/public/lingo.png +0 -0
  56. data/lib/lingo/web/public/lingoweb.css +74 -0
  57. data/lib/lingo/web/views/index.erb +92 -0
  58. data/lib/lingo/web.rb +94 -0
  59. data/lib/lingo.rb +27 -29
  60. data/lingo.cfg +1 -1
  61. data/lir.cfg +24 -0
  62. data/ru/lingo-dic.txt +22342 -0
  63. data/ru/lingo-mul.txt +5151 -0
  64. data/ru/lingo-syn.txt +0 -0
  65. data/ru.lang +99 -0
  66. data/test/attendee/ts_sequencer.rb +2 -2
  67. data/test/attendee/ts_text_reader.rb +36 -2
  68. data/test/attendee/ts_text_writer.rb +6 -6
  69. data/test/lir.vec +3 -3
  70. data/test/test_helper.rb +104 -102
  71. data/test/ts_database.rb +1 -1
  72. data/test/ts_language.rb +55 -96
  73. data/txt/artikel-ru.txt +45 -0
  74. data/txt/lir.txt +1 -3
  75. metadata +143 -83
  76. data/TODO +0 -23
data/ru/lingo-syn.txt ADDED
File without changes
data/ru.lang ADDED
@@ -0,0 +1,99 @@
1
+ #------------------------------------------------------------------------------------------------------------------------------------
2
+ #
3
+ # database-Section - Definitionen für Wörterbücher
4
+ #
5
+ # In der database-Section können alle benötigten Wörterbücher angegeben werden.
6
+ # Dabei werden folgende Attribute interpretiert:
7
+ #
8
+ # Attribut Default Bedeutung
9
+ # -----------------------------------------------------------------------------
10
+ # id Über diese Kurzbezeichnung kann die Datenquelle an anderer Stelle referenziert werden, z.B. bei Attendees
11
+ # als source-Attribut.
12
+ #
13
+ # name Gibt den Ort der Quelldaten an.
14
+ #
15
+ # def-wc ? Gibt eine Wortklasse vor die verwendet wird, wenn die Datenquelle über keine adäquate Information zur
16
+ # Wortklasse eines Eintrags verfügt.
17
+ #
18
+ # txt-format KeyValue Gibt an, in welchem Format die Quelldaten je Zeile vorliegen. Dabei wird unterschieden zwischen
19
+ # SingleWord = Je Zeile ist nur ein Wort (ohne Projektion) angegeben, z.B.
20
+ # "Nasenbär\n"
21
+ # KeyValue = Je Zeile ist ein Wort und die dazugehörige Projektion angegeben, z.B.
22
+ # "John Vorhauer*Vorhauer, John\n"
23
+ # WordClass = Je Zeile ist ein Wort und die dazugehörige Projektion angegeben, die aus mehreren
24
+ # Lexikalisierungen bestehen kann, z.B.
25
+ # "Essen,essen #v Essen #s Esse #s\n"
26
+ # MultiValue = Je Zeile sind mehrere Worte angegeben, die als Äquivalenzklasse interpretiert werden, z.B.
27
+ # "Fax;Faxkopie;Telefax\n"
28
+ # MultiKey
29
+ #
30
+ # separator (s.Text) Gibt an, durch welches Zeichen eine Textzeile die Grundform von der Projektion trennt. Der Defaultwert ist
31
+ # abhängig vom Text-Format: KeyValue='*', WordClass=',' und MultiValue=';'.
32
+ #
33
+ # use-lex Gibt an, dass bei Mehrwort-Schlüsseln eine Vorab-Lexikalisierung vorgenommen wird durch Zuhilfenahme der
34
+ # Wörterbücher, die mit diesem Attribut angegeben werden, z.B. use-lex='sys-dic'.
35
+ # Die Vorab-Lexikalisierung von Mehrwortgruppen ermöglicht die leichte Erkennung von allen möglichen
36
+ # Dehnungsvarianten. Bei Mehrwort-Wörterbüchern, die ausschließlich Personennamen enthalten, kann dieser Wert
37
+ # entfallen, da er nur die Verarbeitungsgeschwindigkeit vermindert ohne die Erkennungsquote zu erhöhen.
38
+ #
39
+ # ACHTUNG: Wird mit dem Attribut use-lex ein anderes Wörterbuch referenziert, so sollte dieses VOR der ersten Referenzierung
40
+ # definiert sein, da es sonst noch nicht existiert!
41
+ #
42
+
43
+ # lingo language definition
44
+ ---
45
+ language:
46
+ name: 'Russisch'
47
+
48
+ dictionary:
49
+ databases:
50
+ # Systemwörterbücher
51
+ sys-dic: { name: ru/lingo-dic.txt, txt-format: WordClass, separator: '=' }
52
+ sys-syn: { name: ru/lingo-syn.txt, txt-format: KeyValue, separator: '=', def-wc: y }
53
+ sys-mul: { name: ru/lingo-mul.txt, txt-format: SingleWord, use-lex: 'sys-dic', def-wc: m }
54
+ # Benutzerwörterbücher
55
+ usr-dic: { name: ru/user-dic.txt, txt-format: WordClass, separator: '=' }
56
+
57
+ compound:
58
+ min-word-size: "7"
59
+ min-part-size: "3"
60
+ max-parts: "5"
61
+ min-avg-part-size: "4"
62
+ append-wordclass: "+"
63
+ skip-sequences: [ xx ]
64
+
65
+ suffix:
66
+ # Suffixliste, Stand: 07-09-2012
67
+ # Suffixklasse: s = Substantiv, a = Adjektiv, v = Verb, e = Eigenwort, f = Fugung
68
+ # Suffixe je Klasse: "<suffix>['/'<ersetzung>][ <suffix>['/'<ersetzung>]]"
69
+ - [s, "а у ом е ы ов ам ами ах и енка/енок енку/енок енком/енок енке/енок ята/енок ят/енок ятам/енок ятами/енок ятах/енок я/й ю/й е/й ем/й и/й ев/й ям/й ями/й ях/й я/ь ю/ь ем/ь е/ь и/ь ей/ь ям/ь ями/ь ях/ь ью/ь ы/а е/а у/а ой/а ам/а ами/а ах/а и/а /а и/я е/я ю/я ей/я ь/я ям/я ями/я ях/я й/я ени/я енем/я ена/я ен/я енам/я енами/я енах/я а/о у/о ом/о е/о ам/о ами/о ах/о и/о /о я/е ю/е ем/е и/е й/е ей/е ям/е ями/е ях/е а/е у/е ам/е ами/е ах/е /е"]
70
+ - [a, "ого/ый ому/ый ым/ый ом/ый ая/ый ой/ый ую/ый ое/ый ые/ый ых/ый ыми/ый а/ый о/ый ы/ый ее/ый им/ый ие/ый их/ый ими/ый ейший/ый ейшего/ый ейшему/ый ейшим/ый ейшем/ый ейшие/ый ейших/ый ейшими/ый ого/ой ому/ой ым/ой ом/ой ая/ой ую/ой ое/ой ые/ой ых/ой ыми/ой а/ой о/ой ы/ой ее/ой им/ой ие/ой их/ой ими/ой ейший/ой ейшего/ой ейшему/ой ейшим/ой ейшем/ой ейшие/ой ейших/ой ейшими/ой его/ий ему/ий им/ий ем/ий ее/ий яя/ий ей/ий юю/ий ие/ий их/ий им/ий ими/ий ого/ий ому/ий ым/ий ом/ий ая/ий ой/ий ую/ий ое/ий ые/ий ых/ий ым/ий ыми/ий а/ий о/ий ы/ий ейший/ий ейшего/ий ейшему/ий ейшим/ий ейшем/ий ейшие/ий ейших/ий ейшими/ий"]
71
+ - [v, "у/ть ю/ть ешь/ть ет/ть ем/ть ете/ть ют/ть л/ть ла/ть ло/ть ли/ть й/ть йте/ть я/ть в/ть ут/ти у/ти ю/ти ешь/ти ет/ти ем/ти ете/ти ют/ти л/ти ла/ти ло/ти ли/ти й/ти йте/ти я/ти в/ти ут/ти усь/ться юсь/ться ешься/ться ется/ться емся/ться етесь/ться ются/ться лся/ться лась/ться лось/ться лись/ться йся/ться йтесь/ться усь/тись юсь/тись ешься/тись ется/тись емся/тись етесь/тись утся/тись ются/тись лся/тись лась/тись лось/тись лись/тись ись/тись итесь/тись ю/ить ишь/ить ит/ить им/ить ите/ить ят/ить ил/ить ила/ить ило/ить или/ить й/ить йте/ить ью/ить ьешь/ить ьет/ить ьем/ить ьете/ить ьют/ить ей/ить ейте/ить я/ить ив/ить юсь/иться ишься/иться ится/иться имся/иться итесь/иться ятся/иться ился/иться илась/иться илось/иться ились/иться йся/иться йтесь/иться ьюсь/иться ьешься/иться ьется/иться ьемся/иться ьетесь/иться ьются/иться ейся/иться ейтесь/иться ю/оть ешь/оть ет/оть ем/оть ете/оть ют/оть л/оть ла/оть ло/оть ли/оть й/оть йте/оть я/оть ов/оть юсь/оться ешься/оться ется/оться емся/оться етесь/оться ются/оться лся/оться лась/оться лось/оться лись/оться ись/оться итесь/оться ую/овать уешь/овать ует/овать уем/овать уете/овать уют/овать овал/овать овала/овать овало/овать овали/овать уй/овать уйте/овать уя/овать овав/овать уюсь/оваться уешься/оваться уется/оваться уемся/оваться уетесь/оваться уются/оваться овался/оваться овалась/оваться овалось/оваться овались/оваться уйся/оваться уйтесь/оваться юю/евать юешь/евать юет/евать юем/евать юете/евать юют/евать евал/евать евала/евать евало/евать евали/евать юй/евать юйте/евать юя/евать евав/евать ююсь/еваться юешься/еваться юется/еваться юемся/еваться юетесь/еваться ются/еваться евался/еваться евалась/еваться евалось/еваться евались/еваться юйся/еваться юйтесь/еваться ну/нуть нешь/нуть нет/нуть нем/нуть нете/нуть нут/нуть нул/нуть нула/нуть нуло/нуть нули/нуть ни/нуть ните/нуть нув/нуть нусь/нуться нешься/нуться нется/нуться немся/нуться нетесь/нуться нутся/нуться нулся/нуться нулась/нуться нулось/нуться нулись/нуться нись/нуться нитесь/нуться гу/чь жешь/чь жет/чь жем/чь жете/чь гут/чь г/чь гла/чь гло/чь гли/чь ги/чь гите/чь ку/чь чешь/чь чет/чь чем/чь чете/чь кут/чь к/чь кла/чь кло/чь кли/чь ки/чь ките/чь гусь/чься жешься/чься жется/чься жемся/чься жетесь/чься гутся/чься гся/чься глась/чься глось/чься глись/чься гись/чься гитесь/чься кусь/чься чешься/чься чется/чься чемся/чься четесь/чься кутся/чься кся/чься клась/чься клось/чься клись/чься кись/чься китесь/чься ююсь/еваться юешься/еваться юется/еваться юемся/еваться юетесь/еваться юются/еваться"]
72
+ # - [e, "s"]
73
+ # - [f, "s n e en es er ch/che /en"]
74
+
75
+ attendees:
76
+ variator:
77
+ variations:
78
+ - [ ieh, sch ]
79
+ - [ fec, see ]
80
+ - [ it, st ]
81
+ - [ fch, sch ]
82
+ - [ fp, sp ]
83
+ - [ f, s ]
84
+ - [ c, e ]
85
+ - [ ffc, sse ]
86
+ - [ ff, ss ]
87
+ - [ e, c ]
88
+ - [ ni, m ]
89
+ - [ feh, sch ]
90
+ - [ lt, st ]
91
+ - [ il, st ]
92
+ - [ ftc, ste ]
93
+ - [ ft, st ]
94
+ - [ fl, st ]
95
+ - [ li, h ]
96
+ - [ i, s ]
97
+
98
+ sequencer:
99
+ sequences: [ [AS, "2, 1"] ]
@@ -19,15 +19,15 @@ class TestAttendeeSequencer < AttendeeTestCase
19
19
  ], [
20
20
  # AS
21
21
  wd('Die|IDF', 'die|w'),
22
- wd('sonne, hell|SEQ', 'sonne, hell|q'),
23
22
  wd('helle|IDF', 'hell|a'),
24
23
  wd('Sonne|IDF', 'sonne|s'),
25
24
  tk('.|PUNC'),
25
+ wd('sonne, hell|SEQ', 'sonne, hell|q'),
26
26
  # AK
27
27
  wd('Der|IDF', 'der|w'),
28
- wd('sonnenuntergang, schön|SEQ', 'sonnenuntergang, schön|q'),
29
28
  wd('schöne|IDF', 'schön|a'),
30
29
  wd('Sonnenuntergang|KOM', 'sonnenuntergang|k', 'sonne|s+', 'untergang|s+'),
30
+ wd('sonnenuntergang, schön|SEQ', 'sonnenuntergang, schön|q'),
31
31
  ai('EOF|')
32
32
  ])
33
33
  end
@@ -5,7 +5,7 @@ require_relative '../test_helper'
5
5
  class TestAttendeeTextReader < AttendeeTestCase
6
6
 
7
7
  def test_lir_file
8
- meet({ 'files' => 'test/lir.txt', 'records' => true }, nil, [
8
+ meet({ 'files' => 'test/lir.txt', 'records' => true, 'fields' => false }, nil, [
9
9
  ai('LIR-FORMAT|'), ai("FILE|#{path = File.expand_path('test/lir.txt')}"),
10
10
  ai('RECORD|00237'),
11
11
  '020: GERHARD.',
@@ -22,7 +22,7 @@ class TestAttendeeTextReader < AttendeeTestCase
22
22
  end
23
23
 
24
24
  def test_lir_file_another_pattern
25
- meet({ 'files' => 'test/lir2.txt', 'records' => '^\021(\d+)\022' }, nil, [
25
+ meet({ 'files' => 'test/lir2.txt', 'records' => '^\021(\d+)\022', 'fields' => false }, nil, [
26
26
  ai('LIR-FORMAT|'), ai("FILE|#{path = File.expand_path('test/lir2.txt')}"),
27
27
  ai('RECORD|00237'),
28
28
  '020: GERHARD.',
@@ -38,6 +38,40 @@ class TestAttendeeTextReader < AttendeeTestCase
38
38
  ])
39
39
  end
40
40
 
41
+ def test_lir_file_fields
42
+ meet({ 'files' => 'test/lir.txt', 'records' => true }, nil, [
43
+ ai('LIR-FORMAT|'), ai("FILE|#{path = File.expand_path('test/lir.txt')}"),
44
+ ai('RECORD|00237'),
45
+ 'GERHARD.',
46
+ 'Automatisches Sammeln, Klassifizieren und Indexieren von wissenschaftlich relevanten Informationsressourcen.',
47
+ 'Die intellektuelle Erschließung des Internet befindet sich in einer Krise. GERHARD ist derzeit weltweit der einzige.',
48
+ ai('RECORD|00238'),
49
+ 'Automatisches Sammeln, Klassifizieren und Indexieren von wissenschaftlich relevanten Informationsressourcen.',
50
+ 'das DFG-Projekt GERHARD.',
51
+ ai('RECORD|00239'),
52
+ 'Information Retrieval und Dokumentmanagement im Multimedia-Zeitalter.',
53
+ '"Das Buch ist ein praxisbezogenes VADEMECUM für alle, die in einer Welt der Datennetze Wissen/Informationen sammeln.',
54
+ ai("EOF|#{path}")
55
+ ])
56
+ end
57
+
58
+ def test_lir_file_fields_another_pattern
59
+ meet({ 'files' => 'test/lir.txt', 'records' => true, 'fields' => '^\d+:' }, nil, [
60
+ ai('LIR-FORMAT|'), ai("FILE|#{path = File.expand_path('test/lir.txt')}"),
61
+ ai('RECORD|00237'),
62
+ ' GERHARD.',
63
+ ' Automatisches Sammeln, Klassifizieren und Indexieren von wissenschaftlich relevanten Informationsressourcen.',
64
+ ' Die intellektuelle Erschließung des Internet befindet sich in einer Krise. GERHARD ist derzeit weltweit der einzige.',
65
+ ai('RECORD|00238'),
66
+ ' Automatisches Sammeln, Klassifizieren und Indexieren von wissenschaftlich relevanten Informationsressourcen.',
67
+ ' das DFG-Projekt GERHARD.',
68
+ ai('RECORD|00239'),
69
+ ' Information Retrieval und Dokumentmanagement im Multimedia-Zeitalter.',
70
+ ' "Das Buch ist ein praxisbezogenes VADEMECUM für alle, die in einer Welt der Datennetze Wissen/Informationen sammeln.',
71
+ ai("EOF|#{path}")
72
+ ])
73
+ end
74
+
41
75
  def test_normal_file
42
76
  meet({ 'files' => 'test/mul.txt' }, nil, [
43
77
  ai("FILE|#{path = File.expand_path('test/mul.txt')}"),
@@ -54,23 +54,23 @@ class TestAttendeeTextWriter < AttendeeTestCase
54
54
  ai('RECORD|00237'),
55
55
  '020: GERHARD.',
56
56
  '025: Automatisches Sammeln, Klassifizieren und Indexieren von wissenschaftlich relevanten Informationsressourcen.',
57
- "056: Die intellektuelle Erschließung des Internet befindet sich in einer Krise. GERHARD ist derzeit weltweit der einzige.\r",
57
+ "056: Die intellektuelle Erschließung des Internet befindet sich in einer Krise. GERHARD ist derzeit weltweit der einzige.",
58
58
  ai('RECORD|00238'),
59
59
  '020: Automatisches Sammeln, Klassifizieren und Indexieren von wissenschaftlich relevanten Informationsressourcen.',
60
- "025: das DFG-Projekt GERHARD.\r",
60
+ "025: das DFG-Projekt GERHARD.",
61
61
  ai('RECORD|00239'),
62
62
  '020: Information Retrieval und Dokumentmanagement im Multimedia-Zeitalter.',
63
- "056: \"Das Buch ist ein praxisbezogenes VADEMECUM für alle, die in einer Welt der Datennetze Wissen/Informationen sammeln.\r",
63
+ "056: \"Das Buch ist ein praxisbezogenes VADEMECUM für alle, die in einer Welt der Datennetze Wissen/Informationen sammeln.",
64
64
  ai('EOF|test/lir.txt')
65
65
  ])
66
66
 
67
67
  assert_equal([
68
68
  "00237*020: GERHARD. 025: Automatisches Sammeln, Klassifizieren und Indexieren von wissenschaftlich relevanten Informationsressour\
69
- cen. 056: Die intellektuelle Erschließung des Internet befindet sich in einer Krise. GERHARD ist derzeit weltweit der einzige.\r\n",
69
+ cen. 056: Die intellektuelle Erschließung des Internet befindet sich in einer Krise. GERHARD ist derzeit weltweit der einzige.\n",
70
70
  "00238*020: Automatisches Sammeln, Klassifizieren und Indexieren von wissenschaftlich relevanten Informationsressourcen. 025: das D\
71
- FG-Projekt GERHARD.\r\n",
71
+ FG-Projekt GERHARD.\n",
72
72
  "00239*020: Information Retrieval und Dokumentmanagement im Multimedia-Zeitalter. 056: \"Das Buch ist ein praxisbezogenes VADEMECUM\
73
- für alle, die in einer Welt der Datennetze Wissen/Informationen sammeln.\r\n"
73
+ für alle, die in einer Welt der Datennetze Wissen/Informationen sammeln.\n"
74
74
  ], File.readlines('test/lir.vec', encoding: Lingo::ENC))
75
75
  end
76
76
 
data/test/lir.vec CHANGED
@@ -1,3 +1,3 @@
1
- 00237*020: GERHARD. 025: Automatisches Sammeln, Klassifizieren und Indexieren von wissenschaftlich relevanten Informationsressourcen. 056: Die intellektuelle Erschließung des Internet befindet sich in einer Krise. GERHARD ist derzeit weltweit der einzige.
2
- 00238*020: Automatisches Sammeln, Klassifizieren und Indexieren von wissenschaftlich relevanten Informationsressourcen. 025: das DFG-Projekt GERHARD.
3
- 00239*020: Information Retrieval und Dokumentmanagement im Multimedia-Zeitalter. 056: "Das Buch ist ein praxisbezogenes VADEMECUM für alle, die in einer Welt der Datennetze Wissen/Informationen sammeln.
1
+ 00237*020: GERHARD. 025: Automatisches Sammeln, Klassifizieren und Indexieren von wissenschaftlich relevanten Informationsressourcen. 056: Die intellektuelle Erschließung des Internet befindet sich in einer Krise. GERHARD ist derzeit weltweit der einzige.
2
+ 00238*020: Automatisches Sammeln, Klassifizieren und Indexieren von wissenschaftlich relevanten Informationsressourcen. 025: das DFG-Projekt GERHARD.
3
+ 00239*020: Information Retrieval und Dokumentmanagement im Multimedia-Zeitalter. 056: "Das Buch ist ein praxisbezogenes VADEMECUM für alle, die in einer Welt der Datennetze Wissen/Informationen sammeln.
data/test/test_helper.rb CHANGED
@@ -1,102 +1,104 @@
1
- # encoding: utf-8
2
-
3
- require 'test/unit'
4
- require 'lingo'
5
-
6
- class LingoTestCase < Test::Unit::TestCase
7
-
8
- unless const_defined?(:TEST_FILE)
9
- TEST_FILE = 'test/de/test.txt'
10
- dir, name = File.split(TEST_FILE)
11
- TEST_GLOB = "{#{dir}/,store/#{File.basename(dir)}/}#{name.chomp('.txt')}*"
12
- end
13
-
14
- def cleanup_store
15
- Dir[TEST_GLOB].each { |f| File.unlink(f) }
16
- end
17
-
18
- def split(t)
19
- t =~ /^([^|]+)\|([^|]*)$/
20
- [$1 || '', $2 || '']
21
- end
22
-
23
- def ai(t)
24
- Lingo::AgendaItem.new(*split(t))
25
- end
26
-
27
- def tk(t)
28
- Lingo::Language::Token.new(*split(t))
29
- end
30
-
31
- def lx(t)
32
- Lingo::Language::Lexical.new(*split(t))
33
- end
34
-
35
- def wd(t, *l)
36
- Lingo::Language::Word.new_lexicals(*split(t), l.map!(&method(:lx)))
37
- end
38
-
39
- end
40
-
41
- class AttendeeTestCase < LingoTestCase
42
-
43
- def initialize(_)
44
- super
45
- @lingo, @attendee = Lingo.new, self.class.to_s[/TestAttendee(.*)/, 1]
46
- end
47
-
48
- def meet(att_cfg, input, expect = nil)
49
- cfg = { 'name' => @attendee }
50
- cfg.update('in' => 'input') if input
51
- cfg.update('out' => 'output') if expect
52
- cfg.update(att_cfg)
53
-
54
- @lingo.reset
55
-
56
- list = [{ @attendee => cfg }]
57
- list.unshift 'TestSpooler' => { 'out' => 'input', 'input' => input } if input
58
- list.push 'TestDumper' => { 'in' => 'output', 'output' => output = [] } if expect
59
-
60
- @lingo.invite(list)
61
- @lingo.start
62
-
63
- assert_equal(expect, output) if expect
64
- end
65
-
66
- end
67
-
68
- class Lingo
69
- class Attendee
70
- class TestSpooler < self
71
-
72
- protected
73
-
74
- def init
75
- @input = get_key('input')
76
- end
77
-
78
- def control(cmd, param)
79
- @input.each(&method(:forward)) if cmd == STR_CMD_TALK
80
- end
81
-
82
- end
83
-
84
- class TestDumper < self
85
-
86
- protected
87
-
88
- def init
89
- @output = get_key('output')
90
- end
91
-
92
- def control(cmd, param)
93
- @output << AgendaItem.new(cmd, param)
94
- end
95
-
96
- def process(obj)
97
- @output << obj
98
- end
99
-
100
- end
101
- end
102
- end
1
+ # encoding: utf-8
2
+
3
+ require 'test/unit'
4
+ require 'lingo'
5
+
6
+ class LingoTestCase < Test::Unit::TestCase
7
+
8
+ unless const_defined?(:TEST_FILE)
9
+ TEST_FILE = 'test/de/test.txt'
10
+ dir, name = File.split(TEST_FILE)
11
+ TEST_GLOB = "{#{dir}/,store/#{File.basename(dir)}/}#{name.chomp('.txt')}*"
12
+ end
13
+
14
+ def cleanup_store
15
+ Dir[TEST_GLOB].each { |f| File.delete(f) }
16
+ end
17
+
18
+ def split(t)
19
+ t =~ /^([^|]+)\|([^|]*)$/
20
+ [$1 || '', $2 || '']
21
+ end
22
+
23
+ def ai(t)
24
+ Lingo::AgendaItem.new(*split(t))
25
+ end
26
+
27
+ def tk(t)
28
+ Lingo::Language::Token.new(*split(t))
29
+ end
30
+
31
+ def lx(t)
32
+ Lingo::Language::Lexical.new(*split(t))
33
+ end
34
+
35
+ def wd(t, *l)
36
+ Lingo::Language::Word.new_lexicals(*split(t), l.map! { |i| lx(i) })
37
+ end
38
+
39
+ end
40
+
41
+ class AttendeeTestCase < LingoTestCase
42
+
43
+ def initialize(_)
44
+ super
45
+ @lingo, @attendee = Lingo.new, self.class.to_s[/TestAttendee(.*)/, 1]
46
+ end
47
+
48
+ def meet(att_cfg, input, expect = nil)
49
+ cfg = { 'name' => @attendee }
50
+ cfg.update('in' => 'input') if input
51
+ cfg.update('out' => 'output') if expect
52
+ cfg.update(att_cfg)
53
+
54
+ @lingo.reset
55
+
56
+ list = [{ @attendee => cfg }]
57
+ list.unshift 'TestSpooler' => { 'out' => 'input', 'input' => input } if input
58
+ list.push 'TestDumper' => { 'in' => 'output', 'output' => output = [] } if expect
59
+
60
+ @lingo.invite(list)
61
+ @lingo.start
62
+
63
+ assert_equal(expect, output) if expect
64
+
65
+ @lingo.reset
66
+ end
67
+
68
+ end
69
+
70
+ class Lingo
71
+ class Attendee
72
+ class TestSpooler < self
73
+
74
+ protected
75
+
76
+ def init
77
+ @input = get_key('input')
78
+ end
79
+
80
+ def control(cmd, param)
81
+ @input.each { |i| forward(i) } if cmd == STR_CMD_TALK
82
+ end
83
+
84
+ end
85
+
86
+ class TestDumper < self
87
+
88
+ protected
89
+
90
+ def init
91
+ @output = get_key('output')
92
+ end
93
+
94
+ def control(cmd, param)
95
+ @output << AgendaItem.new(cmd, param)
96
+ end
97
+
98
+ def process(obj)
99
+ @output << obj
100
+ end
101
+
102
+ end
103
+ end
104
+ end
data/test/ts_database.rb CHANGED
@@ -250,7 +250,7 @@ Wort2=
250
250
 
251
251
  def compare(config, input, output = nil)
252
252
  FileUtils.mkdir_p(File.dirname(TEST_FILE))
253
- File.write(TEST_FILE, input, encoding: Lingo::ENC)
253
+ File.open(TEST_FILE, 'w', encoding: Lingo::ENC) { |f| f.write(input) }
254
254
 
255
255
  Lingo::Database.open(set_config('tst', config.merge('name' => TEST_FILE)), @lingo) { |db|
256
256
  if block_given?