|
19 | 19 | end |
20 | 20 |
|
21 | 21 | context 'with explicit prefix' do |
22 | | - it 'derives the build code with prefix "1"' do |
23 | | - version = Fastlane::Models::AppVersion.new(1, 2, 3, 4) |
24 | | - formatter = described_class.new(prefix: '1') |
25 | | - build_code_string = formatter.build_code(version: version) |
26 | | - expect(build_code_string.to_s).to eq('101020304') |
27 | | - end |
28 | | - |
29 | 22 | it 'derives the build code with prefix "2"' do |
30 | 23 | version = Fastlane::Models::AppVersion.new(1, 2, 3, 4) |
31 | 24 | formatter = described_class.new(prefix: '2') |
32 | 25 | build_code_string = formatter.build_code(version: version) |
33 | 26 | expect(build_code_string.to_s).to eq('201020304') |
34 | 27 | end |
35 | 28 |
|
36 | | - it 'derives the build code with prefix "0"' do |
| 29 | + it 'derives the build code with prefix "0" and trims leading zeros' do |
37 | 30 | version = Fastlane::Models::AppVersion.new(12, 34, 56, 78) |
38 | 31 | formatter = described_class.new(prefix: '0') |
39 | 32 | build_code_string = formatter.build_code(version: version) |
|
81 | 74 | end |
82 | 75 | end |
83 | 76 |
|
| 77 | + describe 'configurable digit counts' do |
| 78 | + context 'with custom digit counts' do |
| 79 | + it 'uses 1 digit for each component' do |
| 80 | + version = Fastlane::Models::AppVersion.new(1, 2, 3, 4) |
| 81 | + formatter = described_class.new(prefix: '1', major_digits: 1, minor_digits: 1, patch_digits: 1, build_digits: 1) |
| 82 | + build_code_string = formatter.build_code(version: version) |
| 83 | + expect(build_code_string.to_s).to eq('11234') |
| 84 | + end |
| 85 | + |
| 86 | + it 'uses 2 digits for each component and pads with zeros' do |
| 87 | + # Test both large numbers and zero-padding in one test |
| 88 | + version_large = Fastlane::Models::AppVersion.new(12, 34, 56, 78) |
| 89 | + formatter = described_class.new(prefix: '2', major_digits: 2, minor_digits: 2, patch_digits: 2, build_digits: 2) |
| 90 | + expect(formatter.build_code(version: version_large).to_s).to eq('212345678') |
| 91 | + |
| 92 | + # Test zero-padding with smaller numbers |
| 93 | + version_small = Fastlane::Models::AppVersion.new(1, 2, 3, 4) |
| 94 | + expect(formatter.build_code(version: version_small).to_s).to eq('201020304') |
| 95 | + end |
| 96 | + |
| 97 | + it 'uses mixed digit counts' do |
| 98 | + version = Fastlane::Models::AppVersion.new(1, 23, 45, 678) |
| 99 | + formatter = described_class.new(prefix: '', major_digits: 1, minor_digits: 2, patch_digits: 2, build_digits: 3) |
| 100 | + build_code_string = formatter.build_code(version: version) |
| 101 | + # 1(1 digit) + 23(2 digits) + 45(2 digits) + 678(3 digits) = "12345678" |
| 102 | + expect(build_code_string.to_s).to eq('12345678') |
| 103 | + end |
| 104 | + |
| 105 | + it 'handles maximum values within digit limits' do |
| 106 | + version = Fastlane::Models::AppVersion.new(99, 99, 99, 99) |
| 107 | + formatter = described_class.new(prefix: '1', major_digits: 2, minor_digits: 2, patch_digits: 2, build_digits: 2) |
| 108 | + build_code_string = formatter.build_code(version: version) |
| 109 | + expect(build_code_string.to_s).to eq('199999999') |
| 110 | + end |
| 111 | + end |
| 112 | + |
| 113 | + context 'with empty prefix and custom digits' do |
| 114 | + it 'trims leading zeros correctly with 1-digit major' do |
| 115 | + version = Fastlane::Models::AppVersion.new(5, 12, 34, 56) |
| 116 | + formatter = described_class.new(prefix: '', major_digits: 1, minor_digits: 2, patch_digits: 2, build_digits: 2) |
| 117 | + build_code_string = formatter.build_code(version: version) |
| 118 | + expect(build_code_string.to_s).to eq('5123456') |
| 119 | + end |
| 120 | + |
| 121 | + it 'trims leading zeros correctly with larger major' do |
| 122 | + version = Fastlane::Models::AppVersion.new(7, 8, 9, 10) |
| 123 | + formatter = described_class.new(prefix: '', major_digits: 2, minor_digits: 2, patch_digits: 2, build_digits: 2) |
| 124 | + build_code_string = formatter.build_code(version: version) |
| 125 | + expect(build_code_string.to_s).to eq('7080910') |
| 126 | + end |
| 127 | + |
| 128 | + it 'handles edge case where all components start with zeros' do |
| 129 | + version = Fastlane::Models::AppVersion.new(0, 1, 2, 3) |
| 130 | + formatter = described_class.new(prefix: '', major_digits: 2, minor_digits: 2, patch_digits: 2, build_digits: 2) |
| 131 | + build_code_string = formatter.build_code(version: version) |
| 132 | + # ''(empty prefix) + '00'(2 digits) + '01'(2 digits) + '02'(2 digits) + '03'(2 digits) = "00010203", trimmed to "10203" |
| 133 | + expect(build_code_string.to_s).to eq('10203') |
| 134 | + end |
| 135 | + end |
| 136 | + |
| 137 | + context 'with backward compatibility (default 2 digits)' do |
| 138 | + it 'maintains existing behavior when no digit parameters specified' do |
| 139 | + version = Fastlane::Models::AppVersion.new(1, 2, 3, 4) |
| 140 | + formatter_old = described_class.new(prefix: '1') |
| 141 | + formatter_new = described_class.new(prefix: '1', major_digits: 2, minor_digits: 2, patch_digits: 2, build_digits: 2) |
| 142 | + |
| 143 | + expect(formatter_old.build_code(version: version)).to eq(formatter_new.build_code(version: version)) |
| 144 | + end |
| 145 | + end |
| 146 | + end |
| 147 | + |
| 148 | + describe 'digit count validation' do |
| 149 | + context 'with valid digit counts' do |
| 150 | + it 'accepts digit counts from 1 to 3 individually' do |
| 151 | + (1..3).each do |count| |
| 152 | + # Test each parameter individually with safe defaults for others |
| 153 | + expect { described_class.new(major_digits: count) }.not_to raise_error |
| 154 | + expect { described_class.new(minor_digits: count) }.not_to raise_error |
| 155 | + expect { described_class.new(patch_digits: count) }.not_to raise_error |
| 156 | + expect { described_class.new(build_digits: count) }.not_to raise_error |
| 157 | + end |
| 158 | + end |
| 159 | + |
| 160 | + it 'accepts mixed valid digit counts within 9 total digits' do |
| 161 | + # 1 + 2 + 2 + 3 = 8 digits <= 9 |
| 162 | + expect { described_class.new(major_digits: 1, minor_digits: 2, patch_digits: 2, build_digits: 3) }.not_to raise_error |
| 163 | + end |
| 164 | + end |
| 165 | + |
| 166 | + context 'with invalid digit counts' do |
| 167 | + it 'rejects digit counts outside valid range (1-3)' do |
| 168 | + expect { described_class.new(major_digits: 0) }.to raise_error(/Digit count must be between 1 and 3/) |
| 169 | + expect { described_class.new(minor_digits: -1) }.to raise_error(/Digit count must be between 1 and 3/) |
| 170 | + expect { described_class.new(patch_digits: 4) }.to raise_error(/Digit count must be between 1 and 3/) |
| 171 | + end |
| 172 | + |
| 173 | + it 'rejects non-integer digit counts' do |
| 174 | + expect { described_class.new(build_digits: '3') }.to raise_error(/Digit count must be an integer, got: String/) |
| 175 | + expect { described_class.new(major_digits: 2.5) }.to raise_error(/Digit count must be an integer, got: Float/) |
| 176 | + expect { described_class.new(minor_digits: 1.0) }.to raise_error(/Digit count must be an integer, got: Float/) |
| 177 | + expect { described_class.new(patch_digits: nil) }.to raise_error(/Digit count must be an integer, got: NilClass/) |
| 178 | + end |
| 179 | + |
| 180 | + it 'rejects configurations exceeding 9 total digits' do |
| 181 | + # 3 + 3 + 3 + 3 = 12 digits > 9 |
| 182 | + expect { described_class.new(major_digits: 3, minor_digits: 3, patch_digits: 3, build_digits: 3) }.to raise_error(/Total digit count \(12\) exceeds maximum allowed \(9\)/) |
| 183 | + end |
| 184 | + |
| 185 | + it 'accepts configurations within and at 9 total digit limit' do |
| 186 | + # 2 + 2 + 2 + 2 = 8 digits <= 9 (default config) |
| 187 | + expect { described_class.new }.not_to raise_error |
| 188 | + # 2 + 2 + 2 + 3 = 9 digits = 9 (at limit) |
| 189 | + expect { described_class.new(major_digits: 2, minor_digits: 2, patch_digits: 2, build_digits: 3) }.not_to raise_error |
| 190 | + end |
| 191 | + end |
| 192 | + end |
| 193 | + |
84 | 194 | describe 'prefix validation' do |
85 | 195 | context 'with valid prefixes' do |
86 | 196 | it 'accepts single digits 0-9' do |
|
99 | 209 | end |
100 | 210 |
|
101 | 211 | context 'with invalid prefixes' do |
102 | | - it 'rejects multi-character strings' do |
| 212 | + it 'rejects invalid prefix formats' do |
| 213 | + # Multi-character strings and out-of-range numbers |
103 | 214 | expect { described_class.new(prefix: '12') }.to raise_error(/Prefix must be a single digit or empty string/) |
104 | | - end |
105 | | - |
106 | | - it 'rejects non-numeric strings' do |
107 | | - expect { described_class.new(prefix: 'a') }.to raise_error(/Prefix must be an integer digit/) |
108 | | - end |
109 | | - |
110 | | - it 'rejects numbers outside 0-9 range' do |
111 | 215 | expect { described_class.new(prefix: '10') }.to raise_error(/Prefix must be a single digit or empty string/) |
112 | 216 | expect { described_class.new(prefix: '-1') }.to raise_error(/Prefix must be a single digit or empty string/) |
113 | | - end |
114 | 217 |
|
115 | | - it 'rejects symbols and special characters' do |
| 218 | + # Non-numeric characters |
| 219 | + expect { described_class.new(prefix: 'a') }.to raise_error(/Prefix must be an integer digit/) |
116 | 220 | expect { described_class.new(prefix: '@') }.to raise_error(/Prefix must be an integer digit/) |
117 | | - expect { described_class.new(prefix: '#') }.to raise_error(/Prefix must be an integer digit/) |
118 | 221 | end |
119 | 222 | end |
120 | 223 | end |
|
0 commit comments