Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

การทดสอบ Rubys Unicode รองรับ

คุณลักษณะใหม่ที่มาพร้อมกับ Ruby 2.4 นั้นได้รับการปรับปรุงการรองรับ Unicode โดยเฉพาะวิธีการเช่น upcase และ downcase ทำงานตามที่คาดไว้โดยเปลี่ยน "ä" เป็น "Ä" แล้วย้อนกลับ สิ่งนี้ทำให้ฉันสงสัย:มีการปรับปรุง Unicode อื่นใดอีกบ้างตั้งแต่ปี 2013 เมื่อฉันอ่านบล็อกโพสต์บล็อกของ André Arko ใน Ruby เป็น UTF-8 ตอนนี้…ใช่ไหม

ฉันทดสอบวิธีการสตริงของ Ruby ทั้งหมด ไม่ได้มองหาข้อผิดพลาดทางเทคนิคแต่สำหรับการละเมิด "หลักการที่น่าประหลาดใจน้อยที่สุด" โดยเฉพาะอย่างยิ่ง สมมติฐานของฉันคือ:

  1. อักขระที่ไม่ซ้ำกันมีเอกลักษณ์เฉพาะ: "e" และ "ë" ต่างกัน เช่นเดียวกับ "e" และ "E"
  2. อักขระตัวเดียวนับเป็นอักขระตัวเดียว ไม่ว่าพวกมันจะแสดงเป็นยูนิโค้ดอย่างไร ซึ่งหมายความว่า "e" และ "ë" แต่ละตัวเป็นอักขระตัวเดียว แม้ว่าตัวหลังจะแสดงด้วยจุดโค้ดสองจุด
  3. ตัวละครไม่สามารถเปลี่ยนได้ การย้อนกลับสตริงของอักขระไม่ควรเปลี่ยนอักขระแต่ละตัว
  4. ช่องว่างถือเป็นช่องว่าง แม้แต่อักขระช่องว่าง Unicode ที่ยุ่งยากเหล่านั้น
  5. ตัวเลขถือเป็นตัวเลข เลข 2 จะเป็นเลข 2 เสมอไม่ว่าจะเขียนอย่างไร

น่าเสียดายที่วิธีจัดการสตริงของ Ruby ส่วนใหญ่ไม่ผ่านการทดสอบเหล่านี้ หากคุณกำลังทำงานกับสตริง Unicode คุณจึงต้องระมัดระวังเป็นอย่างยิ่งว่าจะใช้สตริงใด

หมายเหตุ:หลังจากการตีพิมพ์ ผู้อ่านบางคนชี้ให้เห็นว่าความล้มเหลวหลายอย่างที่ฉันพูดถึงจะไม่เกิดขึ้นถ้าฉันจะทำให้สตริงการทดสอบ Unicode เป็นมาตรฐาน นี่เป็นเรื่องจริง อย่างไรก็ตาม Ruby หรือ Rails จะไม่ทำให้สตริงเป็นมาตรฐานโดยอัตโนมัติ (ในแอปใดๆ ที่ฉันทดสอบ) การทดสอบเหล่านี้มีขึ้นเพื่อแสดงกรณีที่เลวร้ายที่สุดเสมอ และฉันคิดว่าการทดสอบเหล่านี้ยังคงมีประโยชน์ในเรื่องนั้น

ทดสอบ Unicode ด้วย Ruby 2.4.0

