Skip to content

Commit

Permalink
modify fixture test
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander Filimonov committed Apr 19, 2024
1 parent 5a5cd06 commit 37749b5
Show file tree
Hide file tree
Showing 10 changed files with 251 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ public final class SynthesizedResourceInterfaceProjectMapper: ProjectMapping { /

/// Map and generate resource interfaces for a given `Target` and `Project`
private func mapTarget(_ target: Target, project: Project) throws -> (Target, [SideEffectDescriptor]) {
guard !target.resources.resources.isEmpty, target.supportsSources else { return (target, []) }
let resourcesForSynthesizersPaths = target.resources.resources
.map(\.path) + target.coreDataModels.map(\.path)
guard !resourcesForSynthesizersPaths.isEmpty, target.supportsSources else { return (target, []) }

var target = target

Expand Down
11 changes: 11 additions & 0 deletions Tests/TuistGeneratorAcceptanceTests/GenerateAcceptanceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,17 @@ final class GenerateAcceptanceTestiOSAppWithCoreData: TuistAcceptanceTestCase {
resource: resource
)
}
XCTAssertTrue(
FileHandler.shared.exists(
fixturePath.appending(
components: [
"Derived",
"Sources",
"TuistCoreData+App.swift",
]
)
)
)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="17709" systemVersion="20C69" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="UnversionedUser" representedClassName="UnversionedUser" syncable="YES" codeGenerationType="class">
<entity name="UnversionedUser" representedClassName="UnversionedUser" syncable="YES">
<attribute name="identifier" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="name" optional="YES" attributeType="String"/>
</entity>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="16119" systemVersion="19E287" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="User" representedClassName="User" syncable="YES" codeGenerationType="class">
<entity name="User" representedClassName="User" syncable="YES">
<attribute name="identifier" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="name" optional="YES" attributeType="String"/>
</entity>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="15508" systemVersion="18G87" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="User" representedClassName="User" syncable="YES" codeGenerationType="class">
<entity name="User" representedClassName="User" syncable="YES">
<attribute name="identifier" optional="YES" attributeType="String"/>
<attribute name="name" optional="YES" attributeType="String"/>
</entity>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="16119" systemVersion="19E287" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="DetectedUser" representedClassName="DetectedUser" syncable="YES" codeGenerationType="class">
<entity name="DetectedUser" representedClassName="DetectedUser" syncable="YES">
<attribute name="identifier" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="name" optional="YES" attributeType="String"/>
</entity>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="17709" systemVersion="20C69" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="DetectedUser" representedClassName="DetectedUser" syncable="YES" codeGenerationType="class">
<entity name="DetectedUser" representedClassName="DetectedUser" syncable="YES">
<attribute name="identifier" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="name" optional="YES" attributeType="String"/>
</entity>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="15508" systemVersion="18G87" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="DetectedUser" representedClassName="DetectedUser" syncable="YES" codeGenerationType="class">
<entity name="DetectedUser" representedClassName="DetectedUser" syncable="YES">
<attribute name="identifier" optional="YES" attributeType="String"/>
<attribute name="name" optional="YES" attributeType="String"/>
</entity>
Expand Down
3 changes: 2 additions & 1 deletion fixtures/ios_app_with_coredata/Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ let project = Project(
.coreDataModel("CoreData/Unversioned.xcdatamodeld"),
]
),
]
],
resourceSynthesizers: .default + [.coreData()]
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
// swiftlint:disable all
// swiftlint:disable superfluous_disable_command implicit_return
// swiftlint:disable sorted_imports
import CoreData
import Foundation
{% for import in param.extraImports %}
import {{ import }}
{% empty %}
{# If extraImports is a single String instead of an array, `for` considers it empty but we still have to check if there's a single String value #}
{%- if param.extraImports %}
import {{ param.extraImports }}
{% endif %}
{% endfor %}

// swiftlint:disable attributes file_length vertical_whitespace_closing_braces
// swiftlint:disable identifier_name line_length type_body_length
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}

{% for model in models %}
{% for name, entity in model.entities %}
{% set superclass %}{{ model.entities[entity.superEntity].className|default:"NSManagedObject" }}{% endset %}
{% set entityClassName %}{{ entity.className|default:"NSManagedObject" }}{% endset %}
{% set hasChildren %}{% for aName,anEntity in model.entities where anEntity.superEntity == name %}1{% endfor %}{% endset %}
// MARK: - {{ entity.name }}

{% if not entity.shouldGenerateCode %}
// Note: '{{ entity.name }}' has codegen enabled for Xcode, skipping code generation.

{% elif entityClassName|contains:"." %}
// Warning: '{{ entityClassName }}' cannot be a valid type name, skipping code generation.

