Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into feature/process-r…
Browse files Browse the repository at this point in the history
…un-io-non-blocking
  • Loading branch information
HertzDevil committed Sep 2, 2024
2 parents 0f7c02c + e6b5b94 commit df2a047
Show file tree
Hide file tree
Showing 19 changed files with 682 additions and 53 deletions.
136 changes: 136 additions & 0 deletions spec/compiler/crystal/tools/doc/type_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -212,4 +212,140 @@ describe Doc::Type do
type.macros.map(&.name).should eq ["+", "~", "foo"]
end
end

describe "#subclasses" do
it "only include types with docs" do
program = semantic(<<-CRYSTAL, wants_doc: true).program
class Foo
end
class Bar < Foo
end
# :nodoc:
class Baz < Foo
end
module Mod1
class Bar < ::Foo
end
end
# :nodoc:
module Mod2
class Baz < ::Foo
end
end
CRYSTAL

generator = Doc::Generator.new program, [""]
type = generator.type(program.types["Foo"])
type.subclasses.map(&.full_name).should eq ["Bar", "Mod1::Bar"]
end
end

describe "#ancestors" do
it "only include types with docs" do
program = semantic(<<-CRYSTAL, wants_doc: true).program
# :nodoc:
module Mod3
class Baz
end
end
class Mod2::Baz < Mod3::Baz
end
module Mod1
# :nodoc:
class Baz < Mod2::Baz
end
end
class Baz < Mod1::Baz
end
class Foo < Baz
end
CRYSTAL

generator = Doc::Generator.new program, [""]
type = generator.type(program.types["Foo"])
type.ancestors.map(&.full_name).should eq ["Baz", "Mod2::Baz"]
end
end

describe "#included_modules" do
it "only include types with docs" do
program = semantic(<<-CRYSTAL, wants_doc: true).program
# :nodoc:
module Mod3
module Baz
end
end
module Mod2
# :nodoc:
module Baz
end
end
module Mod1
module Baz
end
end
module Baz
end
class Foo
include Baz
include Mod1::Baz
include Mod2::Baz
include Mod3::Baz
end
CRYSTAL

generator = Doc::Generator.new program, [""]
type = generator.type(program.types["Foo"])
type.included_modules.map(&.full_name).should eq ["Baz", "Mod1::Baz"]
end
end

describe "#included_modules" do
it "only include types with docs" do
program = semantic(<<-CRYSTAL, wants_doc: true).program
# :nodoc:
module Mod3
module Baz
end
end
module Mod2
# :nodoc:
module Baz
end
end
module Mod1
module Baz
end
end
module Baz
end
class Foo
extend Baz
extend Mod1::Baz
extend Mod2::Baz
extend Mod3::Baz
end
CRYSTAL

generator = Doc::Generator.new program, [""]
type = generator.type(program.types["Foo"])
type.extended_modules.map(&.full_name).should eq ["Baz", "Mod1::Baz"]
end
end
end
6 changes: 6 additions & 0 deletions spec/std/string_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -957,13 +957,16 @@ describe "String" do
it { "日本語".index('本').should eq(1) }
it { "bar".index('あ').should be_nil }
it { "あいう_えお".index('_').should eq(3) }
it { "xyz\xFFxyz".index('\u{FFFD}').should eq(3) }

describe "with offset" do
it { "foobarbaz".index('a', 5).should eq(7) }
it { "foobarbaz".index('a', -4).should eq(7) }
it { "foo".index('g', 1).should be_nil }
it { "foo".index('g', -20).should be_nil }
it { "日本語日本語".index('本', 2).should eq(4) }
it { "xyz\xFFxyz".index('\u{FFFD}', 2).should eq(3) }
it { "xyz\xFFxyz".index('\u{FFFD}', 4).should be_nil }

# Check offset type
it { "foobarbaz".index('a', 5_i64).should eq(7) }
Expand Down Expand Up @@ -1106,6 +1109,7 @@ describe "String" do
it { "foobar".rindex('g').should be_nil }
it { "日本語日本語".rindex('本').should eq(4) }
it { "あいう_えお".rindex('_').should eq(3) }
it { "xyz\xFFxyz".rindex('\u{FFFD}').should eq(3) }

describe "with offset" do
it { "bbbb".rindex('b', 2).should eq(2) }
Expand All @@ -1118,6 +1122,8 @@ describe "String" do
it { "faobar".rindex('a', 3).should eq(1) }
it { "faobarbaz".rindex('a', -3).should eq(4) }
it { "日本語日本語".rindex('本', 3).should eq(1) }
it { "xyz\xFFxyz".rindex('\u{FFFD}', 4).should eq(3) }
it { "xyz\xFFxyz".rindex('\u{FFFD}', 2).should be_nil }

