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

Merge branch 'master' into task/cascade-animation

This commit is contained in:
Alisa Mylnikova 2019-07-05 14:31:35 +07:00
commit 62a8a863bf
161 changed files with 7688 additions and 139 deletions

View File

@ -1,4 +1,4 @@
language: objective-c
language: swift
osx_image: xcode10.2
branches:
@ -7,7 +7,8 @@ branches:
script:
- set -o pipefail && xcodebuild test -project Macaw.xcodeproj -scheme 'Macaw iOS' -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO -destination 'platform=iOS Simulator,OS=12.2,name=iPhone X' | xcpretty;
- set -o pipefail && xcodebuild build -project Macaw.xcodeproj -scheme 'MacawOSX' ONLY_ACTIVE_ARCH=NO | xcpretty;
- set -o pipefail && xcodebuild test -project Macaw.xcodeproj -scheme 'MacawOSX' ONLY_ACTIVE_ARCH=NO | xcpretty;
notifications:
slack: exyte:kdo9FNtTOFMuMqAyyvZPDAD7

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,26 @@
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "57FCD2751D76EA4600CC0FB6"
BuildableName = "MacawTests.xctest"
BlueprintName = "MacawTests"
ReferencedContainer = "container:Macaw.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "57614AFB1F83D15600875933"
BuildableName = "MacawOSX.framework"
BlueprintName = "MacawOSX"
ReferencedContainer = "container:Macaw.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>

View File

