virtfs 0.0.1

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 (91) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +8 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +154 -0
  8. data/Rakefile +5 -0
  9. data/lib/virtfs-nativefs-thick.rb +1 -0
  10. data/lib/virtfs-nativefs-thin.rb +1 -0
  11. data/lib/virtfs.rb +38 -0
  12. data/lib/virtfs/activation.rb +97 -0
  13. data/lib/virtfs/block_io.rb +140 -0
  14. data/lib/virtfs/byte_range.rb +71 -0
  15. data/lib/virtfs/context.rb +300 -0
  16. data/lib/virtfs/context_manager.rb +175 -0
  17. data/lib/virtfs/context_switch_class_methods.rb +96 -0
  18. data/lib/virtfs/delegate_module.rb +40 -0
  19. data/lib/virtfs/dir_instance_delegate.rb +3 -0
  20. data/lib/virtfs/exception.rb +13 -0
  21. data/lib/virtfs/file_instance_delegate.rb +3 -0
  22. data/lib/virtfs/file_modes_and_options.rb +293 -0
  23. data/lib/virtfs/find_class_methods.rb +106 -0
  24. data/lib/virtfs/io_buffer.rb +133 -0
  25. data/lib/virtfs/io_instance_delegate.rb +3 -0
  26. data/lib/virtfs/kernel.rb +146 -0
  27. data/lib/virtfs/nativefs/thick.rb +30 -0
  28. data/lib/virtfs/nativefs/thick/dir_class_methods.rb +38 -0
  29. data/lib/virtfs/nativefs/thick/file_class_methods.rb +178 -0
  30. data/lib/virtfs/nativefs/thin.rb +32 -0
  31. data/lib/virtfs/nativefs/thin/dir.rb +30 -0
  32. data/lib/virtfs/nativefs/thin/dir_class_methods.rb +41 -0
  33. data/lib/virtfs/nativefs/thin/file.rb +112 -0
  34. data/lib/virtfs/nativefs/thin/file_class_methods.rb +181 -0
  35. data/lib/virtfs/protofs/protofs.rb +7 -0
  36. data/lib/virtfs/protofs/protofs_base.rb +12 -0
  37. data/lib/virtfs/protofs/protofs_dir.rb +13 -0
  38. data/lib/virtfs/protofs/protofs_dir_class.rb +31 -0
  39. data/lib/virtfs/protofs/protofs_file.rb +27 -0
  40. data/lib/virtfs/protofs/protofs_file_class.rb +136 -0
  41. data/lib/virtfs/stat.rb +100 -0
  42. data/lib/virtfs/thin_dir_delegator.rb +79 -0
  43. data/lib/virtfs/thin_file_delegator.rb +77 -0
  44. data/lib/virtfs/thin_io_delegator_methods.rb +301 -0
  45. data/lib/virtfs/thin_io_delegator_methods_bufferio.rb +337 -0
  46. data/lib/virtfs/v_dir.rb +238 -0
  47. data/lib/virtfs/v_file.rb +480 -0
  48. data/lib/virtfs/v_io.rb +243 -0
  49. data/lib/virtfs/v_pathname.rb +128 -0
  50. data/lib/virtfs/version.rb +3 -0
  51. data/spec/activate_spec.rb +202 -0
  52. data/spec/chroot_spec.rb +120 -0
  53. data/spec/context_manager_class_spec.rb +246 -0
  54. data/spec/context_manager_instance_spec.rb +255 -0
  55. data/spec/context_spec.rb +335 -0
  56. data/spec/data/UTF-16LE-data.txt +0 -0
  57. data/spec/data/UTF-8-data.txt +212 -0
  58. data/spec/dir_class_spec.rb +506 -0
  59. data/spec/dir_instance_spec.rb +208 -0
  60. data/spec/file_class_spec.rb +2106 -0
  61. data/spec/file_instance_spec.rb +154 -0
  62. data/spec/file_modes_and_options_spec.rb +1556 -0
  63. data/spec/find_spec.rb +142 -0
  64. data/spec/io_bufferio_size_shared_examples.rb +371 -0
  65. data/spec/io_bufferio_size_spec.rb +861 -0
  66. data/spec/io_bufferio_spec.rb +801 -0
  67. data/spec/io_class_spec.rb +145 -0
  68. data/spec/io_instance_spec.rb +516 -0
  69. data/spec/kernel_spec.rb +285 -0
  70. data/spec/mount_spec.rb +186 -0
  71. data/spec/nativefs_local_root_spec.rb +132 -0
  72. data/spec/path_spec.rb +39 -0
  73. data/spec/spec_helper.rb +126 -0
  74. data/tasks/rspec.rake +3 -0
  75. data/tasks/yard.rake +7 -0
  76. data/test/UTF-8-demo.txt +212 -0
  77. data/test/bench.rb +18 -0
  78. data/test/bio_internal_test.rb +45 -0
  79. data/test/delegate_io.rb +31 -0
  80. data/test/delegate_module.rb +62 -0
  81. data/test/encode_test.rb +42 -0
  82. data/test/enoent_test.rb +30 -0
  83. data/test/namespace_test.rb +42 -0
  84. data/test/read_block_valid_encoding.rb +44 -0
  85. data/test/read_test.rb +78 -0
  86. data/test/stream_readers.rb +46 -0
  87. data/test/utf-16-demo.txt +0 -0
  88. data/test/utf8_to_utf16.rb +77 -0
  89. data/test/wrapper_test.rb +34 -0
  90. data/virtfs.gemspec +29 -0
  91. metadata +230 -0