# Check offset type
it { "bbbb".rindex('b', 2_i64).should eq(2) }
Expand Down
38 changes: 28 additions & 10 deletions spec/std/system/user_spec.cr
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
{% skip_file if flag?(:win32) %}

require "spec"
require "system/user"

USER_NAME = {{ `id -un`.stringify.chomp }}
USER_ID = {{ `id -u`.stringify.chomp }}
{% if flag?(:win32) %}
{% name, id = `whoami /USER /FO TABLE /NH`.stringify.chomp.split(" ") %}
USER_NAME = {{ name }}
USER_ID = {{ id }}
{% else %}
USER_NAME = {{ `id -un`.stringify.chomp }}
USER_ID = {{ `id -u`.stringify.chomp }}
{% end %}

INVALID_USER_NAME = "this_user_does_not_exist"
INVALID_USER_ID = {% if flag?(:android) %}"8888"{% else %}"1234567"{% end %}

def normalized_username(username)
# on Windows, domain names are case-insensitive, so we unify the letter case
# from sources like `whoami`, `hostname`, or Win32 APIs
{% if flag?(:win32) %}
domain, _, user = username.partition('\\')
"#{domain.upcase}\\#{user}"
{% else %}
username
{% end %}
end

describe System::User do
describe ".find_by(*, name)" do
it "returns a user by name" do
user = System::User.find_by(name: USER_NAME)

user.should be_a(System::User)
user.username.should eq(USER_NAME)
normalized_username(user.username).should eq(normalized_username(USER_NAME))
user.id.should eq(USER_ID)
end

Expand All @@ -31,7 +47,7 @@ describe System::User do

user.should be_a(System::User)
user.id.should eq(USER_ID)
user.username.should eq(USER_NAME)
normalized_username(user.username).should eq(normalized_username(USER_NAME))
end

it "raises on nonexistent user id" do
Expand All @@ -46,7 +62,7 @@ describe System::User do
user = System::User.find_by?(name: USER_NAME).not_nil!

user.should be_a(System::User)
user.username.should eq(USER_NAME)
normalized_username(user.username).should eq(normalized_username(USER_NAME))
user.id.should eq(USER_ID)
end

Expand All @@ -62,7 +78,7 @@ describe System::User do

user.should be_a(System::User)
user.id.should eq(USER_ID)
user.username.should eq(USER_NAME)
normalized_username(user.username).should eq(normalized_username(USER_NAME))
end

it "returns nil on nonexistent user id" do
Expand All @@ -73,7 +89,8 @@ describe System::User do

describe "#username" do
it "is the same as the source name" do
System::User.find_by(name: USER_NAME).username.should eq(USER_NAME)
user = System::User.find_by(name: USER_NAME)
normalized_username(user.username).should eq(normalized_username(USER_NAME))
end
end

Expand Down Expand Up @@ -109,7 +126,8 @@ describe System::User do

describe "#to_s" do
it "returns a string representation" do
System::User.find_by(name: USER_NAME).to_s.should eq("#{USER_NAME} (#{USER_ID})")
user = System::User.find_by(name: USER_NAME)
user.to_s.should eq("#{user.username} (#{user.id})")
end
end
end
65 changes: 65 additions & 0 deletions src/big/big_float.cr
Original file line number Diff line number Diff line change
Expand Up @@ -115,18 +115,60 @@ struct BigFloat < Float
BigFloat.new { |mpf| LibGMP.mpf_neg(mpf, self) }
end

def +(other : Int::Primitive) : BigFloat
Int.primitive_ui_check(other) do |ui, neg_ui, big_i|
{
ui: BigFloat.new { |mpf| LibGMP.mpf_add_ui(mpf, self, {{ ui }}) },
neg_ui: BigFloat.new { |mpf| LibGMP.mpf_sub_ui(mpf, self, {{ neg_ui }}) },
big_i: self + {{ big_i }},
}
end
end

def +(other : Number) : BigFloat
BigFloat.new { |mpf| LibGMP.mpf_add(mpf, self, other.to_big_f) }
end

def -(other : Int::Primitive) : BigFloat
Int.primitive_ui_check(other) do |ui, neg_ui, big_i|
{
ui: BigFloat.new { |mpf| LibGMP.mpf_sub_ui(mpf, self, {{ ui }}) },
neg_ui: BigFloat.new { |mpf| LibGMP.mpf_add_ui(mpf, self, {{ neg_ui }}) },
big_i: self - {{ big_i }},
}
end
end

