|
198 | 198 | end |
199 | 199 | end |
200 | 200 |
|
| 201 | + describe 'current_value= setter' do |
| 202 | + it 'sets value on simple property and triggers watchers' do |
| 203 | + watch.count = 5 |
| 204 | + binding = watch.count.bind |
| 205 | + |
| 206 | + values = [] |
| 207 | + binding.watch { |old, new| values << [old, new] } |
| 208 | + |
| 209 | + binding.current_value = 10 |
| 210 | + expect(values).to eq([[5, 10]]) |
| 211 | + expect(watch.count).to eq(10) |
| 212 | + end |
| 213 | + |
| 214 | + it 'sets value on hash key and triggers watchers' do |
| 215 | + watch.data = { name: 'Alice', age: 30 } |
| 216 | + binding = watch.data[:age].bind |
| 217 | + |
| 218 | + values = [] |
| 219 | + binding.watch { |old, new| values << [old, new] } |
| 220 | + |
| 221 | + binding.current_value = 31 |
| 222 | + expect(values).to eq([[30, 31]]) |
| 223 | + expect(watch.data[:age]).to eq(31) |
| 224 | + end |
| 225 | + |
| 226 | + it 'sets value on array index and triggers watchers' do |
| 227 | + watch.list = [1, 2, 3] |
| 228 | + binding = watch.list[1].bind |
| 229 | + |
| 230 | + values = [] |
| 231 | + binding.watch { |old, new| values << [old, new] } |
| 232 | + |
| 233 | + binding.current_value = 99 |
| 234 | + expect(values).to eq([[2, 99]]) |
| 235 | + expect(watch.list).to eq([1, 99, 3]) |
| 236 | + end |
| 237 | + |
| 238 | + it 'sets value on deeply nested hash path' do |
| 239 | + watch.data = { users: [{ name: 'Alice', age: 30 }] } |
| 240 | + binding = watch.data[:users][0][:age].bind |
| 241 | + |
| 242 | + values = [] |
| 243 | + binding.watch { |old, new| values << [old, new] } |
| 244 | + |
| 245 | + binding.current_value = 35 |
| 246 | + expect(values).to eq([[30, 35]]) |
| 247 | + expect(watch.data[:users][0][:age]).to eq(35) |
| 248 | + end |
| 249 | + |
| 250 | + it 'sets value on deeply nested array path' do |
| 251 | + watch.matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] |
| 252 | + binding = watch.matrix[1][2].bind |
| 253 | + |
| 254 | + values = [] |
| 255 | + binding.watch { |old, new| values << [old, new] } |
| 256 | + |
| 257 | + binding.current_value = 99 |
| 258 | + expect(values).to eq([[6, 99]]) |
| 259 | + expect(watch.matrix[1][2]).to eq(99) |
| 260 | + end |
| 261 | + |
| 262 | + it 'sets value on mixed hash/array path' do |
| 263 | + watch.data = { items: [{ id: 1, count: 5 }, { id: 2, count: 10 }] } |
| 264 | + binding = watch.data[:items][1][:count].bind |
| 265 | + |
| 266 | + values = [] |
| 267 | + binding.watch { |old, new| values << [old, new] } |
| 268 | + |
| 269 | + binding.current_value = 20 |
| 270 | + expect(values).to eq([[10, 20]]) |
| 271 | + expect(watch.data[:items][1][:count]).to eq(20) |
| 272 | + end |
| 273 | + |
| 274 | + it 'triggers multiple watchers when setting value' do |
| 275 | + watch.value = 1 |
| 276 | + binding = watch.value.bind |
| 277 | + |
| 278 | + values1 = [] |
| 279 | + values2 = [] |
| 280 | + binding.watch { |old, new| values1 << [old, new] } |
| 281 | + binding.watch { |old, new| values2 << [old, new] } |
| 282 | + |
| 283 | + binding.current_value = 5 |
| 284 | + expect(values1).to eq([[1, 5]]) |
| 285 | + expect(values2).to eq([[1, 5]]) |
| 286 | + end |
| 287 | + |
| 288 | + it 'does not trigger when setting to same value' do |
| 289 | + watch.value = 42 |
| 290 | + binding = watch.value.bind |
| 291 | + |
| 292 | + triggered = false |
| 293 | + binding.watch { |_old, _new| triggered = true } |
| 294 | + |
| 295 | + binding.current_value = 42 |
| 296 | + expect(triggered).to be false |
| 297 | + end |
| 298 | + |
| 299 | + it 'handles setting nil value' do |
| 300 | + watch.value = 'something' |
| 301 | + binding = watch.value.bind |
| 302 | + |
| 303 | + values = [] |
| 304 | + binding.watch { |old, new| values << [old, new] } |
| 305 | + |
| 306 | + binding.current_value = nil |
| 307 | + expect(values).to eq([['something', nil]]) |
| 308 | + expect(watch.value).to be_nil |
| 309 | + end |
| 310 | + |
| 311 | + it 'handles setting value from nil' do |
| 312 | + watch.value = nil |
| 313 | + binding = watch.value.bind |
| 314 | + |
| 315 | + values = [] |
| 316 | + binding.watch { |old, new| values << [old, new] } |
| 317 | + |
| 318 | + binding.current_value = 'something' |
| 319 | + expect(values).to eq([[nil, 'something']]) |
| 320 | + expect(watch.value).to eq('something') |
| 321 | + end |
| 322 | + |
| 323 | + it 'sets complex objects as values' do |
| 324 | + watch.data = { config: { timeout: 30 } } |
| 325 | + binding = watch.data[:config].bind |
| 326 | + |
| 327 | + values = [] |
| 328 | + binding.watch { |old, new| values << [old, new] } |
| 329 | + |
| 330 | + new_config = { timeout: 60, retries: 3 } |
| 331 | + binding.current_value = new_config |
| 332 | + expect(values).to eq([[{ timeout: 30 }, new_config]]) |
| 333 | + expect(watch.data[:config]).to eq(new_config) |
| 334 | + end |
| 335 | + |
| 336 | + it 'works with array element after mutations' do |
| 337 | + watch.items = [10, 20, 30] |
| 338 | + binding = watch.items[0].bind |
| 339 | + |
| 340 | + values = [] |
| 341 | + binding.watch { |old, new| values << [old, new] } |
| 342 | + |
| 343 | + binding.current_value = 100 |
| 344 | + expect(values).to eq([[10, 100]]) |
| 345 | + expect(watch.items).to eq([100, 20, 30]) |
| 346 | + |
| 347 | + watch.items.push(40) |
| 348 | + binding.current_value = 200 |
| 349 | + expect(values).to eq([[10, 100], [100, 200]]) |
| 350 | + expect(watch.items).to eq([200, 20, 30, 40]) |
| 351 | + end |
| 352 | + |
| 353 | + it 'returns the new value when setting' do |
| 354 | + watch.value = 1 |
| 355 | + binding = watch.value.bind |
| 356 | + |
| 357 | + result = binding.current_value = 42 |
| 358 | + expect(result).to eq(42) |
| 359 | + end |
| 360 | + end |
| 361 | + |
201 | 362 | describe 'integration with Ruby collections' do |
202 | 363 | it 'works as array index' do |
203 | 364 | watch.index = 2 |
|
0 commit comments