Skip to content

Commit

Permalink
Merge branch 'master' into feat/unreachable-relative_paths
Browse files Browse the repository at this point in the history
  • Loading branch information
straight-shoota committed Nov 5, 2023
2 parents 031b0a1 + 3a1b8e3 commit 8d8de72
Show file tree
Hide file tree
Showing 37 changed files with 3,012 additions and 2,474 deletions.
5 changes: 2 additions & 3 deletions spec/compiler/config_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ require "./spec_helper"
describe Crystal::Config do
it ".host_target" do
{% begin %}
# TODO: CRYSTAL_SPEC_COMPILER_BIN must be quoted (#11456)
{% compiler = (env("CRYSTAL_SPEC_COMPILER_BIN") || "bin/crystal").id %}
Crystal::Config.host_target.should eq Crystal::Codegen::Target.new({{ `#{compiler} --version`.lines[-1] }}.lchop("Default target: "))
{% host_triple = Crystal.constant("HOST_TRIPLE") || Crystal::DESCRIPTION.lines[-1].gsub(/^Default target: /, "") %}
Crystal::Config.host_target.should eq Crystal::Codegen::Target.new({{ host_triple }})
{% end %}
end

Expand Down
8 changes: 3 additions & 5 deletions spec/compiler/crystal/tools/unreachable_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ def processed_unreachable_visitor(code)
visitor.excludes << Path[Dir.current].to_posix.to_s
visitor.includes << "."

process_result = visitor.process(result)

{visitor, process_result}
visitor.process(result)
end

private def assert_unreachable(code, file = __FILE__, line = __LINE__)
Expand All @@ -27,9 +25,9 @@ private def assert_unreachable(code, file = __FILE__, line = __LINE__)

code = code.gsub('༓', "")

visitor, result = processed_unreachable_visitor(code)
defs = processed_unreachable_visitor(code)

result_location = result.defs.try &.compact_map(&.location).sort_by! do |loc|
result_location = defs.try &.compact_map(&.location).sort_by! do |loc|
{loc.filename.as(String), loc.line_number, loc.column_number}
end.map(&.to_s)

Expand Down
40 changes: 40 additions & 0 deletions spec/compiler/parser/parser_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,34 @@ module Crystal
it_parses "[1] /2", Call.new(([1.int32] of ASTNode).array, "/", 2.int32)
it_parses "2**3**4", Call.new(2.int32, "**", Call.new(3.int32, "**", 4.int32))

it_parses %(foo%i), Call.new("foo".call, "%", "i".call)
it_parses %(foo%q), Call.new("foo".call, "%", "q".call)
it_parses %(foo%Q), Call.new("foo".call, "%", "Q".path)
it_parses %(foo%r), Call.new("foo".call, "%", "r".call)
it_parses %(foo%x), Call.new("foo".call, "%", "x".call)
it_parses %(foo%w), Call.new("foo".call, "%", "w".call)

it_parses %(foo %i), Call.new("foo".call, "%", "i".call)
it_parses %(foo %q), Call.new("foo".call, "%", "q".call)
it_parses %(foo %Q), Call.new("foo".call, "%", "Q".path)
it_parses %(foo %r), Call.new("foo".call, "%", "r".call)
it_parses %(foo %x), Call.new("foo".call, "%", "x".call)
it_parses %(foo %w), Call.new("foo".call, "%", "w".call)

it_parses %(foo %i()), "foo".call(([] of ASTNode).array_of(Path.global("Symbol")))
it_parses %(foo %q()), "foo".call("".string)
it_parses %(foo %Q()), "foo".call("".string)
it_parses %(foo %r()), "foo".call(regex(""))
it_parses %(foo %x()), "foo".call(Call.new(nil, "`", "".string))
it_parses %(foo %w()), "foo".call(([] of ASTNode).array_of(Path.global("String")))

it_parses %(foo % i()), Call.new("foo".call, "%", "i".call)
it_parses %(foo % q()), Call.new("foo".call, "%", "q".call)
it_parses %(foo % Q()), Call.new("foo".call, "%", Generic.new("Q".path, [] of ASTNode))
it_parses %(foo % r()), Call.new("foo".call, "%", "r".call)
it_parses %(foo % x()), Call.new("foo".call, "%", "x".call)
it_parses %(foo % w()), Call.new("foo".call, "%", "w".call)

it_parses "!1", Not.new(1.int32)
it_parses "- 1", Call.new(1.int32, "-")
it_parses "+ 1", Call.new(1.int32, "+")
Expand Down Expand Up @@ -2736,5 +2764,17 @@ module Crystal
node = Parser.parse(source).as(EnumDef).members.first
node_source(source, node).should eq("protected macro foo; end")
end

it "sets correct location of global path in class def" do
source = "class ::Foo; end"
node = Parser.parse(source).as(ClassDef).name
node_source(source, node).should eq("::Foo")
end

