Skip to content

Commit

Permalink
Merge pull request #1232 from herwinw/encoding_default_external
Browse files Browse the repository at this point in the history
  • Loading branch information
seven1m authored Sep 13, 2023
2 parents 2590603 + c5ac882 commit b28c199
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 7 deletions.
2 changes: 1 addition & 1 deletion include/natalie/encoding/utf8_encoding_object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ using namespace TM;
class Utf8EncodingObject : public EncodingObject {
public:
Utf8EncodingObject()
: EncodingObject { Encoding::UTF_8, { "UTF-8", "CP65001", "locale", "external", "filesystem" } } { }
: EncodingObject { Encoding::UTF_8, { "UTF-8", "CP65001" } } { }

virtual bool valid_codepoint(nat_int_t codepoint) const override {
// from RFC3629: 0x0..0x10FFFF are valid, with exception of 0xD800-0xDFFF
Expand Down
69 changes: 69 additions & 0 deletions spec/core/encoding/default_external_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
require_relative '../../spec_helper'

describe "Encoding.default_external" do
before :each do
@original_encoding = Encoding.default_external
end

after :each do
Encoding.default_external = @original_encoding
end

it "returns an Encoding object" do
Encoding.default_external.should be_an_instance_of(Encoding)
end

it "returns the default external encoding" do
Encoding.default_external = Encoding::SHIFT_JIS
Encoding.default_external.should == Encoding::SHIFT_JIS
end

platform_is :windows do
it 'is UTF-8 by default on Windows' do
Encoding.default_external.should == Encoding::UTF_8
end
end
end

describe "Encoding.default_external=" do
before :each do
@original_encoding = Encoding.default_external
end

after :each do
Encoding.default_external = @original_encoding
end

it "sets the default external encoding" do
Encoding.default_external = Encoding::SHIFT_JIS
Encoding.default_external.should == Encoding::SHIFT_JIS
Encoding.find('external').should == Encoding::SHIFT_JIS
end

platform_is_not :windows do
it "also sets the filesystem encoding" do
Encoding.default_external = Encoding::SHIFT_JIS
Encoding.find('filesystem').should == Encoding::SHIFT_JIS
end
end

it "can accept a name of an encoding as a String" do
Encoding.default_external = 'Shift_JIS'
Encoding.default_external.should == Encoding::SHIFT_JIS
end

it "calls #to_s on arguments that are neither Strings nor Encodings" do
string = mock('string')
string.should_receive(:to_str).at_least(1).and_return('US-ASCII')
Encoding.default_external = string
Encoding.default_external.should == Encoding::ASCII
end

it "raises a TypeError unless the argument is an Encoding or convertible to a String" do
-> { Encoding.default_external = [] }.should raise_error(TypeError)
end

it "raises an ArgumentError if the argument is nil" do
-> { Encoding.default_external = nil }.should raise_error(ArgumentError)
end
end
17 changes: 11 additions & 6 deletions src/encoding_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,14 @@ HashObject *EncodingObject::aliases(Env *env) {
auto aliases = new HashObject();
for (auto encoding : *list(env)) {
auto enc = encoding->as_encoding();
const auto &names = enc->m_names;
const auto names = enc->names(env);

if (names.size() < 2)
if (names->size() < 2)
continue;

auto original = new StringObject { names[0] };
for (size_t i = 1; i < names.size(); ++i)
aliases->put(env, new StringObject { names[i] }, original);
auto original = (*names)[0]->dup(env);
for (size_t i = 1; i < names->size(); ++i)
aliases->put(env, (*names)[i]->dup(env), original);
}
return aliases;
}
Expand All @@ -99,6 +99,7 @@ EncodingObject *EncodingObject::set_default_external(Env *env, Value arg) {
auto name = arg->to_str(env);
s_default_external = find(env, name)->as_encoding();
}
s_filesystem = s_default_external;
return default_external();
}
EncodingObject *EncodingObject::set_default_internal(Env *env, Value arg) {
Expand All @@ -120,7 +121,7 @@ Value EncodingObject::find(Env *env, Value name) {
return name;
if (!name->is_string())
name = name->to_str(env);
auto string = name->as_string()->string();
auto string = name->as_string()->string().lowercase();
if (string == "internal") {
auto intenc = EncodingObject::default_internal();
if (!intenc) return NilObject::the();
Expand Down Expand Up @@ -206,6 +207,10 @@ ArrayObject *EncodingObject::names(Env *env) const {
auto array = new ArrayObject { m_names.size() };
for (const auto &name : m_names)
array->push(new StringObject { name });
if (this == s_locale) array->push(new StringObject { "locale" });
if (this == s_default_external) array->push(new StringObject { "external" });
if (this == s_filesystem) array->push(new StringObject { "filesystem" });
if (this == s_default_internal) array->push(new StringObject { "internal" });
return array;
}

Expand Down

0 comments on commit b28c199

Please sign in to comment.