This is an automated email from the ASF dual-hosted git repository.

borinquenkid pushed a commit to branch chore/8.1.x-datamapping-core-timestamp
in repository https://gitbox.apache.org/repos/asf/grails-core.git

commit a4218ff51355e605c1f4e64ec23e155a5dc024b2
Author: Walter Duque de Estrada <[email protected]>
AuthorDate: Tue Aug 18 10:59:05 2026 -0500

    Add spec coverage for AggregateTimestampProvider
    
    AggregateTimestampProvider was the only class in the timestamp package
    without test coverage. Also replaces iterator().next() with getFirst()
    per SequencedCollection (JDK 21).
    
    Co-Authored-By: Claude Sonnet 5 <[email protected]>
---
 .../gorm/timestamp/AggregateTimestampProvider.java |   2 +-
 .../gorm/timestamp/DefaultTimestampProvider.java   |   2 -
 .../AggregateTimestampProviderSpec.groovy          | 126 +++++++++++++++++++++
 3 files changed, 127 insertions(+), 3 deletions(-)

diff --git 
a/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/timestamp/AggregateTimestampProvider.java
 
b/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/timestamp/AggregateTimestampProvider.java
index 7fb0f360f3..d8e0855056 100644
--- 
a/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/timestamp/AggregateTimestampProvider.java
+++ 
b/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/timestamp/AggregateTimestampProvider.java
@@ -49,7 +49,7 @@ public class AggregateTimestampProvider implements 
TimestampProvider {
                 }
             }
         } else {
-            return createTimestamp(timestampProviders.iterator().next(), 
dateTimeClass);
+            return createTimestamp(timestampProviders.getFirst(), 
dateTimeClass);
         }
         throw new IllegalArgumentException("dateTimeClass given as parameter 
isn't supported by any TimestampProvider. You should call supportsCreating 
first.");
     }
diff --git 
a/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/timestamp/DefaultTimestampProvider.java
 
b/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/timestamp/DefaultTimestampProvider.java
index 471345b4c0..5d44a8dc08 100644
--- 
a/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/timestamp/DefaultTimestampProvider.java
+++ 
b/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/timestamp/DefaultTimestampProvider.java
@@ -26,9 +26,7 @@ import org.springframework.util.ClassUtils;
 
 /**
  * Default implementation of TimestampProvider
- *
  * supports creating timestamps for any class that supports a constructor that 
accepts a Long or long value.
- *
  * "currentTimeMillis" can be overrided in subclasses (useful for testing 
purposes)
  *
  */
diff --git 
a/grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/timestamp/AggregateTimestampProviderSpec.groovy
 
b/grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/timestamp/AggregateTimestampProviderSpec.groovy
new file mode 100644
index 0000000000..d29cbff92c
--- /dev/null
+++ 
b/grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/timestamp/AggregateTimestampProviderSpec.groovy
@@ -0,0 +1,126 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.grails.datastore.gorm.timestamp
+
+import spock.lang.Specification
+
+class AggregateTimestampProviderSpec extends Specification {
+
+    AggregateTimestampProvider aggregateTimestampProvider = new 
AggregateTimestampProvider()
+
+    void "getTimestampProviders defaults to an empty list"() {
+        expect:
+        aggregateTimestampProvider.timestampProviders == []
+    }
+
+    void "setTimestampProviders stores the given providers"() {
+        given:
+        TimestampProvider dateProvider = Stub(TimestampProvider)
+        TimestampProvider stringProvider = Stub(TimestampProvider)
+
+        when:
+        aggregateTimestampProvider.timestampProviders = [dateProvider, 
stringProvider]
+
+        then:
+        aggregateTimestampProvider.timestampProviders == [dateProvider, 
stringProvider]
+    }
+
+    void "supportsCreating returns true when any delegate provider supports 
the class"() {
+        given:
+        TimestampProvider dateProvider = Stub(TimestampProvider) {
+            supportsCreating(Date) >> false
+        }
+        TimestampProvider stringProvider = Stub(TimestampProvider) {
+            supportsCreating(Date) >> true
+        }
+        aggregateTimestampProvider.timestampProviders = [dateProvider, 
stringProvider]
+
+        expect:
+        aggregateTimestampProvider.supportsCreating(Date)
+    }
+
+    void "supportsCreating returns false when no delegate provider supports 
the class"() {
+        given:
+        TimestampProvider dateProvider = Stub(TimestampProvider) {
+            supportsCreating(_) >> false
+        }
+        aggregateTimestampProvider.timestampProviders = [dateProvider]
+
+        expect:
+        !aggregateTimestampProvider.supportsCreating(Date)
+    }
+
+    void "supportsCreating returns false when there are no delegate 
providers"() {
+        expect:
+        !aggregateTimestampProvider.supportsCreating(Date)
+    }
+
+    void "createTimestamp delegates directly to the single registered 
provider"() {
+        given:
+        Date timestamp = new Date()
+        TimestampProvider onlyProvider = Stub(TimestampProvider) {
+            createTimestamp(Date) >> timestamp
+        }
+        aggregateTimestampProvider.timestampProviders = [onlyProvider]
+
+        expect:
+        aggregateTimestampProvider.createTimestamp(Date) == timestamp
+    }
+
+    void "createTimestamp with multiple providers delegates to the first 
provider that supports the class"() {
+        given:
+        Date timestamp = new Date()
+        TimestampProvider unsupportingProvider = Stub(TimestampProvider) {
+            supportsCreating(Date) >> false
+        }
+        TimestampProvider supportingProvider = Stub(TimestampProvider) {
+            supportsCreating(Date) >> true
+            createTimestamp(Date) >> timestamp
+        }
+        aggregateTimestampProvider.timestampProviders = [unsupportingProvider, 
supportingProvider]
+
+        expect:
+        aggregateTimestampProvider.createTimestamp(Date) == timestamp
+    }
+
+    void "createTimestamp with multiple providers throws when none support the 
class"() {
+        given:
+        TimestampProvider firstProvider = Stub(TimestampProvider) {
+            supportsCreating(Date) >> false
+        }
+        TimestampProvider secondProvider = Stub(TimestampProvider) {
+            supportsCreating(Date) >> false
+        }
+        aggregateTimestampProvider.timestampProviders = [firstProvider, 
secondProvider]
+
+        when:
+        aggregateTimestampProvider.createTimestamp(Date)
+
+        then:
+        thrown(IllegalArgumentException)
+    }
+
+    void "createTimestamp with no registered providers throws"() {
+        when:
+        aggregateTimestampProvider.createTimestamp(Date)
+
+        then:
+        thrown(NoSuchElementException)
+    }
+}

Reply via email to