it "sets correct location of global path in annotation" do
source = "@[::Foo]"
node = Parser.parse(source).as(Annotation).path
node_source(source, node).should eq("::Foo")
end
end
end
1 change: 1 addition & 0 deletions spec/compiler/parser/to_s_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ describe "ASTNode#to_s" do
expect_to_s %q(%r{#{1}\/\0}), %q(/#{1}\/\0/)
expect_to_s %q(`\n\0`), %q(`\n\u0000`)
expect_to_s %q(`#{1}\n\0`), %q(`#{1}\n\u0000`)
expect_to_s Call.new(nil, "`", Call.new("String".path, "interpolation", "x".var, global: true)), %q(`#{::String.interpolation(x)}`)
expect_to_s "macro foo\n{% verbatim do %}1{% end %}\nend"
expect_to_s Assign.new("x".var, Expressions.new([1.int32, 2.int32] of ASTNode)), "x = (1\n2\n)"
expect_to_s "foo.*"
Expand Down
120 changes: 54 additions & 66 deletions spec/compiler/semantic/private_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -318,76 +318,64 @@ describe "Semantic: private" do
)) { int32 }
end

it "doesn't find private class from outside namespace" do
assert_error %(
class Foo
private class Bar
end
end
Foo::Bar
),
"private constant Foo::Bar referenced"
end

it "doesn't find private module from outside namespace" do
assert_error %(
class Foo
private module Bar
end
end
Foo::Bar
),
"private constant Foo::Bar referenced"
end

it "doesn't find private enum from outside namespace" do
assert_error %(
class Foo
private enum Bar
A
end
end
Foo::Bar
),
"private constant Foo::Bar referenced"
end

it "doesn't find private alias from outside namespace" do
assert_error %(
class Foo
private alias Bar = Int32
end
Foo::Bar
),
"private constant Foo::Bar referenced"
end

it "doesn't find private lib from outside namespace" do
assert_error %(
class Foo
private lib LibBar
{% for kind, decl in {
"class" => %(class Bar; end),
"module" => %(module Bar; end),
"enum" => %(enum Bar; A; end),
"alias" => %(alias Bar = Int32),
"lib" => %(lib Bar; end),
"constant" => %(Bar = 1),
} %}
it "doesn't find private {{ kind.id }} from outside namespace" do
assert_error <<-CRYSTAL, "private constant Foo::Bar referenced"
module Foo
private {{ decl.id }}
end
end
Foo::LibBar
),
"private constant Foo::LibBar referenced"
end
Foo::Bar
CRYSTAL
end
{% end %}

{% for kind, decl in {
"class" => %(class Foo::Bar; end),
"module" => %(module Foo::Bar; end),
"enum" => %(enum Foo::Bar; A; end),
"alias" => %(alias Foo::Bar = Int32),
"lib" => %(lib Foo::Bar; end),
"constant" => %(Foo::Bar = 1),
} %}
it "doesn't find private {{ kind.id }} from outside namespace, long name (#8831)" do
assert_error <<-CRYSTAL, "private constant Foo::Bar referenced"
private {{ decl.id }}
Foo::Bar
CRYSTAL
end

it "doesn't find private constant from outside namespace" do
assert_error %(
class Foo
private Bar = 1
end
it "doesn't define incorrect type in top-level namespace (#13511)" do
assert_error <<-CRYSTAL, "undefined constant Bar"
private {{ decl.id }}
Foo::Bar
),
"private constant Foo::Bar referenced"
end
Bar
CRYSTAL
end
{% end %}

{% for kind, decl in {
"class" => %(class ::Foo; end),
"module" => %(module ::Foo; end),
"enum" => %(enum ::Foo; A; end),
"alias" => %(alias ::Foo = Int32),
"lib" => %(lib ::Foo; end),
"constant" => %(::Foo = 1),
} %}
it "doesn't define private {{ kind.id }} with global type name" do
assert_error <<-CRYSTAL, "can't declare private type in the global namespace"
private {{ decl.id }}
CRYSTAL
end
{% end %}