@ -7,7 +7,12 @@
//
import XCTest
#if os(OSX)
@testable import MacawOSX
#elseif os(iOS)
@testable import Macaw
#endif
class AnimationUtilsTests: XCTestCase {

View File

@ -6,24 +6,27 @@
// Copyright © 2017 Exyte. All rights reserved.
//
#if os(iOS)
import XCTest
#if os(OSX)
@testable import MacawOSX
#elseif os(iOS)
@testable import Macaw
#endif
class CombineAnimationTests: XCTestCase {
var testView: MacawView!
var testGroup: Group!
var window: UIWindow!
var window: MWindow!
override func setUp() {
super.setUp()
testGroup = [Shape(form:Rect(x: 0.0, y: 0.0, w: 0.0, h: 0.0))].group()
testView = MacawView(node: testGroup, frame: CGRect.zero)
testView = MacawView(node: testGroup, frame: .zero)
window = UIWindow()
window = MWindow()
window.addSubview(testView)
}
@ -98,5 +101,3 @@ class CombineAnimationTests: XCTestCase {
}
}
#endif

View File

@ -7,7 +7,12 @@
//
import XCTest
#if os(OSX)
@testable import MacawOSX
#elseif os(iOS)
@testable import Macaw
#endif
class ControlStatesTests: XCTestCase {

View File

@ -6,25 +6,27 @@
// Copyright © 2017 Exyte. All rights reserved.
//
#if os(iOS)
import XCTest
#if os(OSX)
@testable import MacawOSX
#elseif os(iOS)
@testable import Macaw
#endif
class DelayedAnimationTests: XCTestCase {
var testView: MacawView!
var testGroup: Group!
var window: UIWindow!
var window: MWindow!
override func setUp() {
super.setUp()
testGroup = [Shape(form:Rect(x: 0.0, y: 0.0, w: 0.0, h: 0.0))].group()
testView = MacawView(node: testGroup, frame: CGRect.zero)
testView = MacawView(node: testGroup, frame: .zero)
window = UIWindow()
window = MWindow()
window.addSubview(testView)
}
@ -54,5 +56,3 @@ class DelayedAnimationTests: XCTestCase {
XCTAssert(animation.paused && !animation.manualStop, "Wrong animation state on pause")
}
}
#endif

View File

@ -6,24 +6,27 @@
// Copyright © 2017 Exyte. All rights reserved.
//
#if os(iOS)
import XCTest
#if os(OSX)
@testable import MacawOSX
#elseif os(iOS)
@testable import Macaw
#endif
class SequenceAnimationTests: XCTestCase {
var testView: MacawView!
var testGroup: Group!
var window: UIWindow!
var window: MWindow!
override func setUp() {
super.setUp()
testGroup = [Shape(form:Rect(x: 0.0, y: 0.0, w: 0.0, h: 0.0))].group()
testView = MacawView(node: testGroup, frame: CGRect.zero)
testView = MacawView(node: testGroup, frame: .zero)
window = UIWindow()
window = MWindow()
window.addSubview(testView)
}
@ -78,5 +81,3 @@ class SequenceAnimationTests: XCTestCase {
}
}
#endif

View File

@ -6,10 +6,13 @@
// Copyright © 2017 Exyte. All rights reserved.
//
#if os(iOS)
import XCTest
#if os(OSX)
@testable import MacawOSX
#elseif os(iOS)
@testable import Macaw
#endif
class ImageBoundsTests: XCTestCase {
@ -26,7 +29,11 @@ class ImageBoundsTests: XCTestCase {
return
}
XCTAssert(bounds.w == 1174.0 && bounds.h == 862.0, "Wrong bounds for path src")
#if os(iOS)
XCTAssert(bounds.w == 1174.0 && bounds.h == 862.0, "Wrong bounds for path src")
#elseif os(OSX)
XCTAssert(bounds.w == 587.0 && bounds.h == 431.0, "Wrong bounds for path src")
#endif
}
func testSrcAsBase64() {
@ -36,7 +43,6 @@ class ImageBoundsTests: XCTestCase {
return
}
let url = URL(fileURLWithPath: path)
guard let base64Content = try? String(contentsOf: url) else {
XCTFail()
@ -49,25 +55,40 @@ class ImageBoundsTests: XCTestCase {
return
}
XCTAssert(bounds.w == 1174.0 && bounds.h == 862.0, "Wrong bounds for base64 src")
#if os(iOS)
XCTAssert(bounds.w == 1174.0 && bounds.h == 862.0, "Wrong bounds for base64 src")
#elseif os(OSX)
XCTAssert(bounds.w == 587.0 && bounds.h == 431.0, "Wrong bounds for base64 src")
#endif
}
func testInMemoryImage() {
let bundle = Bundle(for: type(of: TestUtils()))
#if os(iOS)
guard let mImage = MImage(named: "logo.png", in: bundle, compatibleWith: .none) else {
XCTFail()
return
}
#elseif os(OSX)
guard let mImage = bundle.image(forResource: "logo.png") else {
XCTFail()
return
}
#endif
let image = Image(image: mImage)
guard let bounds = image.bounds else {
XCTFail("Bounds not available")
return
}
XCTAssert(bounds.w == 1174.0 && bounds.h == 862.0, "Wrong bounds for in-memory image")
#if os(iOS)
XCTAssert(bounds.w == 1174.0 && bounds.h == 862.0, "Wrong bounds for in-memory image")
#elseif os(OSX)
XCTAssert(bounds.w == 587.0 && bounds.h == 431.0, "Wrong bounds for in-memory image")
#endif
}
}
#endif

View File

@ -6,13 +6,16 @@
// Copyright © 2017 Exyte. All rights reserved.
//
#if os(iOS)
import XCTest
#if os(OSX)
@testable import MacawOSX
#elseif os(iOS)
@testable import Macaw
#endif
class NodeBoundsTests: XCTestCase {
var window: UIWindow!
var window: MWindow!
//TO DO: need to test paths bounds: M 50 50 C 20 20, 40 20, 50 10 and M 50 50 c 20 20, 40 20, 50 10
//currently doesn't work because of http://www.openradar.me/6468254639 or #41355347 on https://bugreport.apple.com/
@ -20,7 +23,7 @@ class NodeBoundsTests: XCTestCase {
override func setUp() {
super.setUp()
window = UIWindow()
window = MWindow()
}
override func tearDown() {
@ -317,5 +320,3 @@ class NodeBoundsTests: XCTestCase {
validate(node: shape, referenceBounds: targetRect)
}
}
#endif

View File

@ -1,11 +1,34 @@
import XCTest
#if os(OSX)
@testable import MacawOSX
#elseif os(iOS)
@testable import Macaw
#endif
class MacawSVGTests: XCTestCase {
/*
When test are running, if shouldSaveFaildedTestImage set to true, result images will be saved into MacawTestOutputData folder in documents.
Also, there is no way to detect that multiple test will runs.
In this case, when all MacawSVGTests will be performed, set multipleTestsWillRun to true, then all test images will be saved to the folder.
Then, if you want to investigate one particular test result, set multipleTestsWillRun to false and test folder will be deleted before new test will run.
*/
private let testFolderName = "MacawTestOutputData"
private let shouldComparePNGImages = true
private let multipleTestsWillRun = false
private let shouldSaveFaildedTestImage = false
override func setUp() {
// Put setup code here. This method is called before the invocation of each test method in the class.
super.setUp()
if shouldSaveFaildedTestImage {
setupTestFolderDirectory()
}
}
override func tearDown() {
@ -25,8 +48,7 @@ class MacawSVGTests: XCTestCase {
XCTFail("No file \(referenceFile)")
}
} catch {
print(error)
XCTFail()
XCTFail(error.localizedDescription)
}
}
@ -36,8 +58,7 @@ class MacawSVGTests: XCTestCase {
let node = try SVGParser.parse(resource: testResource, fromBundle: bundle)
validate(node: node, referenceFile: testResource)
} catch {
print(error)
XCTFail()
XCTFail(error.localizedDescription)
}
}
@ -59,8 +80,7 @@ class MacawSVGTests: XCTestCase {
let path = bundle.bundlePath + "/" + name + ".reference"
try result.write(to: URL(fileURLWithPath: path), atomically: true, encoding: String.Encoding.utf8)
} catch {
print(error)
XCTFail()
XCTFail(error.localizedDescription)
}
}
@ -105,10 +125,13 @@ class MacawSVGTests: XCTestCase {
func testSVGImage() {
let bundle = Bundle(for: type(of: TestUtils()))
if let path = bundle.path(forResource: "small-logo", ofType: "png") {
if let mimage = MImage(contentsOfFile: path), let base64Content = MImagePNGRepresentation(mimage)?.base64EncodedString() {
let node = Image(image: mimage)
let imageReferenceContent = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" ><image xlink:href=\"data:image/png;base64,\(String(base64Content))\" width=\"59.0\" height=\"43.0\" /></svg>"
XCTAssertEqual(SVGSerializer.serialize(node: node), imageReferenceContent)
if let mImage = MImage(contentsOfFile: path), let base64Content = MImagePNGRepresentation(mImage)?.base64EncodedString() {
let imageSize = mImage.size
let imageReferenceContent = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" ><image xlink:href=\"data:image/png;base64,\(String(base64Content))\" width=\"\(imageSize.width)\" height=\"\(imageSize.height)\" /></svg>"
let node = Image(image: mImage)
let imageSerialization = SVGSerializer.serialize(node: node)
XCTAssertEqual(imageSerialization, imageReferenceContent)
}
}
}
@ -174,10 +197,18 @@ class MacawSVGTests: XCTestCase {
let nodeContent = String(data: getJSONData(node: node), encoding: String.Encoding.utf8)
if nodeContent != referenceContent {
let referencePath = writeToFile(string: referenceContent, fileName: referenceFile + "_reference.txt")
let _ = writeToFile(string: nodeContent!, fileName: referenceFile + "_incorrect.txt")
XCTFail("Not equal, see both files in \(String(describing: referencePath?.deletingLastPathComponent().path))")
XCTFail("nodeContent is not equal to referenceContent")
}
let nativeImage = getImage(from: referenceFile)
//To save new PNG image for test, uncomment this
//saveImage(image: nativeImage, fileName: referenceFile)
#if os(OSX)
if shouldComparePNGImages {
validateImage(nodeImage: nativeImage, referenceFile: referenceFile)
}
#endif
} else {
XCTFail("No file \(referenceFile)")
}
@ -195,6 +226,53 @@ class MacawSVGTests: XCTestCase {
XCTFail(error.localizedDescription)
}
}
func validateImage(nodeImage: MImage, referenceFile: String) {
let bundle = Bundle(for: type(of: TestUtils()))
guard let fullpath = bundle.path(forResource: referenceFile, ofType: "png"), let referenceImage = MImage(contentsOfFile: fullpath) else {
XCTFail("No reference image \(referenceFile)")
return
}
#if os(OSX)
guard let referenceContentData = referenceImage.tiffRepresentation else {
XCTFail("Failed to get Data from png \(referenceFile).png")
return
}
guard let nodeContentData = nodeImage.tiffRepresentation else {
XCTFail("Failed to get Data from reference image \(referenceFile)")
return
}
#endif
#if os(iOS)
guard let referenceContentData = referenceImage.pngData() else {
XCTFail("Failed to get Data from png \(referenceFile).png")
return
}
guard let nodeContentData = nodeImage.pngData() else {
XCTFail("Failed to get Data from reference image \(referenceFile)")
return
}
#endif
if referenceContentData != nodeContentData {
var failInfo = "referenceContentData is not equal to nodeContentData"
if shouldSaveFaildedTestImage {
let _ = saveImage(image: referenceImage, fileName: referenceFile + "_reference")
let _ = saveImage(image: nodeImage, fileName: referenceFile + "_incorrect")
failInfo.append("\n Images are saved in \(testFolderName) folder in Documents directory")
}
XCTFail(failInfo)
}
}
func createJSON(_ testResourcePath: String) {
do {
@ -214,11 +292,21 @@ class MacawSVGTests: XCTestCase {
return Data()
}
do {
#if os(OSX)
if #available(OSX 10.13, *) {
return try JSONSerialization.data(withJSONObject: serializableNode.toDictionary(), options: [.prettyPrinted, .sortedKeys])
} else {
return try JSONSerialization.data(withJSONObject: serializableNode.toDictionary(), options: .prettyPrinted)
}
#endif
#if os(iOS)
if #available(iOS 11.0, *) {
return try JSONSerialization.data(withJSONObject: serializableNode.toDictionary(), options: [.prettyPrinted, .sortedKeys])
} else {
return try JSONSerialization.data(withJSONObject: serializableNode.toDictionary(), options: .prettyPrinted)
}
#endif
} catch {
XCTFail(error.localizedDescription)
return Data()
@ -240,15 +328,16 @@ class MacawSVGTests: XCTestCase {
}
func writeToFile(data: Data, fileName: String) -> URL? {
guard let directory = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) as NSURL else {
return .none
guard let documentDirectory = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) as NSURL,
let testDirectory = documentDirectory.appendingPathComponent(testFolderName) else {
return .none
}
do {
let path = directory.appendingPathComponent("\(fileName)")!
try data.write(to: URL(fileURLWithPath: fileName))
let path = testDirectory.appendingPathComponent("\(fileName)")
try data.write(to: path)
return path
} catch {
print(error.localizedDescription)
XCTFail(error.localizedDescription)
return .none
}
}
@ -546,7 +635,11 @@ class MacawSVGTests: XCTestCase {
}
func testColorProp04() {
#if os(iOS)
validateJSON("color-prop-04-t-manual")
#elseif os(OSX)
validateJSON("color-prop-04-t-manual-osx")
#endif
}
func testTypesBasic01() {
@ -652,6 +745,10 @@ class MacawSVGTests: XCTestCase {
func testPathsData10() {
validateJSON("paths-data-10-t-manual")
}
func testShapesGrammar01() {
validateJSON("shapes-grammar-01-f-manual")
}
func testPserversGrad01() {
validateJSON("pservers-grad-01-b-manual")
@ -661,23 +758,118 @@ class MacawSVGTests: XCTestCase {
validateJSON("pservers-grad-02-b-manual")
}
func testPserversGrad03() {
validateJSON("pservers-grad-03-b-manual")
}
func testPserversGrad07() {
validateJSON("pservers-grad-07-b-manual")
}
func testShapesGrammar01() {
validateJSON("shapes-grammar-01-f-manual")
func testPserversGrad09() {
validateJSON("pservers-grad-09-b-manual")
}
func testMaskingPath02() {
validateJSON("masking-path-02-b-manual")
func testPserversGrad12() {
validateJSON("pservers-grad-12-b-manual")
}
func testPserversGrad13() {
validateJSON("pservers-grad-13-b-manual")
}
func testPserversGrad15() {
validateJSON("pservers-grad-15-b-manual")
}
func testPserversGrad22() {
validateJSON("pservers-grad-22-b-manual")
}
func testPserversGrad23() {
validateJSON("pservers-grad-23-f-manual")
}
func testPserversGrad24() {
validateJSON("pservers-grad-24-f-manual")
}
func testMaskingIntro01() {
validateJSON("masking-intro-01-f-manual")
}
func testPserversGrad03() {
validateJSON("pservers-grad-03-b-manual")
func testMaskingFilter01() {
validateJSON("masking-filter-01-f-manual")
}
func testMaskingPath02() {
validateJSON("masking-path-02-b-manual")
}
func testMaskingPath13() {
validateJSON("masking-path-13-f-manual")
}
func testMaskingMask02() {
validateJSON("masking-mask-02-f-manual")
}
func getImage(from svgName: String) -> MImage {
let bundle = Bundle(for: type(of: TestUtils()))
do {
let node = try SVGParser.parse(resource: svgName, fromBundle: bundle)
var frame = node.bounds
if frame == nil, let group = node as? Group {
frame = Group(contents: group.contents).bounds
}
let image = node.toNativeImage(size: frame?.size() ?? Size.init(w: 100, h: 100))
return image
} catch {
XCTFail(error.localizedDescription)
}
XCTFail()
return MImage()
}
func saveImage(image: MImage, fileName: String) {
#if os(OSX)
guard let data = image.tiffRepresentation else {
return
}
#endif
#if os(iOS)
guard let data = image.pngData() else {
return
}
#endif
let _ = writeToFile(data: data, fileName: "\(fileName).png")
}
fileprivate func setupTestFolderDirectory() {
guard let myDocuments = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
return
}
let testDirectoryPath = myDocuments.appendingPathComponent("\(testFolderName)")
do {
if !multipleTestsWillRun {
try FileManager.default.removeItem(at: testDirectoryPath)
}
var isDirectory: ObjCBool = ObjCBool(true)
if !FileManager.default.fileExists(atPath: testDirectoryPath.absoluteString, isDirectory: &isDirectory) {
try FileManager.default.createDirectory(at: testDirectoryPath, withIntermediateDirectories: true, attributes: .none)
}
} catch {
XCTFail(error.localizedDescription)
return
}
}
}

View File

@ -1,5 +1,10 @@
import XCTest
#if os(OSX)
@testable import MacawOSX
#elseif os(iOS)
@testable import Macaw
#endif
class MacawTests: XCTestCase {

View File

@ -7,7 +7,12 @@
//
import XCTest
#if os(OSX)
@testable import MacawOSX
#elseif os(iOS)
@testable import Macaw
#endif
class SVGParserTest: XCTestCase {
func testParseFromOtherBundle() {

View File

@ -6,8 +6,15 @@
// Copyright © 2018 Exyte. All rights reserved.
//
#if os(OSX)
import Foundation
@testable import MacawOSX
#endif
#if os(iOS)
import UIKit
@testable import Macaw
#endif
protocol Initializable {
init()
@ -367,12 +374,23 @@ extension Path: Serializable {
}
}
#if os(iOS)
extension Polygon: Serializable {
func toDictionary() -> [String:Any] {
return ["type": "Polygon", "points": points]
}
}
#endif
#if os(OSX)
extension MacawOSX.Polygon: Serializable {
func toDictionary() -> [String:Any] {
return ["type": "Polygon", "points": points]
}
}
#endif
extension Polyline: Serializable {

View File

@ -1,5 +1,11 @@
import Foundation
import Macaw
#if os(OSX)
@testable import MacawOSX
#endif
#if os(iOS)
@testable import Macaw
#endif
class TestUtils {

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More