diff --git a/lib/arkana/models/type.rb b/lib/arkana/models/type.rb index 7aab27d..f700616 100644 --- a/lib/arkana/models/type.rb +++ b/lib/arkana/models/type.rb @@ -11,6 +11,10 @@ def self.new(string_value:) when "true", "false" BOOLEAN when /^\d+$/ + # Handles cases like "0001" which should be interpreted as strings + return STRING if string_value.to_i.to_s != string_value + # Handle int overflow + return STRING if string_value.to_i > (2**31) - 1 INTEGER else STRING diff --git a/lib/arkana/templates/arkana_tests.swift.erb b/lib/arkana/templates/arkana_tests.swift.erb index 42ed22e..282216d 100644 --- a/lib/arkana/templates/arkana_tests.swift.erb +++ b/lib/arkana/templates/arkana_tests.swift.erb @@ -86,6 +86,46 @@ final class <%= @namespace %>Tests: XCTestCase { XCTAssertEqual(<%= @namespace %>.decode(encoded: encoded, cipher: salt), 42) } + func test_decodeIntValueWithLeadingZeroes_shouldDecodeAsString() { +<% int_with_leading_zeroes_key = "0001" %> +<% secret = generate_test_secret(key: int_with_leading_zeroes_key) %> + let encoded: [UInt8] = [ + <%= secret.encoded_value %> + + ] + XCTAssertEqual(<%= @namespace %>.decode(encoded: encoded, cipher: salt), "0001") + } + + func test_decodeMassiveIntValue_shouldDecodeAsString() { +<% int_with_massive_number_key = "92233720368547758079223372036854775807" %> +<% secret = generate_test_secret(key: int_with_massive_number_key) %> + let encoded: [UInt8] = [ + <%= secret.encoded_value %> + + ] + XCTAssertEqual(<%= @namespace %>.decode(encoded: encoded, cipher: salt), "92233720368547758079223372036854775807") + } + + func test_decodeNegativeIntValue_shouldDecodeAsString() { +<% negative_int_key = "-42" %> +<% secret = generate_test_secret(key: negative_int_key) %> + let encoded: [UInt8] = [ + <%= secret.encoded_value %> + + ] + XCTAssertEqual(<%= @namespace %>.decode(encoded: encoded, cipher: salt), "-42") + } + + func test_decodeFloatingPointValue_shouldDecodeAsString() { +<% float_key = "3.14" %> +<% secret = generate_test_secret(key: float_key) %> + let encoded: [UInt8] = [ + <%= secret.encoded_value %> + + ] + XCTAssertEqual(<%= @namespace %>.decode(encoded: encoded, cipher: salt), "3.14") + } + func test_encodeAndDecodeValueWithDollarSign_shouldDecode() { <% dollar_sign_key = "real_$lim_shady" %> <% secret = generate_test_secret(key: dollar_sign_key) %> diff --git a/spec/fixtures/.env.fruitloops b/spec/fixtures/.env.fruitloops index c2d3c70..50f0bf3 100644 --- a/spec/fixtures/.env.fruitloops +++ b/spec/fixtures/.env.fruitloops @@ -5,6 +5,14 @@ BoolAsBoolTrueKey = true BoolAsBoolFalseKey = false IntAsStringKey = "42" IntAsNumberKey = 42 +IntWithLeadingZeroesAsStringKey = "0001" +IntWithLeadingZeroesAsNumberKey = 0001 +MassiveIntAsStringKey = "92233720368547758079223372036854775807" +MassiveIntAsNumberKey = 92233720368547758079223372036854775807 +NegativeIntAsStringKey = "-42" +NegativeIntAsNumberKey = -42 +FloatAsStringKey = "3.14" +FloatAsNumberKey = 3.14 SecretWithDollarSignEscapedAndAndNoQuotesKey = real_\$lim_shady SecretWithDollarSignEscapedAndDoubleQuoteKey = "real_\$lim_shady" SecretWithDollarSignNotEscapedAndSingleQuoteKey = 'real_$lim_shady' diff --git a/spec/fixtures/swift-tests.yml b/spec/fixtures/swift-tests.yml index 5e8e00e..462ad57 100644 --- a/spec/fixtures/swift-tests.yml +++ b/spec/fixtures/swift-tests.yml @@ -12,6 +12,14 @@ global_secrets: - BoolAsBoolFalseKey - IntAsStringKey - IntAsNumberKey +- IntWithLeadingZeroesAsStringKey +- IntWithLeadingZeroesAsNumberKey +- MassiveIntAsStringKey +- MassiveIntAsNumberKey +- NegativeIntAsStringKey +- NegativeIntAsNumberKey +- FloatAsStringKey +- FloatAsNumberKey - SecretWithDollarSignEscapedAndAndNoQuotesKey - SecretWithDollarSignEscapedAndDoubleQuoteKey - SecretWithDollarSignNotEscapedAndSingleQuoteKey diff --git a/spec/models/type_spec.rb b/spec/models/type_spec.rb index e65fa73..3550bb9 100644 --- a/spec/models/type_spec.rb +++ b/spec/models/type_spec.rb @@ -25,5 +25,55 @@ expect(subject).to eq :string end end + + context "when passing something that looks like a number" do + context "when it contains leading zeros" do + subject { described_class.new(string_value: "0001") } + + it "returns :string" do + expect(subject).to eq :string + end + end + + context "when its string representation is the same as its integer representation" do + subject { described_class.new(string_value: "1234567890") } + + it "returns :integer" do + expect(subject).to eq :integer + end + end + + context "when its string representation is different from its integer representation" do + subject { described_class.new(string_value: "1234567890.0") } + + it "returns :string" do + expect(subject).to eq :string + end + end + + context "when it contains a decimal point" do + subject { described_class.new(string_value: "3.14") } + + it "returns :string" do + expect(subject).to eq :string + end + end + + context "when it contains a comma" do + subject { described_class.new(string_value: "1,000") } + + it "returns :string" do + expect(subject).to eq :string + end + end + + context "when it contains a massive number" do + subject { described_class.new(string_value: "123456789012345678901234567890") } + + it "returns :string" do + expect(subject).to eq :string + end + end + end end end