it "finds private type from inside namespace" do
assert_type(%(
Expand Down
12 changes: 12 additions & 0 deletions spec/std/big/big_decimal_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,18 @@ describe BigDecimal do
(-1.to_big_d - BigDecimal.new(50000, 204)).round(200, mode: :ties_even).should eq(-1.to_big_d - BigDecimal.new(5, 200))
end
end

describe "#integer?" do
it { BigDecimal.new(0, 0).integer?.should be_true }
it { BigDecimal.new(1, 0).integer?.should be_true }
it { BigDecimal.new(10, 0).integer?.should be_true }
it { BigDecimal.new(-10, 1).integer?.should be_true }
it { BigDecimal.new(10000, 4).integer?.should be_true }

it { BigDecimal.new(1, 1).integer?.should be_false }
it { BigDecimal.new(13, 2).integer?.should be_false }
it { BigDecimal.new(-2400, 3).integer?.should be_false }
end
end

describe "#inspect" do
Expand Down
6 changes: 6 additions & 0 deletions spec/std/big/big_float_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,12 @@ describe "BigFloat" do
end
end

describe "#integer?" do
it { BigFloat.zero.integer?.should be_true }
it { 1.to_big_f.integer?.should be_true }
it { 1.2.to_big_f.integer?.should be_false }
end

it "#hash" do
b = 123.to_big_f
b.hash.should eq(b.to_f64.hash)
Expand Down
5 changes: 5 additions & 0 deletions spec/std/big/big_int_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ private def it_converts_to_s(num, str, *, file = __FILE__, line = __LINE__, **op
end

describe "BigInt" do
describe "#integer?" do
it { BigInt.zero.integer?.should be_true }
it { 12345.to_big_i.integer?.should be_true }
end

it "creates with a value of zero" do
BigInt.new.to_s.should eq("0")
end
Expand Down
9 changes: 9 additions & 0 deletions spec/std/big/big_rational_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,15 @@ describe BigRational do
end
end

describe "#integer?" do
it { br(0, 1).integer?.should be_true }
it { br(1, 1).integer?.should be_true }
it { br(9, 3).integer?.should be_true }
it { br(-126, 7).integer?.should be_true }
it { br(5, 2).integer?.should be_false }
it { br(7, -3).integer?.should be_false }
end

it "#hash" do
b = br(10, 3)
hash = b.hash
Expand Down
5 changes: 5 additions & 0 deletions spec/std/char/reader_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,18 @@ describe "Char::Reader" do
reader.pos.should eq(0)
reader.current_char.ord.should eq(0)
reader.has_previous?.should be_false
reader.has_next?.should be_false
end

it "gets previous char (ascii)" do
reader = Char::Reader.new(at_end: "hello")
reader.pos.should eq(4)
reader.current_char.should eq('o')
reader.has_previous?.should be_true
reader.has_next?.should be_true

reader.previous_char.should eq('l')
reader.has_next?.should be_true
reader.previous_char.should eq('l')
reader.previous_char.should eq('e')
reader.previous_char.should eq('h')
Expand All @@ -126,8 +129,10 @@ describe "Char::Reader" do
reader.pos.should eq(9)
reader.current_char.should eq('語')
reader.has_previous?.should be_true
reader.has_next?.should be_true

reader.previous_char.should eq('本')
reader.has_next?.should be_true
reader.previous_char.should eq('日')
reader.previous_char.should eq('á')
reader.previous_char.should eq('h')
Expand Down
17 changes: 17 additions & 0 deletions spec/std/float_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,23 @@ describe "Float" do
it { 2.9.ceil.should eq(3) }
end

describe "#integer?" do
it { 1.0_f32.integer?.should be_true }
it { 1.0_f64.integer?.should be_true }

it { 1.2_f32.integer?.should be_false }
it { 1.2_f64.integer?.should be_false }

it { Float32::MAX.integer?.should be_true }
it { Float64::MAX.integer?.should be_true }

it { Float32::INFINITY.integer?.should be_false }
it { Float64::INFINITY.integer?.should be_false }

it { Float32::NAN.integer?.should be_false }
it { Float64::NAN.integer?.should be_false }
end

describe "fdiv" do
it { 1.0.fdiv(1).should eq 1.0 }
it { 1.0.fdiv(2).should eq 0.5 }
Expand Down
14 changes: 9 additions & 5 deletions spec/std/html_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ describe "HTML" do

context "numeric entities" do
it "decimal" do
HTML.unescape("3 &#43; 2 &#00061 5").should eq("3 + 2 = 5")
HTML.unescape("3 &#43; 2 &#00061 5 &#9;").should eq("3 + 2 = 5 \t")
end

it "hex" do
HTML.unescape("&#x000033; &#x2B; 2 &#x0003D &#x000035").should eq("3 + 2 = 5")
HTML.unescape("&#x000033; &#x2B; 2 &#x0003D &#x000035; &#x9;").should eq("3 + 2 = 5 \t")
end

it "early termination" do
Expand All @@ -48,6 +48,12 @@ describe "HTML" do
it "does not unescape characters above Char::MAX_CODEPOINT" do
HTML.unescape("limit &#x110000;").should eq("limit \uFFFD")
HTML.unescape("limit &#1114112;").should eq("limit \uFFFD")
HTML.unescape("limit &#x110000000000000;").should eq("limit \uFFFD")
end

it "ignores leading zeros" do
HTML.unescape("&#0000000065;").should eq("A")
HTML.unescape("&#x0000000065;").should eq("e")
end

it "space characters" do
Expand Down Expand Up @@ -101,9 +107,7 @@ describe "HTML" do
end

it "invalid utf-8" do
expect_raises(ArgumentError, "UTF-8 error") do
HTML.unescape("test \xff\xfe").should eq "test \xff\xfe"
end
HTML.unescape("test \xff\xfe").should eq "test \xff\xfe"
end
end
end
Loading

0 comments on commit 8d8de72

Please sign in to comment.