| 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); |
| 3 | |
| 4 | const TestEnum = enum { TestEnumValue }; |
| 5 | const tag_name = @tagName(TestEnum.TestEnumValue); |
| 6 | const ptr_tag_name: [*:0]const u8 = tag_name; |
| 7 | |
| 8 | test "@tagName() returns a string literal" { |
| 9 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 10 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 11 | |
| 12 | try std.testing.expect(*const [13:0]u8 == @TypeOf(tag_name)); |
| 13 | try std.testing.expect(std.mem.eql(u8, "TestEnumValue", tag_name)); |
| 14 | try std.testing.expect(std.mem.eql(u8, "TestEnumValue", ptr_tag_name[0..tag_name.len])); |
| 15 | } |
| 16 | |
| 17 | const TestError = error{TestErrorCode}; |
| 18 | const error_name = @errorName(TestError.TestErrorCode); |
| 19 | const ptr_error_name: [*:0]const u8 = error_name; |
| 20 | |
| 21 | test "@errorName() returns a string literal" { |
| 22 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 23 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 24 | |
| 25 | try std.testing.expect(*const [13:0]u8 == @TypeOf(error_name)); |
| 26 | try std.testing.expect(std.mem.eql(u8, "TestErrorCode", error_name)); |
| 27 | try std.testing.expect(std.mem.eql(u8, "TestErrorCode", ptr_error_name[0..error_name.len])); |
| 28 | } |
| 29 | |
| 30 | const TestType = struct {}; |
| 31 | const type_name = @typeName(TestType); |
| 32 | const ptr_type_name: [*:0]const u8 = type_name; |
| 33 | |
| 34 | test "@typeName() returns a string literal" { |
| 35 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 36 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 37 | |
| 38 | try std.testing.expect(*const [type_name.len:0]u8 == @TypeOf(type_name)); |
| 39 | try std.testing.expect(std.mem.eql(u8, "behavior.string_literals.TestType", type_name)); |
| 40 | try std.testing.expect(std.mem.eql(u8, "behavior.string_literals.TestType", ptr_type_name[0..type_name.len])); |
| 41 | } |
| 42 | |
| 43 | const actual_contents = @embedFile("file_to_embed.txt"); |
| 44 | const ptr_actual_contents: [*:0]const u8 = actual_contents; |
| 45 | const expected_contents = "hello zig\n"; |
| 46 | |
| 47 | test "@embedFile() returns a string literal" { |
| 48 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 49 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 50 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 51 | |
| 52 | try std.testing.expect(*const [expected_contents.len:0]u8 == @TypeOf(actual_contents)); |
| 53 | try std.testing.expect(std.mem.eql(u8, expected_contents, actual_contents)); |
| 54 | try std.testing.expect(std.mem.eql(u8, expected_contents, actual_contents)); |
| 55 | try std.testing.expect(std.mem.eql(u8, expected_contents, ptr_actual_contents[0..actual_contents.len])); |
| 56 | } |
| 57 | |
| 58 | fn testFnForSrc() std.builtin.SourceLocation { |
| 59 | return @src(); |
| 60 | } |
| 61 | |
| 62 | test "@src() returns a struct containing 0-terminated string slices" { |
| 63 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 64 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 65 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 66 | |
| 67 | const src = testFnForSrc(); |
| 68 | try std.testing.expect([:0]const u8 == @TypeOf(src.file)); |
| 69 | try std.testing.expect(std.mem.endsWith(u8, src.file, "string_literals.zig")); |
| 70 | try std.testing.expect([:0]const u8 == @TypeOf(src.fn_name)); |
| 71 | try std.testing.expect(std.mem.endsWith(u8, src.fn_name, "testFnForSrc")); |
| 72 | |
| 73 | const ptr_src_file: [*:0]const u8 = src.file; |
| 74 | _ = ptr_src_file; // unused |
| 75 | |
| 76 | const ptr_src_fn_name: [*:0]const u8 = src.fn_name; |
| 77 | _ = ptr_src_fn_name; // unused |
| 78 | } |
| 79 | |
| 80 | test "string literal pointer sentinel" { |
| 81 | const string_literal = "something"; |
| 82 | |
| 83 | try std.testing.expect(@TypeOf(string_literal.ptr) == [*:0]const u8); |
| 84 | } |
| 85 | |
| 86 | test "sentinel slice of string literal" { |
| 87 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 88 | |
| 89 | const string = "Hello!\x00World!"; |
| 90 | try std.testing.expect(@TypeOf(string) == *const [13:0]u8); |
| 91 | |
| 92 | const slice_without_sentinel: []const u8 = string[0..6]; |
| 93 | try std.testing.expect(@TypeOf(slice_without_sentinel) == []const u8); |
| 94 | |
| 95 | const slice_with_sentinel: [:0]const u8 = string[0..6 :0]; |
| 96 | try std.testing.expect(@TypeOf(slice_with_sentinel) == [:0]const u8); |
| 97 | } |
| 98 | |
| 99 | test "Peer type resolution with string literals and unknown length u8 pointers" { |
| 100 | try std.testing.expect(@TypeOf("", "a", @as([*:0]const u8, "")) == [*:0]const u8); |
| 101 | try std.testing.expect(@TypeOf(@as([*:0]const u8, "baz"), "foo", "bar") == [*:0]const u8); |
| 102 | } |
| 103 | |
| 104 | test "including the sentinel when dereferencing a string literal" { |
| 105 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 106 | var var_str = "abc"; |
| 107 | const var_derefed = var_str[0 .. var_str.len + 1].*; |
| 108 | |
| 109 | const const_str = "abc"; |
| 110 | const const_derefed = const_str[0 .. const_str.len + 1].*; |
| 111 | |
| 112 | try std.testing.expectEqualSlices(u8, &var_derefed, &const_derefed); |
| 113 | try std.testing.expectEqual(0, const_derefed[3]); |
| 114 | } |