{% else %}
{% if param.generateObjcName %}
@objc({{ entityClassName }})
{% endif %}
{{ accessModifier }} {%+ if not entity.isAbstract and not hasChildren %}final {%+ endif %}class {{ entityClassName }}: {{ superclass }} {
{% set override %}{% if superclass != "NSManagedObject" %}override {%+ endif %}{% endset %}
{{ override }}{{ accessModifier }} class var entityName: String {
return "{{ entity.name }}"
}

{{ override }}{{ accessModifier }} class func entity(in managedObjectContext: NSManagedObjectContext) -> NSEntityDescription? {
return NSEntityDescription.entity(forEntityName: entityName, in: managedObjectContext)
}

@available(*, deprecated, renamed: "makeFetchRequest", message: "To avoid collisions with the less concrete method in `NSManagedObject`, please use `makeFetchRequest()` instead.")
@nonobjc {{ accessModifier }} class func fetchRequest() -> NSFetchRequest<{{ entityClassName }}> {
return NSFetchRequest<{{ entityClassName }}>(entityName: entityName)
}

@nonobjc {{ accessModifier }} class func makeFetchRequest() -> NSFetchRequest<{{ entityClassName }}> {
return NSFetchRequest<{{ entityClassName }}>(entityName: entityName)
}

// swiftlint:disable discouraged_optional_boolean discouraged_optional_collection implicit_getter
{% for attribute in entity.attributes %}
{% if attribute.userInfo.RawType %}
{% set rawType attribute.userInfo.RawType %}
{% set unwrapOptional attribute.userInfo.unwrapOptional %}
{{ accessModifier }} var {{ attribute.name }}: {{ rawType }}{% if not unwrapOptional %}?{% endif %} {
get {
let key = "{{ attribute.name }}"
willAccessValue(forKey: key)
defer { didAccessValue(forKey: key) }

guard let value = primitiveValue(forKey: key) as? {{ rawType }}.RawValue else {
{%+ if unwrapOptional %}fatalError("Could not convert value for key '\(key)' to type '{{ rawType }}.RawValue'"){% else %}return nil{% endif +%}
}
{% if attribute.userInfo.nonOptionalInit or not unwrapOptional %}
return {{ rawType }}(rawValue: value)
{% else %}
guard let result = {{ rawType }}(rawValue: value) else {
fatalError("Could not convert value for key '\(key)' to type '{{ rawType }}'")
}
return result
{% endif %}
}
{% if not attribute.isDerived %}
set {
let key = "{{ attribute.name }}"
willChangeValue(forKey: key)
defer { didChangeValue(forKey: key) }

setPrimitiveValue(newValue{% if not unwrapOptional %}?{% endif %}.rawValue, forKey: key)
}
{% endif %}
}
{% elif attribute.usesScalarValueType and attribute.isOptional %}
{{ accessModifier }} var {{ attribute.name }}: {{ attribute.typeName }}? {
get {
let key = "{{ attribute.name }}"
willAccessValue(forKey: key)
defer { didAccessValue(forKey: key) }

return primitiveValue(forKey: key) as? {{ attribute.typeName }}
}
{% if not attribute.isDerived %}
set {
let key = "{{ attribute.name }}"
willChangeValue(forKey: key)
defer { didChangeValue(forKey: key) }

setPrimitiveValue(newValue, forKey: key)
}
{% endif %}
}
{% elif attribute.isDerived %}
{{ accessModifier }} var {{ attribute.name }}: {{ attribute.typeName }}{% if attribute.isOptional %}?{% endif %} {
let key = "{{ attribute.name }}"
willAccessValue(forKey: key)
defer { didAccessValue(forKey: key) }

{% if attribute.isOptional %}
return primitiveValue(forKey: key) as? {{ attribute.typeName }}
{% else %}
guard let value = primitiveValue(forKey: key) as? {{ attribute.typeName }} else {
fatalError("Could not convert value for key '\(key)' to type '{{ attribute.typeName }}'")
}
return value
{% endif %}
}
{% else %}
@NSManaged {{ accessModifier }} var {{ attribute.name }}: {{ attribute.typeName }}{% if attribute.isOptional %}?{% endif +%}
{% endif %}
{% endfor %}
{% for relationship in entity.relationships %}
{% if relationship.isToMany %}
@NSManaged {{ accessModifier }} var {{ relationship.name }}: {%+ if relationship.isOrdered %}NSOrderedSet{% else %}Set<{{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}>{% endif %}{% if relationship.isOptional %}?{% endif +%}
{% else %}
@NSManaged {{ accessModifier }} var {{ relationship.name }}: {{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}{% if relationship.isOptional %}?{% endif +%}
{% endif %}
{% endfor %}
{% for fetchedProperty in entity.fetchedProperties %}
@NSManaged {{ accessModifier }} var {{ fetchedProperty.name }}: [{{ model.entities[fetchedProperty.fetchRequest.entity].className|default:"NSManagedObject" }}]
{% endfor %}
// swiftlint:enable discouraged_optional_boolean discouraged_optional_collection implicit_getter
}

{% for relationship in entity.relationships where relationship.isToMany %}
{% set destinationEntityClassName %}{{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}{% endset %}
{% set collectionClassName %}{% if relationship.isOrdered %}NSOrderedSet{% else %}Set<{{ destinationEntityClassName }}>{% endif %}{% endset %}
{% set relationshipName %}{{ relationship.name | upperFirstLetter }}{% endset %}
// MARK: Relationship {{ relationshipName }}

extension {{ entityClassName }} {
{% if relationship.isOrdered %}
@objc(insertObject:in{{ relationshipName }}AtIndex:)
@NSManaged public func insertInto{{ relationshipName }}(_ value: {{ destinationEntityClassName }}, at idx: Int)

@objc(removeObjectFrom{{ relationshipName }}AtIndex:)
@NSManaged public func removeFrom{{ relationshipName }}(at idx: Int)

@objc(insert{{ relationshipName }}:atIndexes:)
@NSManaged public func insertInto{{ relationshipName }}(_ values: [{{ destinationEntityClassName }}], at indexes: NSIndexSet)

@objc(remove{{ relationshipName }}AtIndexes:)
@NSManaged public func removeFrom{{ relationshipName }}(at indexes: NSIndexSet)

@objc(replaceObjectIn{{ relationshipName }}AtIndex:withObject:)
@NSManaged public func replace{{ relationshipName }}(at idx: Int, with value: {{ destinationEntityClassName }})

@objc(replace{{ relationshipName }}AtIndexes:with{{ relationshipName }}:)
@NSManaged public func replace{{ relationshipName }}(at indexes: NSIndexSet, with values: [{{ destinationEntityClassName }}])

{% endif %}
@objc(add{{ relationshipName }}Object:)
@NSManaged public func addTo{{ relationshipName }}(_ value: {{ destinationEntityClassName }})

@objc(remove{{ relationshipName }}Object:)
@NSManaged public func removeFrom{{ relationshipName }}(_ value: {{ destinationEntityClassName }})

@objc(add{{ relationshipName }}:)
@NSManaged public func addTo{{ relationshipName }}(_ values: {{ collectionClassName }})

@objc(remove{{ relationshipName }}:)
@NSManaged public func removeFrom{{ relationshipName }}(_ values: {{ collectionClassName }})
}

{% endfor %}
{% if model.fetchRequests[entity.name].count > 0 %}
// MARK: Fetch Requests

extension {{ entityClassName }} {
{% for fetchRequest in model.fetchRequests[entity.name] %}
{% set resultTypeName -%}
{%- if fetchRequest.resultType == "Object" -%}
{{ entityClassName }}
{%- elif fetchRequest.resultType == "Object ID" -%}
NSManagedObjectID
{%- elif fetchRequest.resultType == "Dictionary" -%}
[String: Any]
{%- endif -%}
{%- endset %}
class func fetch{{ fetchRequest.name | upperFirstLetter }}(managedObjectContext: NSManagedObjectContext
{%- for variableName, variableType in fetchRequest.substitutionVariables -%}
, {{ variableName | lowerFirstWord }}: {{ variableType }}
{%- endfor -%}
) throws -> [{{ resultTypeName }}] {
guard let persistentStoreCoordinator = managedObjectContext.persistentStoreCoordinator else {
fatalError("Managed object context has no persistent store coordinator for getting fetch request templates")
}
let model = persistentStoreCoordinator.managedObjectModel
let substitutionVariables: [String: Any] = [
{% for variableName, variableType in fetchRequest.substitutionVariables %}
"{{ variableName }}": {{ variableName | lowerFirstWord }}{{ "," if not forloop.last }}
{% empty %}
:
{% endfor %}
]

guard let fetchRequest = model.fetchRequestFromTemplate(withName: "{{ fetchRequest.name }}", substitutionVariables: substitutionVariables) else {
fatalError("No fetch request template named '{{ fetchRequest.name }}' found.")
}

guard let result = try managedObjectContext.fetch(fetchRequest) as? [{{ resultTypeName }}] else {
fatalError("Unable to cast fetch result to correct result type.")
}

return result
}

{% endfor %}
}

{% endif %}
{% endif %}
{% endfor %}
{% endfor %}
// swiftlint:enable identifier_name line_length type_body_length

0 comments on commit 37749b5

Please sign in to comment.