@@ -0,0 +1,335 @@
1
+ require 'spec_helper'
2
+
3
+ describe VirtFS::Context do
4
+ before(:all) do
5
+ @full_path = File.expand_path(__FILE__)
6
+ @rel_path = File.basename(@full_path)
7
+ @this_dir = File.dirname(@full_path)
8
+ @root = File::SEPARATOR
9
+
10
+ @new_root = VfsRealFile.expand_path(VfsRealFile.join(__dir__, ".."))
11
+ @new_this_dir = VfsRealFile.expand_path(VfsRealFile.join("/", VfsRealFile.basename(__dir__)))
12
+ @new_full_path = VfsRealFile.expand_path(VfsRealFile.join(@new_this_dir, VfsRealFile.basename(__FILE__)))
13
+ end
14
+
15
+ before(:each) do
16
+ reset_context
17
+ @context0 = VirtFS::Context.new
18
+ end
19
+
20
+ describe "#mount" do
21
+ before(:each) do
22
+ @native_fs = nativefs_class.new
23
+ end
24
+
25
+ context "single filesystem:" do
26
+ it "should raise RuntimeError when an invalid filesystem is provided" do
27
+ expect do
28
+ @context0.mount(nil, @root)
29
+ end.to raise_error(
30
+ RuntimeError, "mount: invalid filesystem object #{nil.class.name}"
31
+ )
32
+ end
33
+
34
+ it "should raise Errno::ENOENT when mount point doesn't exist" do
35
+ expect do
36
+ @context0.mount(@native_fs, @this_dir)
37
+ end.to raise_error(
38
+ Errno::ENOENT, "No such file or directory - #{@this_dir}"
39
+ )
40
+ end
41
+
42
+ it "should raise RuntimeError when attempting to reuse mount point" do
43
+ expect do
44
+ @context0.mount(@native_fs, @root)
45
+ @context0.mount(nativefs_class.new, @root)
46
+ end.to raise_error(
47
+ RuntimeError, "mount: mount point #{@root} is busy"
48
+ )
49
+ end
50
+
51
+ it "should raise RuntimeError when attempting to mount a mounted filesystem" do
52
+ expect do
53
+ @context0.mount(@native_fs, @root)
54
+ @context0.mount(@native_fs, @this_dir)
55
+ end.to raise_error(
56
+ RuntimeError, "mount: filesystem is busy"
57
+ )
58
+ end
59
+
60
+ it "should return nil on successful mount" do
61
+ expect(@context0.mount(@native_fs, @root)).to be_nil
62
+ end
63
+ end
64
+
65
+ context "second filesystem:" do
66
+ before(:each) do
67
+ @native_fs2 = nativefs_class.new
68
+ @context0.mount(@native_fs, @root)
69
+ end
70
+
71
+ it "should raise RuntimeError when attempting to reuse mount point" do
72
+ expect do
73
+ @context0.mount(@native_fs2, @this_dir)
74
+ @context0.mount(nativefs_class.new, @this_dir)
75
+ end.to raise_error(
76
+ RuntimeError, "mount: mount point #{@this_dir} is busy"
77
+ )
78
+ end
79
+
80
+ it "should return nil on successful mount" do
81
+ expect(@context0.mount(@native_fs2, @this_dir)).to be_nil
82
+ end
83
+ end
84
+ end
85
+
86
+ describe "#umount" do
87
+ before(:each) do
88
+ @native_fs = nativefs_class.new
89
+ end
90
+
91
+ it "should raise RuntimeError when nothing mounted on mount point" do
92
+ @context0.mount(@native_fs, @root)
93
+ expect do
94
+ @context0.umount(@this_dir)
95
+ end.to raise_error(
96
+ RuntimeError, "umount: nothing mounted on #{@this_dir}"
97
+ )
98
+ end
99
+
100
+ it "should return nil on successful umount" do
101
+ @context0.mount(@native_fs, @root)
102
+ expect(@context0.umount(@root)).to be_nil
103
+ end
104
+
105
+ it "should enable re-mount" do
106
+ @context0.mount(@native_fs, @root)
107
+ @context0.umount(@root)
108
+ expect(@context0.mount(@native_fs, @root)).to be_nil
109
+ end
110
+ end
111
+
112
+ describe "#mount_points" do
113
+ it "should return an Array" do
114
+ expect(@context0.mount_points).to be_kind_of(Array)
115
+ end
116
+
117
+ it "should return an empty Array when nothing mounted" do
118
+ expect(@context0.mount_points.empty?).to be true
119
+ end
120
+
121
+ it "should return an array of the expected length" do
122
+ expect(@context0.mount_points.length).to eq(0)
123
+ native_fs1 = nativefs_class.new
124
+ @context0.mount(native_fs1, @root)
125
+ expect(@context0.mount_points.length).to eq(1)
126
+ native_fs2 = nativefs_class.new
127
+ @context0.mount(native_fs2, @this_dir)
128
+ expect(@context0.mount_points.length).to eq(2)
129
+ end
130
+
131
+ it "should return an array containing expected values" do
132
+ expect(@context0.mount_points).to match_array([])
133
+ native_fs1 = nativefs_class.new
134
+ @context0.mount(native_fs1, @root)
135
+ expect(@context0.mount_points).to match_array([@root])
136
+ native_fs2 = nativefs_class.new
137
+ @context0.mount(native_fs2, @this_dir)
138
+ expect(@context0.mount_points).to match_array([@root, @this_dir])
139
+ end
140
+ end
141
+
142
+ describe "#mounted?" do
143
+ it "should return false when nothing is mounted" do
144
+ expect(@context0.mounted?(@root)).to be false
145
+ end
146
+
147
+ it "should return false, given a directory that's not a mount point" do
148
+ native_fs1 = nativefs_class.new
149
+ @context0.mount(native_fs1, @root)
150
+ expect(@context0.mounted?(@this_dir)).to be false
151
+ end
152
+
153
+ it "should return true, given a directory that is a mount point" do
154
+ native_fs1 = nativefs_class.new
155
+ @context0.mount(native_fs1, @root)
156
+ expect(@context0.mounted?(@root)).to be true
157
+ native_fs2 = nativefs_class.new
158
+ @context0.mount(native_fs2, @this_dir)
159
+ expect(@context0.mounted?(@this_dir)).to be true
160
+ end
161
+ end
162
+
163
+ describe "#fs_on" do
164
+ it "should return nil when nothing is mounted" do
165
+ expect(@context0.fs_on(@root)).to be nil
166
+ end
167
+
168
+ it "should return nil, given a directory that's not a mount point" do
169
+ native_fs1 = nativefs_class.new
170
+ @context0.mount(native_fs1, @root)
171
+ expect(@context0.fs_on(@this_dir)).to be nil
172
+ end
173
+
174
+ it "should return the FS object for the filesystem mounted on the mount point" do
175
+ native_fs1 = nativefs_class.new
176
+ @context0.mount(native_fs1, @root)
177
+ expect(@context0.fs_on(@root)).to eq(native_fs1)
178
+ native_fs2 = nativefs_class.new
179
+ @context0.mount(native_fs2, @this_dir)
180
+ expect(@context0.fs_on(@this_dir)).to eq(native_fs2)
181
+ end
182
+ end
183
+
184
+ describe "#chroot" do
185
+ before(:each) do
186
+ @native_fs = nativefs_class.new
187
+ @context0.mount(@native_fs, @root)
188
+ end
189
+
190
+ it "should raise Errno::ENOENT when directory does exist" do
191
+ expect do
192
+ @context0.chroot("/not_a_dir/foo.d")
193
+ end.to raise_error(
194
+ Errno::ENOENT, /No such file or directory/
195
+ )
196
+ end
197
+
198
+ it "should return 0 on success" do
199
+ expect(@context0.chroot(@this_dir)).to eq(0)
200
+ end
201
+
202
+ it "should set the value of root accordingly" do
203
+ @context0.chroot(@new_root)
204
+ _cwd, root = @context0.cwd_root
205
+ expect(root).to eq(@new_root)
206
+ end
207
+
208
+ it "should set the current directory to '/'" do
209
+ @context0.chroot(@new_root)
210
+ cwd, _root = @context0.cwd_root
211
+ expect(cwd).to eq(File::SEPARATOR)
212
+ end
213
+
214
+ it "should find directory through new full path" do
215
+ @context0.chroot(@new_root)
216
+ expect(@context0.dir_exist?(@new_this_dir)).to be true
217
+ end
218
+ end
219
+
220
+ describe "#with_root" do
221
+ before(:each) do
222
+ @native_fs = nativefs_class.new
223
+ @context0.mount(@native_fs, @root)
224
+ end
225
+
226
+ it "should raise Errno::ENOENT when directory does exist" do
227
+ expect do
228
+ @context0.with_root("/not_a_dir/foo.d") {}
229
+ end.to raise_error(
230
+ Errno::ENOENT, /No such file or directory/
231
+ )
232
+ end
233
+
234
+ it "should raise LocalJumpError when no block given" do
235
+ expect do
236
+ @context0.with_root(@this_dir)
237
+ end.to raise_error(
238
+ LocalJumpError, /no block given/
239
+ )
240
+ end
241
+
242
+ it "should set the value of root within the block" do
243
+ _cwd, root0 = @context0.cwd_root
244
+ expect(root0).to_not eq(@new_root)
245
+
246
+ @context0.with_root(@new_root) do
247
+ _cwd, root1 = @context0.cwd_root
248
+ expect(root1).to eq(@new_root)
249
+ end
250
+
251
+ _cwd, root2 = @context0.cwd_root
252
+ expect(root2).to eq(root0)
253
+ end
254
+ end
255
+
256
+ describe "#path_lookup" do
257
+ context "with no filesystems mounted" do
258
+ it "should raise Errno::ENOENT" do
259
+ expect do
260
+ @context0.path_lookup(@full_path)
261
+ end.to raise_error(
262
+ Errno::ENOENT, "No such file or directory - #{@full_path}"
263
+ )
264
+ end
265
+
266
+ it "should raise Errno::ENOENT with original path in message" do
267
+ expect do
268
+ @context0.path_lookup(@rel_path)
269
+ end.to raise_error(
270
+ Errno::ENOENT, "No such file or directory - #{@rel_path}"
271
+ )
272
+ end
273
+ end
274
+
275
+ context "with FS mounted on #{@root}" do
276
+ before(:each) do
277
+ @native_fs = nativefs_class.new
278
+ @context0.mount(@native_fs, @root)
279
+ end
280
+
281
+ it "should return native_fs, when given fully qualified path" do
282
+ fs, _path = @context0.path_lookup(@full_path)
283
+ expect(fs).to eq(@native_fs)
284
+ end
285
+
286
+ it "should return the full path, when given fully qualified path" do
287
+ _fs, path = @context0.path_lookup(@full_path)
288
+ expect(path).to eq(@full_path) # .sub(@native_fs.mount_point, '')
289
+ end
290
+
291
+ it "should return native_fs, when given relative path" do
292
+ @context0.chdir(@this_dir)
293
+ fs, _path = @context0.path_lookup(@rel_path)
294
+ expect(fs).to eq(@native_fs)
295
+ end
296
+
297
+ it "should return the full path, when given relative path" do
298
+ @context0.chdir(@this_dir)
299
+ _fs, path = @context0.path_lookup(@rel_path)
300
+ expect(path).to eq(@full_path) # .sub(@native_fs.mount_point, '')
301
+ end
302
+ end
303
+
304
+ context "with FS mounted on #{@this_dir}" do
305
+ before(:each) do
306
+ @native_fs = nativefs_class.new
307
+ @native_fs2 = nativefs_class.new
308
+ @context0.mount(@native_fs, @root)
309
+ @context0.mount(@native_fs2, @this_dir)
310
+ end
311
+
312
+ it "should return native_fs2, when given fully qualified path" do
313
+ fs, _path = @context0.path_lookup(@full_path)
314
+ expect(fs).to eq(@native_fs2)
315
+ end
316
+
317
+ it "should return the path relative to the mount point, when given fully qualified path" do
318
+ _fs, path = @context0.path_lookup(@full_path)
319
+ expect(path).to eq(@full_path.sub(@native_fs2.mount_point, File::SEPARATOR))
320
+ end
321
+
322
+ it "should return native_fs2, when given relative path" do
323
+ @context0.chdir(@this_dir)
324
+ fs, _path = @context0.path_lookup(@rel_path)
325
+ expect(fs).to eq(@native_fs2)
326
+ end
327
+
328
+ it "should return the path relative to the mount point, when given relative path" do
329
+ @context0.chdir(@this_dir)
330
+ _fs, path = @context0.path_lookup(@rel_path)
331
+ expect(path).to eq(@full_path.sub(@native_fs2.mount_point, File::SEPARATOR))
332
+ end
333
+ end
334
+ end
335
+ end
@@ -0,0 +1,212 @@
1
+
2
+ UTF-8 encoded sample plain-text file
3
+ ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
4
+
5
+ Markus Kuhn [ˈmaʳkʊs kuːn] <http://www.cl.cam.ac.uk/~mgk25/> — 2002-07-25 CC BY
6
+
7
+
8
+ The ASCII compatible UTF-8 encoding used in this plain-text file
9
+ is defined in Unicode, ISO 10646-1, and RFC 2279.
10
+
11
+
12
+ Using Unicode/UTF-8, you can write in emails and source code things such as
13
+
14
+ Mathematics and sciences:
15
+
16
+ ∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i), ⎧⎡⎛┌─────┐⎞⎤⎫
17
+ ⎪⎢⎜│a²+b³ ⎟⎥⎪
18
+ ∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β), ⎪⎢⎜│───── ⎟⎥⎪
19
+ ⎪⎢⎜⎷ c₈ ⎟⎥⎪
20
+ ℕ ⊆ ℕ₀ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ, ⎨⎢⎜ ⎟⎥⎬
21
+ ⎪⎢⎜ ∞ ⎟⎥⎪
22
+ ⊥ < a ≠ b ≡ c ≤ d ≪ ⊤ ⇒ (⟦A⟧ ⇔ ⟪B⟫), ⎪⎢⎜ ⎲ ⎟⎥⎪
23
+ ⎪⎢⎜ ⎳aⁱ-bⁱ⎟⎥⎪
24
+ 2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm ⎩⎣⎝i=1 ⎠⎦⎭
25
+
26
+ Linguistics and dictionaries:
27
+
28
+ ði ıntəˈnæʃənəl fəˈnɛtık əsoʊsiˈeıʃn
29
+ Y [ˈʏpsilɔn], Yen [jɛn], Yoga [ˈjoːgɑ]
30
+
31
+ APL:
32
+
33
+ ((V⍳V)=⍳⍴V)/V←,V ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈
34
+
35
+ Nicer typography in plain text files:
36
+
37
+ ╔══════════════════════════════════════════╗
38
+ ║ ║
39
+ ║ • ‘single’ and “double” quotes ║
40
+ ║ ║
41
+ ║ • Curly apostrophes: “We’ve been here” ║
42
+ ║ ║
43
+ ║ • Latin-1 apostrophe and accents: '´` ║
44
+ ║ ║
45
+ ║ • ‚deutsche‘ „Anführungszeichen“ ║
46
+ ║ ║
47
+ ║ • †, ‡, ‰, •, 3–4, —, −5/+5, ™, … ║
48
+ ║ ║
49
+ ║ • ASCII safety test: 1lI|, 0OD, 8B ║
50
+ ║ ╭─────────╮ ║
51
+ ║ • the euro symbol: │ 14.95 € │ ║
52
+ ║ ╰─────────╯ ║
53
+ ╚══════════════════════════════════════════╝
54
+
55
+ Combining characters:
56
+
57
+ STARGΛ̊TE SG-1, a = v̇ = r̈, a⃑ ⊥ b⃑
58
+
59
+ Greek (in Polytonic):
60
+
61
+ The Greek anthem:
62
+
63
+ Σὲ γνωρίζω ἀπὸ τὴν κόψη
64
+ τοῦ σπαθιοῦ τὴν τρομερή,
65
+ σὲ γνωρίζω ἀπὸ τὴν ὄψη
66
+ ποὺ μὲ βία μετράει τὴ γῆ.
67
+
68
+ ᾿Απ᾿ τὰ κόκκαλα βγαλμένη
69
+ τῶν ῾Ελλήνων τὰ ἱερά
70
+ καὶ σὰν πρῶτα ἀνδρειωμένη
71
+ χαῖρε, ὦ χαῖρε, ᾿Ελευθεριά!
72
+
73
+ From a speech of Demosthenes in the 4th century BC:
74
+
75
+ Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι,
76
+ ὅταν τ᾿ εἰς τὰ πράγματα ἀποβλέψω καὶ ὅταν πρὸς τοὺς
77
+ λόγους οὓς ἀκούω· τοὺς μὲν γὰρ λόγους περὶ τοῦ
78
+ τιμωρήσασθαι Φίλιππον ὁρῶ γιγνομένους, τὰ δὲ πράγματ᾿
79
+ εἰς τοῦτο προήκοντα, ὥσθ᾿ ὅπως μὴ πεισόμεθ᾿ αὐτοὶ
80
+ πρότερον κακῶς σκέψασθαι δέον. οὐδέν οὖν ἄλλο μοι δοκοῦσιν
81
+ οἱ τὰ τοιαῦτα λέγοντες ἢ τὴν ὑπόθεσιν, περὶ ἧς βουλεύεσθαι,
82
+ οὐχὶ τὴν οὖσαν παριστάντες ὑμῖν ἁμαρτάνειν. ἐγὼ δέ, ὅτι μέν
83
+ ποτ᾿ ἐξῆν τῇ πόλει καὶ τὰ αὑτῆς ἔχειν ἀσφαλῶς καὶ Φίλιππον
84
+ τιμωρήσασθαι, καὶ μάλ᾿ ἀκριβῶς οἶδα· ἐπ᾿ ἐμοῦ γάρ, οὐ πάλαι
85
+ γέγονεν ταῦτ᾿ ἀμφότερα· νῦν μέντοι πέπεισμαι τοῦθ᾿ ἱκανὸν
86
+ προλαβεῖν ἡμῖν εἶναι τὴν πρώτην, ὅπως τοὺς συμμάχους
87
+ σώσομεν. ἐὰν γὰρ τοῦτο βεβαίως ὑπάρξῃ, τότε καὶ περὶ τοῦ
88
+ τίνα τιμωρήσεταί τις καὶ ὃν τρόπον ἐξέσται σκοπεῖν· πρὶν δὲ
89
+ τὴν ἀρχὴν ὀρθῶς ὑποθέσθαι, μάταιον ἡγοῦμαι περὶ τῆς
90
+ τελευτῆς ὁντινοῦν ποιεῖσθαι λόγον.
91
+
92
+ Δημοσθένους, Γ´ ᾿Ολυνθιακὸς
93
+
94
+ Georgian:
95
+
96
+ From a Unicode conference invitation:
97
+
98
+ გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო
99
+ კონფერენციაზე დასასწრებად, რომელიც გაიმართება 10-12 მარტს,
100
+ ქ. მაინცში, გერმანიაში. კონფერენცია შეჰკრებს ერთად მსოფლიოს
101
+ ექსპერტებს ისეთ დარგებში როგორიცაა ინტერნეტი და Unicode-ი,
102
+ ინტერნაციონალიზაცია და ლოკალიზაცია, Unicode-ის გამოყენება
103
+ ოპერაციულ სისტემებსა, და გამოყენებით პროგრამებში, შრიფტებში,
104
+ ტექსტების დამუშავებასა და მრავალენოვან კომპიუტერულ სისტემებში.
105
+
106
+ Russian:
107
+
108
+ From a Unicode conference invitation:
109
+
110
+ Зарегистрируйтесь сейчас на Десятую Международную Конференцию по
111
+ Unicode, которая состоится 10-12 марта 1997 года в Майнце в Германии.
112
+ Конференция соберет широкий круг экспертов по вопросам глобального
113
+ Интернета и Unicode, локализации и интернационализации, воплощению и
114
+ применению Unicode в различных операционных системах и программных
115
+ приложениях, шрифтах, верстке и многоязычных компьютерных системах.
116
+
117
+ Thai (UCS Level 2):
118
+
119
+ Excerpt from a poetry on The Romance of The Three Kingdoms (a Chinese
120
+ classic 'San Gua'):
121
+
122
+ [----------------------------|------------------------]
123
+ ๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่
124
+ สิบสองกษัตริย์ก่อนหน้าแลถัดไป สององค์ไซร้โง่เขลาเบาปัญญา
125
+ ทรงนับถือขันทีเป็นที่พึ่ง บ้านเมืองจึงวิปริตเป็นนักหนา
126
+ โฮจิ๋นเรียกทัพทั่วหัวเมืองมา หมายจะฆ่ามดชั่วตัวสำคัญ
127
+ เหมือนขับไสไล่เสือจากเคหา รับหมาป่าเข้ามาเลยอาสัญ
128
+ ฝ่ายอ้องอุ้นยุแยกให้แตกกัน ใช้สาวนั้นเป็นชนวนชื่นชวนใจ
129
+ พลันลิฉุยกุยกีกลับก่อเหตุ ช่างอาเพศจริงหนาฟ้าร้องไห้
130
+ ต้องรบราฆ่าฟันจนบรรลัย ฤๅหาใครค้ำชูกู้บรรลังก์ ฯ
131
+
132
+ (The above is a two-column text. If combining characters are handled
133
+ correctly, the lines of the second column should be aligned with the
134
+ | character above.)
135
+
136
+ Ethiopian:
137
+
138
+ Proverbs in the Amharic language:
139
+
140
+ ሰማይ አይታረስ ንጉሥ አይከሰስ።
141
+ ብላ ካለኝ እንደአባቴ በቆመጠኝ።
142
+ ጌጥ ያለቤቱ ቁምጥና ነው።
143
+ ደሀ በሕልሙ ቅቤ ባይጠጣ ንጣት በገደለው።
144
+ የአፍ ወለምታ በቅቤ አይታሽም።
145
+ አይጥ በበላ ዳዋ ተመታ።
146
+ ሲተረጉሙ ይደረግሙ።
147
+ ቀስ በቀስ፥ ዕንቁላል በእግሩ ይሄዳል።
148
+ ድር ቢያብር አንበሳ ያስር።
149
+ ሰው እንደቤቱ እንጅ እንደ ጉረቤቱ አይተዳደርም።
150
+ እግዜር የከፈተውን ጉሮሮ ሳይዘጋው አይድርም።
151
+ የጎረቤት ሌባ፥ ቢያዩት ይስቅ ባያዩት ያጠልቅ።
152
+ ሥራ ከመፍታት ልጄን ላፋታት።
153
+ ዓባይ ማደሪያ የለው፥ ግንድ ይዞ ይዞራል።
154
+ የእስላም አገሩ መካ የአሞራ አገሩ ዋርካ።
155
+ ተንጋሎ ቢተፉ ተመልሶ ባፉ።
156
+ ወዳጅህ ማር ቢሆን ጨርስህ አትላሰው።
157
+ እግርህን በፍራሽህ ልክ ዘርጋ።
158
+
159
+ Runes:
160
+
161
+ ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ
162
+
163
+ (Old English, which transcribed into Latin reads 'He cwaeth that he
164
+ bude thaem lande northweardum with tha Westsae.' and means 'He said
165
+ that he lived in the northern land near the Western Sea.')
166
+
167
+ Braille:
168
+
169
+ ⡌⠁⠧⠑ ⠼⠁⠒ ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌
170
+
171
+ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠙⠑⠁⠙⠒ ⠞⠕ ⠃⠑⠛⠔ ⠺⠊⠹⠲ ⡹⠻⠑ ⠊⠎ ⠝⠕ ⠙⠳⠃⠞
172
+ ⠱⠁⠞⠑⠧⠻ ⠁⠃⠳⠞ ⠹⠁⠞⠲ ⡹⠑ ⠗⠑⠛⠊⠌⠻ ⠕⠋ ⠙⠊⠎ ⠃⠥⠗⠊⠁⠇ ⠺⠁⠎
173
+ ⠎⠊⠛⠝⠫ ⠃⠹ ⠹⠑ ⠊⠇⠻⠛⠹⠍⠁⠝⠂ ⠹⠑ ⠊⠇⠻⠅⠂ ⠹⠑ ⠥⠝⠙⠻⠞⠁⠅⠻⠂
174
+ ⠁⠝⠙ ⠹⠑ ⠡⠊⠑⠋ ⠍⠳⠗⠝⠻⠲ ⡎⠊⠗⠕⠕⠛⠑ ⠎⠊⠛⠝⠫ ⠊⠞⠲ ⡁⠝⠙
175
+ ⡎⠊⠗⠕⠕⠛⠑⠰⠎ ⠝⠁⠍⠑ ⠺⠁⠎ ⠛⠕⠕⠙ ⠥⠏⠕⠝ ⠰⡡⠁⠝⠛⠑⠂ ⠋⠕⠗ ⠁⠝⠹⠹⠔⠛ ⠙⠑
176
+ ⠡⠕⠎⠑ ⠞⠕ ⠏⠥⠞ ⠙⠊⠎ ⠙⠁⠝⠙ ⠞⠕⠲
177
+
178
+ ⡕⠇⠙ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲
179
+
180
+ ⡍⠔⠙⠖ ⡊ ⠙⠕⠝⠰⠞ ⠍⠑⠁⠝ ⠞⠕ ⠎⠁⠹ ⠹⠁⠞ ⡊ ⠅⠝⠪⠂ ⠕⠋ ⠍⠹
181
+ ⠪⠝ ⠅⠝⠪⠇⠫⠛⠑⠂ ⠱⠁⠞ ⠹⠻⠑ ⠊⠎ ⠏⠜⠞⠊⠊⠥⠇⠜⠇⠹ ⠙⠑⠁⠙ ⠁⠃⠳⠞
182
+ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ ⡊ ⠍⠊⠣⠞ ⠙⠁⠧⠑ ⠃⠑⠲ ⠔⠊⠇⠔⠫⠂ ⠍⠹⠎⠑⠇⠋⠂ ⠞⠕
183
+ ⠗⠑⠛⠜⠙ ⠁ ⠊⠕⠋⠋⠔⠤⠝⠁⠊⠇ ⠁⠎ ⠹⠑ ⠙⠑⠁⠙⠑⠌ ⠏⠊⠑⠊⠑ ⠕⠋ ⠊⠗⠕⠝⠍⠕⠝⠛⠻⠹
184
+ ⠔ ⠹⠑ ⠞⠗⠁⠙⠑⠲ ⡃⠥⠞ ⠹⠑ ⠺⠊⠎⠙⠕⠍ ⠕⠋ ⠳⠗ ⠁⠝⠊⠑⠌⠕⠗⠎
185
+ ⠊⠎ ⠔ ⠹⠑ ⠎⠊⠍⠊⠇⠑⠆ ⠁⠝⠙ ⠍⠹ ⠥⠝⠙⠁⠇⠇⠪⠫ ⠙⠁⠝⠙⠎
186
+ ⠩⠁⠇⠇ ⠝⠕⠞ ⠙⠊⠌⠥⠗⠃ ⠊⠞⠂ ⠕⠗ ⠹⠑ ⡊⠳⠝⠞⠗⠹⠰⠎ ⠙⠕⠝⠑ ⠋⠕⠗⠲ ⡹⠳
187
+ ⠺⠊⠇⠇ ⠹⠻⠑⠋⠕⠗⠑ ⠏⠻⠍⠊⠞ ⠍⠑ ⠞⠕ ⠗⠑⠏⠑⠁⠞⠂ ⠑⠍⠏⠙⠁⠞⠊⠊⠁⠇⠇⠹⠂ ⠹⠁⠞
188
+ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲
189
+
190
+ (The first couple of paragraphs of "A Christmas Carol" by Dickens)
191
+
192
+ Compact font selection example text:
193
+
194
+ ABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789
195
+ abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ
196
+ –—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвгд
197
+ ∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi�⑀₂ἠḂӥẄɐː⍎אԱა
198
+
199
+ Greetings in various languages:
200
+
201
+ Hello world, Καλημέρα κόσμε, コンニチハ
202
+
203
+ Box drawing alignment tests: █
204
+
205
+ ╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳
206
+ ║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳
207
+ ║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳
208
+ ╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳
209
+ ║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎
210
+ ║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏
211
+ ╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ ▗▄▖▛▀▜ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█
212
+ ▝▀▘▙▄▟