-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move LanguageTag and LanguageRange from Hyperspace project
Add String>>#escaped and String>>#unescaped to handle character control and Unicode escape sequences
- Loading branch information
Showing
15 changed files
with
1,099 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
Extension { #name : 'String' } | ||
|
||
{ #category : '*Buoy-Localization-Extensions' } | ||
String >> asLanguageRange [ | ||
|
||
^ LanguageRange fromString: self | ||
] | ||
|
||
{ #category : '*Buoy-Localization-Extensions' } | ||
String >> asLanguageTag [ | ||
|
||
^ LanguageTag fromString: self | ||
] | ||
|
||
{ #category : '*Buoy-Localization-Extensions' } | ||
String >> escaped [ | ||
|
||
^ self species new: self size streamContents: [ :result | | ||
| stream | | ||
stream := self readStream. | ||
[ stream atEnd ] whileFalse: [ StringEscapingRule escape: stream next on: result ] | ||
] | ||
] | ||
|
||
{ #category : '*Buoy-Localization-Extensions' } | ||
String >> unescaped [ | ||
|
||
^ self species new: self size streamContents: [ :result | | ||
| stream | | ||
stream := self readStream. | ||
[ stream atEnd ] whileFalse: [ | ||
| currentChar | | ||
currentChar := stream next. | ||
currentChar == $\ | ||
ifTrue: [ | ||
stream atEnd | ||
ifTrue: [ AssertionFailed signal: 'Missing escape sequence' ] | ||
ifFalse: [ StringEscapingRule unescape: stream next from: stream on: result ] | ||
] | ||
ifFalse: [ result nextPut: currentChar ] | ||
] | ||
] | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Package { #name : 'Buoy-Localization-Extensions' } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
" | ||
A LanguageRangeTest is a test class for testing the behavior of LanguageRange | ||
" | ||
Class { | ||
#name : 'LanguageRangeTest', | ||
#superclass : 'TestCase', | ||
#category : 'Buoy-Localization-Tests', | ||
#package : 'Buoy-Localization-Tests' | ||
} | ||
|
||
{ #category : 'tests' } | ||
LanguageRangeTest >> testAny [ | ||
|
||
self | ||
assert: LanguageRange any printString equals: '*'; | ||
assert: LanguageRange any equals: LanguageRange any; | ||
assert: LanguageRange any hash equals: LanguageRange any hash; | ||
assert: LanguageRange any subtags equals: #('*') | ||
] | ||
|
||
{ #category : 'tests' } | ||
LanguageRangeTest >> testAnyMatches [ | ||
|
||
| range | | ||
|
||
range := LanguageRange any. | ||
self | ||
assert: ( range matches: 'en-Latn-US' asLanguageTag ); | ||
assert: ( range matches: 'en' asLanguageTag ); | ||
assert: ( range matches: 'es-ar' asLanguageTag ) | ||
] | ||
|
||
{ #category : 'tests' } | ||
LanguageRangeTest >> testAsLanguageRange [ | ||
|
||
self | ||
assert: '*' asLanguageRange equals: LanguageRange any; | ||
assert: LanguageRange any asLanguageRange equals: LanguageRange any; | ||
assert: 'es-AR' asLanguageRange equals: ( LanguageRange from: #( 'es' 'AR' ) ) asLanguageRange | ||
] | ||
|
||
{ #category : 'tests' } | ||
LanguageRangeTest >> testComparison [ | ||
|
||
| range | | ||
|
||
range := LanguageRange from: #('en' 'US'). | ||
self | ||
assert: range equals: ( LanguageRange fromString: 'en-us' ); | ||
assert: range hash equals: ( LanguageRange fromString: 'en-us' ) hash; | ||
deny: range equals: LanguageRange any; | ||
deny: range equals: ( LanguageRange from: #('en') ) | ||
] | ||
|
||
{ #category : 'tests' } | ||
LanguageRangeTest >> testCreation [ | ||
|
||
| range | | ||
|
||
range := LanguageRange from: #('en' 'Latn' 'us'). | ||
self | ||
assert: range subtags equals: #('en' 'Latn' 'US'); | ||
assert: range printString equals: 'en-Latn-US' | ||
] | ||
|
||
{ #category : 'tests' } | ||
LanguageRangeTest >> testMatches [ | ||
|
||
| range | | ||
|
||
range := LanguageRange from: #('en' 'US'). | ||
self | ||
deny: ( range matches: 'en-Latn-US' asLanguageTag ); | ||
assert: ( range matches: 'en-US' asLanguageTag ); | ||
deny: ( range matches: 'en' asLanguageTag ); | ||
assert: ( range matches: 'en-us-x-x-x' asLanguageTag ). | ||
|
||
range := LanguageRange from: #('en'). | ||
self | ||
assert: ( range matches: 'en-Latn-US' asLanguageTag ); | ||
assert: ( range matches: 'en-US' asLanguageTag ); | ||
assert: ( range matches: 'en' asLanguageTag ); | ||
assert: ( range matches: 'en-us-x-x-x' asLanguageTag ) | ||
] | ||
|
||
{ #category : 'tests' } | ||
LanguageRangeTest >> testSpecificity [ | ||
|
||
self | ||
assert: '*' asLanguageRange specificity equals: 0; | ||
assert: 'es' asLanguageRange specificity equals: 1; | ||
assert: 'es-AR' asLanguageRange specificity equals: 2; | ||
assert: 'hy-Latn-IT-arevela' asLanguageRange specificity equals: 4 | ||
] |
125 changes: 125 additions & 0 deletions
125
source/Buoy-Localization-Tests/LanguageTagTest.class.st
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
" | ||
A LanguageTagTest is a test class for testing the behavior of LanguageTag | ||
" | ||
Class { | ||
#name : 'LanguageTagTest', | ||
#superclass : 'TestCase', | ||
#category : 'Buoy-Localization-Tests', | ||
#package : 'Buoy-Localization-Tests' | ||
} | ||
|
||
{ #category : 'tests' } | ||
LanguageTagTest >> testCantCreateWhenLanguageCodeIsInvalid [ | ||
|
||
self | ||
should: [ LanguageTag fromString: 'e' ] | ||
raise: InstanceCreationFailed | ||
withMessageText: 'ISO 639 language codes must be 2 or 3 letters.'; | ||
should: [ LanguageTag fromString: 'e2' ] | ||
raise: InstanceCreationFailed | ||
withMessageText: 'ISO 639 language codes must consist only of letters.' | ||
] | ||
|
||
{ #category : 'tests' } | ||
LanguageTagTest >> testCantCreateWhenRegionIsInvalid [ | ||
|
||
self | ||
should: [ LanguageTag fromString: 'en-A3' ] | ||
raise: InstanceCreationFailed | ||
withMessageText: 'Supported ISO 3166-1 codes must be 2 letters.' | ||
] | ||
|
||
{ #category : 'tests' } | ||
LanguageTagTest >> testCantCreateWhenScriptIsInvalid [ | ||
|
||
self | ||
should: [ LanguageTag fromString: 'en-L123' ] | ||
raise: InstanceCreationFailed | ||
withMessageText: 'ISO 15924 script codes must be 4 letters.' | ||
] | ||
|
||
{ #category : 'tests' } | ||
LanguageTagTest >> testCreation [ | ||
|
||
| tag | | ||
|
||
tag := LanguageTag fromString: 'en-Latn-US'. | ||
self assert: tag languageCode equals: 'en'. | ||
tag | ||
withScriptDo: [ :script | self assert: script equals: 'Latn' ]; | ||
withRegionDo: [ :region | self assert: region equals: 'US' ]. | ||
|
||
self assert: tag subtags equals: #('en' 'Latn' 'US') | ||
] | ||
|
||
{ #category : 'tests' } | ||
LanguageTagTest >> testCreationWithExtensions [ | ||
|
||
| tag | | ||
|
||
tag := LanguageTag fromString: 'en-Latn-GB-boont-r-extended-sequence-x-private'. | ||
self assert: tag languageCode equals: 'en'. | ||
tag | ||
withScriptDo: [ :script | self assert: script equals: 'Latn' ]; | ||
withRegionDo: [ :region | self assert: region equals: 'GB' ]. | ||
|
||
self | ||
assert: tag subtags | ||
equals: #('en' 'Latn' 'GB' 'boont' 'r' 'extended' 'sequence' 'x' 'private') | ||
] | ||
|
||
{ #category : 'tests' } | ||
LanguageTagTest >> testCreationWithHorribleCase [ | ||
|
||
| tag | | ||
|
||
tag := LanguageTag fromString: 'Es-lAtN-aR'. | ||
self assert: tag languageCode equals: 'es'. | ||
tag | ||
withScriptDo: [ :script | self assert: script equals: 'Latn' ]; | ||
withRegionDo: [ :region | self assert: region equals: 'AR' ]. | ||
|
||
self assert: tag subtags equals: #('es' 'Latn' 'AR') | ||
] | ||
|
||
{ #category : 'tests' } | ||
LanguageTagTest >> testCreationWithOnlyLanguage [ | ||
|
||
| tag | | ||
|
||
tag := LanguageTag fromString: 'en'. | ||
self assert: tag languageCode equals: 'en'. | ||
tag | ||
withScriptDo: [ :script | self fail ]; | ||
withRegionDo: [ :region | self fail ]. | ||
|
||
self assert: tag subtags equals: #('en') | ||
] | ||
|
||
{ #category : 'tests' } | ||
LanguageTagTest >> testCreationWithRegionButNotScript [ | ||
|
||
| tag | | ||
|
||
tag := LanguageTag fromString: 'en-us'. | ||
self assert: tag languageCode equals: 'en'. | ||
tag | ||
withScriptDo: [ :script | self fail ]; | ||
withRegionDo: [ :region | self assert: region equals: 'US' ]. | ||
|
||
self assert: tag subtags equals: #('en' 'US') | ||
] | ||
|
||
{ #category : 'tests' } | ||
LanguageTagTest >> testCreationWithScriptButNoRegion [ | ||
|
||
| tag | | ||
|
||
tag := LanguageTag fromString: 'es-latn'. | ||
self assert: tag languageCode equals: 'es'. | ||
tag | ||
withScriptDo: [ :script | self assert: script equals: 'Latn' ]; | ||
withRegionDo: [ :region | self fail ]. | ||
|
||
self assert: tag subtags equals: #('es' 'Latn') | ||
] |
23 changes: 23 additions & 0 deletions
23
source/Buoy-Localization-Tests/StringEscapingRuleTest.class.st
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
" | ||
A StringEscapingRuleTest is a test class for testing the behavior of StringEscapingRule | ||
" | ||
Class { | ||
#name : 'StringEscapingRuleTest', | ||
#superclass : 'TestCase', | ||
#category : 'Buoy-Localization-Tests', | ||
#package : 'Buoy-Localization-Tests' | ||
} | ||
|
||
{ #category : 'tests' } | ||
StringEscapingRuleTest >> testIsAbstract [ | ||
|
||
self assert: StringEscapingRule isAbstract | ||
] | ||
|
||
{ #category : 'tests' } | ||
StringEscapingRuleTest >> testPriority [ | ||
|
||
self | ||
assert: ReverseSolidusEscapingRule new priority > ControlCharactersEscapingRule new priority; | ||
assert: ControlCharactersEscapingRule new priority > UnicodeCharacterEscapingRule new priority | ||
] |
Oops, something went wrong.