def -(other : Number) : BigFloat
BigFloat.new { |mpf| LibGMP.mpf_sub(mpf, self, other.to_big_f) }
end

def *(other : Int::Primitive) : BigFloat
Int.primitive_ui_check(other) do |ui, neg_ui, big_i|
{
ui: BigFloat.new { |mpf| LibGMP.mpf_mul_ui(mpf, self, {{ ui }}) },
neg_ui: BigFloat.new { |mpf| LibGMP.mpf_mul_ui(mpf, self, {{ neg_ui }}); LibGMP.mpf_neg(mpf, mpf) },
big_i: self + {{ big_i }},
}
end
end

def *(other : Number) : BigFloat
BigFloat.new { |mpf| LibGMP.mpf_mul(mpf, self, other.to_big_f) }
end

def /(other : Int::Primitive) : BigFloat
# Division by 0 in BigFloat is not allowed, there is no BigFloat::Infinity
raise DivisionByZeroError.new if other == 0
Int.primitive_ui_check(other) do |ui, neg_ui, _|
{
ui: BigFloat.new { |mpf| LibGMP.mpf_div_ui(mpf, self, {{ ui }}) },
neg_ui: BigFloat.new { |mpf| LibGMP.mpf_div_ui(mpf, self, {{ neg_ui }}); LibGMP.mpf_neg(mpf, mpf) },
big_i: BigFloat.new { |mpf| LibGMP.mpf_div(mpf, self, BigFloat.new(other)) },
}
end
end

def /(other : BigFloat) : BigFloat
# Division by 0 in BigFloat is not allowed, there is no BigFloat::Infinity
raise DivisionByZeroError.new if other == 0
Expand Down Expand Up @@ -448,6 +490,29 @@ struct Int
def <=>(other : BigFloat)
-(other <=> self)
end

def -(other : BigFloat) : BigFloat
Int.primitive_ui_check(self) do |ui, neg_ui, _|
{
ui: BigFloat.new { |mpf| LibGMP.mpf_neg(mpf, other); LibGMP.mpf_add_ui(mpf, mpf, {{ ui }}) },
neg_ui: BigFloat.new { |mpf| LibGMP.mpf_neg(mpf, other); LibGMP.mpf_sub_ui(mpf, mpf, {{ neg_ui }}) },
big_i: BigFloat.new { |mpf| LibGMP.mpf_sub(mpf, BigFloat.new(self), other) },
}
end
end

def /(other : BigFloat) : BigFloat
# Division by 0 in BigFloat is not allowed, there is no BigFloat::Infinity
raise DivisionByZeroError.new if other == 0

Int.primitive_ui_check(self) do |ui, neg_ui, _|
{
ui: BigFloat.new { |mpf| LibGMP.mpf_ui_div(mpf, {{ ui }}, other) },
neg_ui: BigFloat.new { |mpf| LibGMP.mpf_ui_div(mpf, {{ neg_ui }}, other); LibGMP.mpf_neg(mpf, mpf) },
big_i: BigFloat.new { |mpf| LibGMP.mpf_div(mpf, BigFloat.new(self), other) },
}
end
end
end

struct Float
Expand Down
3 changes: 3 additions & 0 deletions src/big/lib_gmp.cr
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,11 @@ lib LibGMP

# # Arithmetic
fun mpf_add = __gmpf_add(rop : MPF*, op1 : MPF*, op2 : MPF*)
fun mpf_add_ui = __gmpf_add_ui(rop : MPF*, op1 : MPF*, op2 : UI)
fun mpf_sub = __gmpf_sub(rop : MPF*, op1 : MPF*, op2 : MPF*)
fun mpf_sub_ui = __gmpf_sub_ui(rop : MPF*, op1 : MPF*, op2 : UI)
fun mpf_mul = __gmpf_mul(rop : MPF*, op1 : MPF*, op2 : MPF*)
fun mpf_mul_ui = __gmpf_mul_ui(rop : MPF*, op1 : MPF*, op2 : UI)
fun mpf_div = __gmpf_div(rop : MPF*, op1 : MPF*, op2 : MPF*)
fun mpf_div_ui = __gmpf_div_ui(rop : MPF*, op1 : MPF*, op2 : UI)
fun mpf_ui_div = __gmpf_ui_div(rop : MPF*, op1 : UI, op2 : MPF*)
Expand Down
Loading

0 comments on commit df2a047

Please sign in to comment.