1
1
mirror of https://github.com/exyte/Macaw.git synced 2024-09-11 13:15:35 +03:00

Merge pull request #460 from cHaLkdusT/master

Improving API structure for readability
This commit is contained in:
Yuri Strot 2018-08-23 07:37:27 +00:00 committed by GitHub
commit ba6512ea89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 118 additions and 18 deletions

View File

@ -480,6 +480,8 @@
5BFEF5D120B80A83008DAC11 /* ColorMatrixEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BFEF5CD20B80A83008DAC11 /* ColorMatrixEffect.swift */; };
5BFEF5D620BC1C1F008DAC11 /* paths-data-18-f-manual.svg in Resources */ = {isa = PBXBuildFile; fileRef = 5BFEF5D420BC1C1E008DAC11 /* paths-data-18-f-manual.svg */; };
5BFEF5D720BC1C1F008DAC11 /* paths-data-18-f-manual.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BFEF5D520BC1C1F008DAC11 /* paths-data-18-f-manual.reference */; };
6A616BFA2129560A006A07FA /* MacawTests.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 6A616BF92129560A006A07FA /* MacawTests.bundle */; };
6A616BFC212964E8006A07FA /* SVGParserTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A616BFB212964E8006A07FA /* SVGParserTest.swift */; };
A718CD441F45C28200966E06 /* Common_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = A718CD431F45C28200966E06 /* Common_iOS.swift */; };
A718CD471F45C28700966E06 /* Graphics_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = A718CD451F45C28700966E06 /* Graphics_iOS.swift */; };
A718CD481F45C28700966E06 /* MView_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = A718CD461F45C28700966E06 /* MView_iOS.swift */; };
@ -877,6 +879,8 @@
5BFEF5CD20B80A83008DAC11 /* ColorMatrixEffect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorMatrixEffect.swift; sourceTree = "<group>"; };
5BFEF5D420BC1C1E008DAC11 /* paths-data-18-f-manual.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "paths-data-18-f-manual.svg"; sourceTree = "<group>"; };
5BFEF5D520BC1C1F008DAC11 /* paths-data-18-f-manual.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "paths-data-18-f-manual.reference"; sourceTree = "<group>"; };
6A616BF92129560A006A07FA /* MacawTests.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = MacawTests.bundle; sourceTree = "<group>"; };
6A616BFB212964E8006A07FA /* SVGParserTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SVGParserTest.swift; sourceTree = "<group>"; };
A718CD431F45C28200966E06 /* Common_iOS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Common_iOS.swift; path = Source/platform/iOS/Common_iOS.swift; sourceTree = SOURCE_ROOT; };
A718CD451F45C28700966E06 /* Graphics_iOS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Graphics_iOS.swift; path = Source/platform/iOS/Graphics_iOS.swift; sourceTree = SOURCE_ROOT; };
A718CD461F45C28700966E06 /* MView_iOS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MView_iOS.swift; path = Source/platform/iOS/MView_iOS.swift; sourceTree = SOURCE_ROOT; };
@ -1289,6 +1293,7 @@
57FCD27A1D76EA4600CC0FB6 /* MacawTests */ = {
isa = PBXGroup;
children = (
6A616BF92129560A006A07FA /* MacawTests.bundle */,
A7E675541EC4211E00BD9ECB /* Bounds */,
5713C4F11E5AD35900BBA4D9 /* Animation */,
57CAB1241D7832E000FD8E47 /* svg */,
@ -1298,6 +1303,7 @@
C4820B191F458D64008CE0FF /* MacawSVGTests.swift */,
5BAE2057208F24DE006BF277 /* SceneSerialization.swift */,
57FCD27D1D76EA4600CC0FB6 /* Info.plist */,
6A616BFB212964E8006A07FA /* SVGParserTest.swift */,
);
path = MacawTests;
sourceTree = "<group>";
@ -1788,6 +1794,7 @@
5B1AE27420B6A669007EECCB /* color-prop-02-f-manual.svg in Resources */,
5B1AE25120B6A669007EECCB /* coords-trans-05-t-manual.reference in Resources */,
5B1AE29120B6A669007EECCB /* coords-transformattr-01-f-manual.svg in Resources */,
6A616BFA2129560A006A07FA /* MacawTests.bundle in Resources */,
5B1AE2D320B6A669007EECCB /* shapes-rect-04-f-manual.reference in Resources */,
5B1AE23C20B6A669007EECCB /* paths-data-15-t-manual.svg in Resources */,
5BAE2039208E163D006BF277 /* polygon.reference in Resources */,
@ -2222,6 +2229,7 @@
5713C4F31E5AD46800BBA4D9 /* ControlStatesTests.swift in Sources */,
57FCD27C1D76EA4600CC0FB6 /* MacawTests.swift in Sources */,
A7E675561EC4213500BD9ECB /* NodeBoundsTests.swift in Sources */,
6A616BFC212964E8006A07FA /* SVGParserTest.swift in Sources */,
57E0EB2E1EB34CDD00638039 /* AnimationUtilsTests.swift in Sources */,
5713C4F51E5AE2C300BBA4D9 /* CombineAnimationTests.swift in Sources */,
57CAB1231D782DFC00FD8E47 /* TestUtils.swift in Sources */,

View File

@ -30,23 +30,24 @@ class MacawSVGTests: XCTestCase {
}
}
func validate(_ test: String) {
func validate(_ testResource: String) {
let bundle = Bundle(for: type(of: TestUtils()))
do {
let node = try SVGParser.parse(bundle: bundle, path: test)
validate(node: node, referenceFile: test)
let node = try SVGParser.parse(bundle: bundle, path: testResource)
validate(node: node, referenceFile: testResource)
let node2 = try SVGParser.parse(resource: testResource, fromBundle: bundle)
validate(node: node2, referenceFile: testResource)
} catch {
print(error)
XCTFail()
}
}
func create(_ test: String) {
func create(_ testResource: String) {
let bundle = Bundle(for: type(of: TestUtils()))
do {
let path = bundle.path(forResource: test, ofType: "svg")?.replacingOccurrences(of: ".svg", with: ".reference")
let node = try SVGParser.parse(bundle: bundle, path: test)
let path = bundle.path(forResource: testResource, ofType: "svg")?.replacingOccurrences(of: ".svg", with: ".reference")
let node = try SVGParser.parse(bundle: bundle, path: testResource)
let result = SVGSerializer.serialize(node: node)
try result.write(to: URL(fileURLWithPath: path!), atomically: true, encoding: String.Encoding.utf8)
} catch {
@ -175,21 +176,23 @@ class MacawSVGTests: XCTestCase {
}
}
func validateJSON(_ test: String) {
func validateJSON(_ testResource: String) {
let bundle = Bundle(for: type(of: TestUtils()))
do {
let node = try SVGParser.parse(bundle: bundle, path: test)
validateJSON(node: node, referenceFile: test)
let node = try SVGParser.parse(bundle: bundle, path: testResource)
validateJSON(node: node, referenceFile: testResource)
let node2 = try SVGParser.parse(resource: testResource, fromBundle: bundle)
validateJSON(node: node2, referenceFile: testResource)
} catch {
XCTFail(error.localizedDescription)
}
}
func createJSON(_ test: String) {
func createJSON(_ testResource: String) {
let bundle = Bundle(for: type(of: TestUtils()))
do {
let path = bundle.path(forResource: test, ofType: "svg")?.replacingOccurrences(of: ".svg", with: ".reference")
let node = try SVGParser.parse(bundle: bundle, path: test)
let path = bundle.path(forResource: testResource, ofType: "svg")?.replacingOccurrences(of: ".svg", with: ".reference")
let node = try SVGParser.parse(bundle: bundle, path: testResource)
guard let serializableNode = node as? Serializable else {
XCTFail()
return

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ><g><g><circle r="40" cy="50" cx="50" fill="red" stroke="black" stroke-width="3.0"/><circle r="40" cy="50" cx="140" fill="#F0F0AA" stroke="black" stroke-width="3.0"/></g></g></svg>

After

Width:  |  Height:  |  Size: 282 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" ><g><circle r="40" cy="50" cx="50" fill="red" stroke="black" stroke-width="3.0"/><circle r="40" cy="50" cx="140" fill="#F0F0AA" stroke="black" stroke-width="3.0"/></g></svg>

After

Width:  |  Height:  |  Size: 276 B

View File

@ -0,0 +1,43 @@
//
// SVGParserTest.swift
// MacawTests
//
// Created by Julius Lundang on 19/08/2018.
// Copyright © 2018 Exyte. All rights reserved.
//
import XCTest
@testable import Macaw
class SVGParserTest: XCTestCase {
func testParseFromOtherBundle() {
let bundle = Bundle(for: type(of: TestUtils()))
let bundleMacawTestsURL = bundle.resourceURL?.appendingPathComponent("MacawTests.bundle")
let macawTestsBundle = Bundle(url: bundleMacawTestsURL!)!
do {
let node = try SVGParser.parse(resource: "circle", fromBundle: macawTestsBundle)
XCTAssertNotNil(node)
if let fullPath = macawTestsBundle.path(forResource: "circle", ofType: "svg") {
let node2 = try SVGParser.parse(fullPath: fullPath)
XCTAssertNotNil(node2)
} else {
XCTFail("No circle.svg found")
}
} catch {
XCTFail(error.localizedDescription)
}
}
func testParseGivenInvalidPath() {
let fullPath = "invalid fullPath"
XCTAssertThrowsError(try SVGParser.parse(fullPath: fullPath)) { error in
XCTAssertEqual(error as! SVGParserError, SVGParserError.noSuchFile(path: "invalid fullPath"))
}
}
func testParseGiventEmptyPath() {
XCTAssertThrowsError(try SVGParser.parse(fullPath: "")) { error in
XCTAssertEqual(error as! SVGParserError, SVGParserError.noSuchFile(path: ""))
}
}
}

View File

@ -12,21 +12,65 @@ import SWXMLHash
open class SVGParser {
/// Parse an SVG file identified by the specified bundle, name and file extension.
/// - returns: Root node of the corresponding Macaw scene.
///
/// - Parameters:
/// - bundle: Bundle resource
/// - path: Resource filename
/// - ofType: Type of resource file. The default is "svg"
/// - Returns: Root node of the corresponding Macaw scene.
/// - Throws: An SVGParserError of no such file
@available(*, deprecated)
open class func parse(bundle: Bundle, path: String, ofType: String = "svg") throws -> Node {
guard let fullPath = bundle.path(forResource: path, ofType: ofType) else {
throw SVGParserError.noSuchFile(path: "\(path).\(ofType)")
}
let text = try String(contentsOfFile: fullPath, encoding: String.Encoding.utf8)
let text = try String(contentsOfFile: fullPath, encoding: .utf8)
return try SVGParser.parse(text: text)
}
/// Parse an SVG file identified by the specified name and file extension.
/// - returns: Root node of the corresponding Macaw scene.
///
/// - Parameters:
/// - path: Resource filename
/// - ofType: Type of resource file. The default is "svg"
/// - Returns: Root node of the corresponding Macaw scene.
/// - Throws: An SVGParserError of no such file
@available(*, deprecated)
open class func parse(path: String, ofType: String = "svg") throws -> Node {
return try SVGParser.parse(bundle: Bundle.main, path: path, ofType: ofType)
}
/// Parse an SVG file
///
/// - Parameters:
/// - resource: Resource file name
/// - type: Type of resource file. The default is `svg`
/// - directory: Directory of given resource
/// - bundle: Bundle of given resource
/// - Returns: Root node of the corresponding Macaw scene.
/// - Throws: An SVGParserError of no such file
open class func parse(resource: String,
ofType type: String = "svg",
inDirectory directory: String? = nil,
fromBundle bundle: Bundle = Bundle.main) throws -> Node {
guard let fullpath = bundle.path(forResource: resource, ofType: type, inDirectory: directory) else {
throw SVGParserError.noSuchFile(path: "\(resource).\(type)")
}
return try SVGParser.parse(fullPath: fullpath)
}
/// Parse an SVG file identified by full file path
///
/// - Parameter fullPath: Full path
/// - Returns: Root node of the corresponding Macaw scene.
/// - Throws: An SVGParserError of no such file
open class func parse(fullPath: String) throws -> Node {
guard let text = try? String(contentsOfFile: fullPath, encoding: .utf8) else {
throw SVGParserError.noSuchFile(path: fullPath)
}
return try SVGParser.parse(text: text)
}
/// Parse the specified content of an SVG file.
/// - returns: Root node of the corresponding Macaw scene.
open class func parse(text: String) throws -> Node {

View File

@ -6,6 +6,6 @@
//
//
enum SVGParserError: Error {
enum SVGParserError: Error, Equatable {
case noSuchFile(path: String)
}

View File

@ -10,7 +10,7 @@ open class SVGView: MacawView {
@IBInspectable open var fileName: String? {
didSet {
node = (try? SVGParser.parse(path: fileName ?? "")) ?? Group()
node = (try? SVGParser.parse(resource: fileName ?? "")) ?? Group()
}
}