วิธีการ ทดสอบ คาดว่า ผลลัพธ์ คำพิพากษา
#% "%s" % "noël" "noël" "noël" ตกลง
#* "noël" * 2 "noëlnoël" "noëlnoël" ตกลง
#<< "noël" << "ë" "noël" "noël" ตกลง
#<=> "ä" <=> "z" -1 -1 ตกลง
#== "ä" == "ä" true true ตกลง
#=~ "ä" =~ /a./ nil 0 ระวัง!
#[] "ä"[0] "ä" "a" ระวัง!
#[]= "ä"[0] = "u" "u" "u" ตกลง
#b "ä".b.encoding.to_s "ASCII-8BIT" "ASCII-8BIT" ตกลง
#bytes "ä".bytes [97, 204, 136] [97, 204, 136] ตกลง
#bytesize "ä".bytesize 3 3 ตกลง
#byteslice "ä".byteslice(1) "\xCC" "\xCC" ตกลง
#capitalize "ä".capitalize "Ä" "Ä" ตกลง
#casecmp "äa".casecmp("äz") -1 -1 ตกลง
#center "ä".center(3) " ä " "ä " ระวัง!
#chars "ä".chars ["ä"] ["a", "̈"] ระวัง!
#chomp "ä ".chomp "ä" "ä" ตกลง
#chop "ä".chop "̈" "a" ระวัง!
#chr "ä".chr "ä" "a" ระวัง!
#เคลียร์ "ä".clear "̈" "̈" ตกลง
#codepoints "ä".codepoints [97, 776] [97, 776] ตกลง
#concat "ä".concat("x") "äx" "äx" ตกลง
#count "ä".count("a") 0 1 ระวัง!
#crypt "123".crypt("ää") == "123".crypt("aa") false false ตกลง
#delete "ä".delete("a") "ä" "̈" ระวัง!
#downcase "Ä".downcase "ä" "ä" ตกลง
#dump "ä".dump "\"a\\u0308\"" "\"a\\u0308\"" ตกลง
#each_byte "ä".each_byte.to_a [97, 204, 136] [97, 204, 136] ตกลง
#each_char "ä".each_char.to_a ["ä"] ["a", "̈"] ระวัง!
#each_codepoint "ä".each_codepoint.to_a [97, 776] [97, 776] ตกลง
#each_line "ä".each_line.to_a ["ä"] ["ä"] ตกลง
#ว่างไหม "ä".empty? false false ตกลง
#encode "ä".encode("ASCII", undef: :replace) "a?" "a?" ตกลง
#encoding "ä".encoding.to_s "UTF-8" "UTF-8" ตกลง
#end_with? "ä".end_with?("ä") true true ตกลง
#eql? "ä".eql?("a") false false ตกลง
#force_encoding "ä".force_encoding("ASCII") "a\xCC\x88" "a\xCC\x88" ตกลง
#getbyte "ä".getbyte(2) 136 136 ตกลง
#gsub "ä".gsub("a", "x") "ä" "ẍ" ระวัง!
#แฮช "ä".hash == "a".hash false false ตกลง
#include? "ä".include?("a") false true ระวัง!
#index "ä".index("a") nil 0 ระวัง!
#replace "ä".replace("u") "u" "u" ตกลง
#insert "ä".insert(1, "u") "äu" "aü" ระวัง!
#ตรวจสอบ "ä".inspect "\"ä\"" "\"ä\"" ตกลง
#ฝึกงาน "ä".intern :ä :ä ตกลง
#length "ä".length 1 2 ระวัง!
#ljust "ä".ljust(3, "_") "ä__" "ä_" ระวัง!
#lstrip " ä".lstrip "ä" "ä" ตกลง
#match "ä".match("a") nil # ระวัง!
#ต่อไป "ä".next "ä" "b̈" ระวัง!
#ord "ä".ord 97 97 ตกลง
#พาร์ทิชัน "händ".partition("a") ["händ"] ["h", "a", "̈nd"] ระวัง!
#prepend "ä".prepend("ä") "ää" "ää" ตกลง
#replace "ä".replace("ẍ") "ẍ" "ẍ" ตกลง
#ย้อนกลับ "händ".reverse "dnäh" "dn̈ah" ระวัง!
#rpartition "händ".rpartition("a") ["händ"] ["h", "a", "̈nd"] ระวัง!
#rstrip "line ".rstrip "line" "line " ระวัง!
#scrub "ä".scrub "ä" "ä" ตกลง
#setbyte s = "ä"; s.setbyte(0, "x".ord); s "ẍ" "ẍ" ตกลง
#ขนาด "ä".size 1 2 ระวัง!
#slice "ä".slice(0) "ä" "a" ระวัง!
#split "ä".split("a") ["ä"] ["", "̈"] ระวัง!
#บีบ "ää".squeeze("ä") "ä" "ää" ระวัง!
#start_with? "ä".start_with?("a") false true ระวัง!
#สตริป " line ".strip "line" " line " ระวัง!
#sub "ä".sub("a", "x") "ä" "ẍ" ระวัง!
#succ "ä".succ "b̈" "b̈" ตกลง
#swapcase "ä".swapcase "Ä" "Ä" ตกลง
#to_c "١".to_c (1+0i) (0+0i) ระวัง!
#to_f "١".to_f 1.0 0.0 ระวัง!
#to_i "١".to_i 1 0 ระวัง!
#to_r "١".to_r (1/1) (0/1) ระวัง!
#to_sym "ä".to_sym :ä :ä ตกลง
#tr "ä".tr("a", "b") "ä" "b̈" ระวัง!
#unpack "ä".unpack("CCC") [97, 204, 136] [97, 204, 136] ตกลง
#ไม่เกิน "ä".upto("c̈").to_a ["ä", "b̈", "c̈"] ["ä", "b̈", "c̈"] ตกลง
#valid_encoding? "ä".valid_encoding? true true ตกลง