mise-a-jour-tags #6

Merged
l.perret merged 21 commits from mise-a-jour-tags into master 2023-12-13 10:46:10 +01:00
7 changed files with 895 additions and 84 deletions
Showing only changes of commit 2a144fc00e - Show all commits

View File

@ -126,13 +126,13 @@ class TagsGenerator {
let footer = " }"
if targets.contains(Tags.TargetType.matomo) {
header = "func configure(sideId: String, url: String) {"
header = "func configure(siteId: String, url: String) {"
} else if targets.contains(Tags.TargetType.firebase) {
header = "func configure() {"
}
if targets.contains(Tags.TargetType.matomo) {
content.append(" managers.append(MatomoAnalyticsManager(siteId: sideId, url: url))\n")
content.append(" managers.append(MatomoAnalyticsManager(siteId: siteId, url: url))")
}
if targets.contains(Tags.TargetType.firebase) {
content.append(" managers.append(FirebaseAnalyticsManager())")

View File

@ -144,6 +144,22 @@ final class StringsFileGeneratorTests: XCTestCase {
extension GenStrings {
enum KeyStrings: String {
case s1_def_one = "s1_def_one"
case s1_def_two = "s1_def_two"
case s2_def_one = "s2_def_one"
case s2_def_two = "s2_def_two"
var keyPath: KeyPath<GenStrings, String> {
switch self {
case .s1_def_one: return \\GenStrings.s1_def_one
case .s1_def_two: return \\GenStrings.s1_def_two
case .s2_def_one: return \\GenStrings.s2_def_one
case .s2_def_two: return \\GenStrings.s2_def_two
}
}
}
// MARK: - section_one
/// Translation in fr :
@ -174,6 +190,9 @@ final class StringsFileGeneratorTests: XCTestCase {
}
"""
if extensionContent != expect {
print(prettyFirstDifferenceBetweenStrings(s1: extensionContent, s2: expect))
}
XCTAssertEqual(extensionContent.adaptForXCTest(), expect.adaptForXCTest())
}
@ -221,6 +240,22 @@ final class StringsFileGeneratorTests: XCTestCase {
extension GenStrings {
enum KeyStrings: String {
case s1_def_one = "s1_def_one"
case s1_def_two = "s1_def_two"
case s2_def_one = "s2_def_one"
case s2_def_two = "s2_def_two"
var keyPath: KeyPath<GenStrings, String> {
switch self {
case .s1_def_one: return \\GenStrings.s1_def_one
case .s1_def_two: return \\GenStrings.s1_def_two
case .s2_def_one: return \\GenStrings.s2_def_one
case .s2_def_two: return \\GenStrings.s2_def_two
}
}
}
// MARK: - section_one
/// Translation in fr :
@ -251,6 +286,9 @@ final class StringsFileGeneratorTests: XCTestCase {
}
"""
if extensionContent != expect {
print(prettyFirstDifferenceBetweenStrings(s1: extensionContent, s2: expect))
}
XCTAssertEqual(extensionContent.adaptForXCTest(), expect.adaptForXCTest())
}
}

View File

@ -1,82 +0,0 @@
//
// TagsGeneratorTests.swift
//
//
// Created by Thibaut Schmitt on 06/09/2022.
//
import Foundation
import XCTest
import ToolCore
@testable import ResgenSwift
final class TagsGeneratorTests: XCTestCase {
private func getDefinition(name: String, lang: String, tags: [String]) -> TagDefinition {
let definition = TagDefinition(title: name)
definition.tags = tags
// definition.translations = [lang: "Some translation"]
return definition
}
func testGeneratedExtensionContent() {
// Given
let sectionOne = TagSection(name: "section_one")
sectionOne.definitions = [
getDefinition(name: "s1_def_one", lang: "ium", tags: ["ios","iosonly"]),
getDefinition(name: "s1_def_two", lang: "ium", tags: ["ios","iosonly"]),
]
let sectionTwo = TagSection(name: "section_two")
sectionTwo.definitions = [
getDefinition(name: "s2_def_one", lang: "ium", tags: ["ios","iosonly"]),
getDefinition(name: "s2_def_two", lang: "ium", tags: ["droid","droidonly"])
]
let sectionThree = TagSection(name: "section_three")
sectionThree.definitions = [
getDefinition(name: "s3_def_one", lang: "ium", tags: ["droid","droidonly"]),
getDefinition(name: "s3_def_two", lang: "ium", tags: ["droid","droidonly"])
]
// When
let extensionContent = TagsGenerator.getExtensionContent(sections: [sectionOne, sectionTwo, sectionThree],
targets: [Tags.TargetType.firebase],
tags: ["ios", "iosonly"],
staticVar: false,
extensionName: "GenTags")
// Expect Tags
let expect = """
// Generated by ResgenSwift.Strings.Tags \(ResgenSwiftVersion)
import UIKit
extension GenTags {
// MARK: - section_one
/// Translation in ium :
/// Some translation
var s1_def_one: String {
"Some translation"
}
/// Translation in ium :
/// Some translation
var s1_def_two: String {
"Some translation"
}
// MARK: - section_two
/// Translation in ium :
/// Some translation
var s2_def_one: String {
"Some translation"
}
}
"""
XCTAssertEqual(extensionContent.adaptForXCTest(), expect.adaptForXCTest())
}
}

View File

@ -0,0 +1,135 @@
//
// File.swift
//
//
// Created by Loris Perret on 06/12/2023.
//
import Foundation
/// Find first differing character between two strings
///
/// :param: s1 First String
/// :param: s2 Second String
///
/// :returns: .DifferenceAtIndex(i) or .NoDifference
public func firstDifferenceBetweenStrings(s1: NSString, s2: NSString) -> FirstDifferenceResult {
let len1 = s1.length
let len2 = s2.length
let lenMin = min(len1, len2)
for i in 0..<lenMin {
if s1.character(at: i) != s2.character(at: i) {
return .DifferenceAtIndex(i)
}
}
if len1 < len2 {
return .DifferenceAtIndex(len1)
}
if len2 < len1 {
return .DifferenceAtIndex(len2)
}
return .NoDifference
}
/// Create a formatted String representation of difference between strings
///
/// :param: s1 First string
/// :param: s2 Second string
///
/// :returns: a string, possibly containing significant whitespace and newlines
public func prettyFirstDifferenceBetweenStrings(s1: String, s2: String) -> String {
let firstDifferenceResult = firstDifferenceBetweenStrings(s1: s1 as NSString, s2: s2 as NSString)
return prettyDescriptionOfFirstDifferenceResult(firstDifferenceResult: firstDifferenceResult, s1: s1 as NSString, s2: s2 as NSString) as String
}
/// Create a formatted String representation of a FirstDifferenceResult for two strings
///
/// :param: firstDifferenceResult FirstDifferenceResult
/// :param: s1 First string used in generation of firstDifferenceResult
/// :param: s2 Second string used in generation of firstDifferenceResult
///
/// :returns: a printable string, possibly containing significant whitespace and newlines
public func prettyDescriptionOfFirstDifferenceResult(firstDifferenceResult: FirstDifferenceResult, s1: NSString, s2: NSString) -> NSString {
func diffString(index: Int, s1: NSString, s2: NSString) -> NSString {
let markerArrow = "\u{2b06}" // ""
let ellipsis = "\u{2026}" // ""
/// Given a string and a range, return a string representing that substring.
///
/// If the range starts at a position other than 0, an ellipsis
/// will be included at the beginning.
///
/// If the range ends before the actual end of the string,
/// an ellipsis is added at the end.
func windowSubstring(s: NSString, range: NSRange) -> String {
let validRange = NSMakeRange(range.location, min(range.length, s.length - range.location))
let substring = s.substring(with: validRange)
let prefix = range.location > 0 ? ellipsis : ""
let suffix = (s.length - range.location > range.length) ? ellipsis : ""
return "\(prefix)\(substring)\(suffix)"
}
// Show this many characters before and after the first difference
let windowPrefixLength = 10
let windowSuffixLength = 10
let windowLength = windowPrefixLength + 1 + windowSuffixLength
let windowIndex = max(index - windowPrefixLength, 0)
let windowRange = NSMakeRange(windowIndex, windowLength)
let sub1 = windowSubstring(s: s1, range: windowRange)
let sub2 = windowSubstring(s: s2, range: windowRange)
let markerPosition = min(windowSuffixLength, index) + (windowIndex > 0 ? 1 : 0)
let markerPrefix = String(repeating: " " as Character, count: markerPosition)
let markerLine = "\(markerPrefix)\(markerArrow)"
return "Difference at index \(index):\n\(sub1)\n\(sub2)\n\(markerLine)" as NSString
}
switch firstDifferenceResult {
case .NoDifference: return "No difference"
case .DifferenceAtIndex(let index): return diffString(index: index, s1: s1, s2: s2)
}
}
/// Result type for firstDifferenceBetweenStrings()
public enum FirstDifferenceResult {
/// Strings are identical
case NoDifference
/// Strings differ at the specified index.
///
/// This could mean that characters at the specified index are different,
/// or that one string is longer than the other
case DifferenceAtIndex(Int)
}
extension FirstDifferenceResult {
/// Textual representation of a FirstDifferenceResult
public var description: String {
switch self {
case .NoDifference:
return "NoDifference"
case .DifferenceAtIndex(let index):
return "DifferenceAtIndex(\(index))"
}
}
/// Textual representation of a FirstDifferenceResult for debugging purposes
public var debugDescription: String {
return self.description
}
}

View File

@ -0,0 +1,162 @@
//
// TagDefinitionTests.swift
//
//
// Created by Loris Perret on 06/12/2023.
//
import Foundation
import XCTest
@testable import ResgenSwift
final class TagDefinitionTests: XCTestCase {
// MARK: - Match line
func testMatchingTagDefinition() {
// Given
let line = "[definition_name]"
// When
let definition = TagDefinition.match(line)
// Expect
XCTAssertNotNil(definition)
XCTAssertEqual(definition?.title, "definition_name")
}
func testNotMatchingTagDefinition() {
// Given
let line1 = "definition_name"
let line2 = "[definition_name"
let line3 = "definition_name]"
// When
let definition1 = TagDefinition.match(line1)
let definition2 = TagDefinition.match(line2)
let definition3 = TagDefinition.match(line3)
// Expect
XCTAssertNil(definition1)
XCTAssertNil(definition2)
XCTAssertNil(definition3)
}
// MARK: - Matching tags
func testMatchingTags() {
// Given
let definition = TagDefinition(title: "definition_name")
definition.tags = ["ios","iosonly","notranslation"]
// When
let match1 = definition.hasOneOrMoreMatchingTags(inputTags: ["ios"])
let match2 = definition.hasOneOrMoreMatchingTags(inputTags: ["iosonly"])
let match3 = definition.hasOneOrMoreMatchingTags(inputTags: ["notranslation"])
// Expect
XCTAssertTrue(match1)
XCTAssertTrue(match2)
XCTAssertTrue(match3)
}
func testNotMatchingTags() {
// Given
let definition = TagDefinition(title: "definition_name")
definition.tags = ["ios","iosonly","notranslation"]
// When
let match1 = definition.hasOneOrMoreMatchingTags(inputTags: ["droid"])
let match2 = definition.hasOneOrMoreMatchingTags(inputTags: ["droidonly"])
let match3 = definition.hasOneOrMoreMatchingTags(inputTags: ["azerty"])
// Expect
XCTAssertFalse(match1)
XCTAssertFalse(match2)
XCTAssertFalse(match3)
}
// MARK: - Raw properties
func testGeneratedRawPropertyScreen() {
// Given
let definition = TagDefinition(title: "definition_name")
definition.path = "ecran_un/"
definition.name = "Ecran un"
definition.type = "screen"
// When
let propertyScreen = definition.getProperty()
// Expect
let expectScreen = """
func logScreenEcranUn() {
logScreen(name: "Ecran un", path: "ecran_un/")
}
"""
XCTAssertEqual(propertyScreen.adaptForXCTest(), expectScreen.adaptForXCTest())
}
func testGeneratedRawPropertyEvent() {
// Given
let definition = TagDefinition(title: "definition_name")
definition.path = "ecran_un/"
definition.name = "Ecran un"
definition.type = "event"
// When
let propertyEvent = definition.getProperty()
// Expect
let expectEvent = """
func logEventEcranUn() {
logEvent(name: "Ecran un")
}
"""
XCTAssertEqual(propertyEvent.adaptForXCTest(), expectEvent.adaptForXCTest())
}
func testGeneratedRawStaticPropertyScreen() {
// Given
let definition = TagDefinition(title: "definition_name")
definition.path = "ecran_un/"
definition.name = "Ecran un"
definition.type = "screen"
// When
let propertyScreen = definition.getStaticProperty()
// Expect
let expectScreen = """
static func logScreenEcranUn() {
logScreen(name: "Ecran un", path: "ecran_un/")
}
"""
XCTAssertEqual(propertyScreen.adaptForXCTest(), expectScreen.adaptForXCTest())
}
func testGeneratedRawStaticPropertyEvent() {
// Given
let definition = TagDefinition(title: "definition_name")
definition.path = "ecran_un/"
definition.name = "Ecran un"
definition.type = "event"
// When
let propertyEvent = definition.getStaticProperty()
// Expect
let expectEvent = """
static func logEventEcranUn() {
logEvent(name: "Ecran un")
}
"""
XCTAssertEqual(propertyEvent.adaptForXCTest(), expectEvent.adaptForXCTest())
}
}

View File

@ -0,0 +1,104 @@
//
// TagSectionTests.swift
//
//
// Created by Loris Perret on 06/12/2023.
//
import Foundation
import XCTest
@testable import ResgenSwift
final class TagSectionTests: XCTestCase {
// MARK: - Match line
func testMatchingTagSection() {
// Given
let line = "[[section_name]]"
// When
let section = TagSection.match(line)
// Expect
XCTAssertNotNil(section)
XCTAssertEqual(section?.name, "section_name")
}
func testNotMatchingTagSection() {
// Given
let lines = ["section_name",
"[section_name]",
"[section_name",
"[[section_name",
"[[section_name]",
"section_name]",
"section_name]]",
"[section_name]]"]
// When
let matches = lines.compactMap { TagSection.match($0) }
// Expect
XCTAssertEqual(matches.isEmpty, true)
}
// MARK: - Matching tags
func testMatchingTags() {
// Given
let section = TagSection(name: "section_name")
section.definitions = [
{
let def = TagDefinition(title: "definition_name")
def.tags = ["ios","iosonly"]
return def
}(),
{
let def = TagDefinition(title: "definition_name_two")
def.tags = ["droid","droidonly"]
return def
}()
]
// When
let match1 = section.hasOneOrMoreMatchingTags(tags: ["ios"])
let match2 = section.hasOneOrMoreMatchingTags(tags: ["iosonly"])
let match3 = section.hasOneOrMoreMatchingTags(tags: ["droid"])
let match4 = section.hasOneOrMoreMatchingTags(tags: ["droidonly"])
// Expect
XCTAssertTrue(match1)
XCTAssertTrue(match2)
XCTAssertTrue(match3)
XCTAssertTrue(match4)
}
func testNotMatchingTags() {
// Given
let section = TagSection(name: "section_name")
section.definitions = [
{
let def = TagDefinition(title: "definition_name")
def.tags = ["ios","iosonly"]
return def
}(),
{
let def = TagDefinition(title: "definition_name_two")
def.tags = ["droid","droidonly"]
return def
}()
]
// When
let match1 = section.hasOneOrMoreMatchingTags(tags: ["web"])
let match2 = section.hasOneOrMoreMatchingTags(tags: ["webonly"])
let match3 = section.hasOneOrMoreMatchingTags(tags: ["azerty"])
// Expect
XCTAssertFalse(match1)
XCTAssertFalse(match2)
XCTAssertFalse(match3)
}
}

View File

@ -0,0 +1,454 @@
//
// TagsGeneratorTests.swift
//
//
// Created by Thibaut Schmitt on 06/09/2022.
//
import Foundation
import XCTest
import ToolCore
@testable import ResgenSwift
final class TagsGeneratorTests: XCTestCase {
private func getTagDefinition(title: String, path: String, name: String, type: String, tags: [String]) -> TagDefinition {
let definition = TagDefinition(title: title)
definition.path = path
definition.name = name
definition.type = type
definition.tags = tags
return definition
}
func testGeneratedExtensionContentFirebase() {
// Given
let sectionOne = TagSection(name: "section_one")
sectionOne.definitions = [
getTagDefinition(title: "s1_def_one", path: "s1_def_one/", name: "s1 def one", type: "screen", tags: ["ios", "iosonly"]),
getTagDefinition(title: "s1_def_two", path: "s1_def_two/", name: "s1 def two", type: "event", tags: ["ios", "iosonly"]),
]
let sectionTwo = TagSection(name: "section_two")
sectionTwo.definitions = [
getTagDefinition(title: "s2_def_one", path: "s2_def_one/", name: "s2 def one", type: "screen", tags: ["ios","iosonly"]),
getTagDefinition(title: "s2_def_two", path: "s2_def_two/", name: "s2 def two", type: "event", tags: ["droid","droidonly"]),
]
let sectionThree = TagSection(name: "section_three")
sectionThree.definitions = [
getTagDefinition(title: "s3_def_one", path: "s3_def_one/", name: "s3 def one", type: "screen", tags: ["droid","droidonly"]),
getTagDefinition(title: "s3_def_two", path: "s3_def_two/", name: "s3 def two", type: "event", tags: ["droid","droidonly"]),
]
// When
TagsGenerator.targets = [Tags.TargetType.firebase]
let extensionContent = TagsGenerator.getExtensionContent(sections: [sectionOne, sectionTwo, sectionThree],
tags: ["ios", "iosonly"],
staticVar: false,
extensionName: "GenTags")
// Expect Tags
let expect = """
// Generated by ResgenSwift.Tags 1.2
import UIKit
import Firebase
// MARK: - Protocol
protocol AnalyticsManagerProtocol {
func logScreen(name: String, path: String)
func logEvent(name: String)
}
// MARK: - Firebase
class FirebaseAnalyticsManager: AnalyticsManagerProtocol {
func logScreen(name: String, path: String) {
Analytics.logEvent(AnalyticsEventScreenView, parameters: [AnalyticsParameterScreenName: name])
}
func logEvent(name: String) {
var parameters = [
AnalyticsParameterValue: name
]
Analytics.logEvent(AnalyticsEventSelectContent, parameters: parameters)
}
}
// MARK: - Manager
class AnalyticsManager {
static var shared = AnalyticsManager()
// MARK: - Properties
var managers: [AnalyticsManagerProtocol] = []
private var isEnabled: Bool = true
// MARK: - Methods
func setAnalyticsEnabled(_ enable: Bool) { isEnabled = enable }
func configure() {
managers.append(FirebaseAnalyticsManager())
}
private func logScreen(name: String, path: String) {
guard isEnabled else { return }
managers.forEach { manager in
manager.logScreen(name: name, path: path)
}
}
private func logEvent(name: String) {
guard isEnabled else { return }
managers.forEach { manager in
manager.logEvent(name: name)
}
}
// MARK: - section_one
func logScreenS1DefOne() {
logScreen(name: "s1 def one", path: "s1_def_one/")
}
func logEventS1DefTwo() {
logEvent(name: "s1 def two")
}
// MARK: - section_two
func logScreenS2DefOne() {
logScreen(name: "s2 def one", path: "s2_def_one/")
}
}
"""
if extensionContent != expect {
print(prettyFirstDifferenceBetweenStrings(s1: extensionContent, s2: expect))
}
XCTAssertEqual(extensionContent.adaptForXCTest(), expect.adaptForXCTest())
}
func testGeneratedExtensionContentMatomo() {
// Given
let sectionOne = TagSection(name: "section_one")
sectionOne.definitions = [
getTagDefinition(title: "s1_def_one", path: "s1_def_one/", name: "s1 def one", type: "screen", tags: ["ios", "iosonly"]),
getTagDefinition(title: "s1_def_two", path: "s1_def_two/", name: "s1 def two", type: "event", tags: ["ios", "iosonly"]),
]
let sectionTwo = TagSection(name: "section_two")
sectionTwo.definitions = [
getTagDefinition(title: "s2_def_one", path: "s2_def_one/", name: "s2 def one", type: "screen", tags: ["ios","iosonly"]),
getTagDefinition(title: "s2_def_two", path: "s2_def_two/", name: "s2 def two", type: "event", tags: ["droid","droidonly"]),
]
let sectionThree = TagSection(name: "section_three")
sectionThree.definitions = [
getTagDefinition(title: "s3_def_one", path: "s3_def_one/", name: "s3 def one", type: "screen", tags: ["droid","droidonly"]),
getTagDefinition(title: "s3_def_two", path: "s3_def_two/", name: "s3 def two", type: "event", tags: ["droid","droidonly"]),
]
// When
TagsGenerator.targets = [Tags.TargetType.matomo]
let extensionContent = TagsGenerator.getExtensionContent(sections: [sectionOne, sectionTwo, sectionThree],
tags: ["ios", "iosonly"],
staticVar: false,
extensionName: "GenTags")
// Expect Tags
let expect = """
// Generated by ResgenSwift.Tags 1.2
import UIKit
import MatomoTracker
// MARK: - Protocol
protocol AnalyticsManagerProtocol {
func logScreen(name: String, path: String)
func logEvent(name: String)
}
// MARK: - Matomo
class MatomoAnalyticsManager: AnalyticsManagerProtocol {
// MARK: - Properties
private var tracker: MatomoTracker
// MARK: - Init
init(siteId: String, url: String) {
debugPrint("[Matomo service] Server URL: \\(url)")
debugPrint("[Matomo service] Site ID: \\(siteId)")
tracker = MatomoTracker(siteId: siteId, baseURL: URL(string: url)!)
#if DEBUG
tracker.dispatchInterval = 5
#endif
#if DEBUG
tracker.logger = DefaultLogger(minLevel: .verbose)
#endif
debugPrint("[Matomo service] Configured with content base: \\(tracker.contentBase?.absoluteString ?? "-")")
debugPrint("[Matomo service] Opt out: \\(tracker.isOptedOut)")
}
// MARK: - Methods
func logScreen(name: String, path: String) {
guard !tracker.isOptedOut else { return }
guard let trackerUrl = tracker.contentBase?.absoluteString else { return }
let urlString = URL(string: "\\(trackerUrl)" + "/" + "\\(path)" + "iOS")
tracker.track(
view: [name],
url: urlString
)
}
func logEvent(name: String) {
guard !tracker.isOptedOut else { return }
tracker.track(
eventWithCategory: "category",
action: "action",
name: name,
number: nil,
url: nil
)
}
}
// MARK: - Manager
class AnalyticsManager {
static var shared = AnalyticsManager()
// MARK: - Properties
var managers: [AnalyticsManagerProtocol] = []
private var isEnabled: Bool = true
// MARK: - Methods
func setAnalyticsEnabled(_ enable: Bool) { isEnabled = enable }
func configure(siteId: String, url: String) {
managers.append(MatomoAnalyticsManager(siteId: siteId, url: url))
}
private func logScreen(name: String, path: String) {
guard isEnabled else { return }
managers.forEach { manager in
manager.logScreen(name: name, path: path)
}
}
private func logEvent(name: String) {
guard isEnabled else { return }
managers.forEach { manager in
manager.logEvent(name: name)
}
}
// MARK: - section_one
func logScreenS1DefOne() {
logScreen(name: "s1 def one", path: "s1_def_one/")
}
func logEventS1DefTwo() {
logEvent(name: "s1 def two")
}
// MARK: - section_two
func logScreenS2DefOne() {
logScreen(name: "s2 def one", path: "s2_def_one/")
}
}
"""
if extensionContent != expect {
print(prettyFirstDifferenceBetweenStrings(s1: extensionContent, s2: expect))
}
XCTAssertEqual(extensionContent.adaptForXCTest(), expect.adaptForXCTest())
}
func testGeneratedExtensionContentMatomoAndFirebase() {
// Given
let sectionOne = TagSection(name: "section_one")
sectionOne.definitions = [
getTagDefinition(title: "s1_def_one", path: "s1_def_one/", name: "s1 def one", type: "screen", tags: ["ios", "iosonly"]),
getTagDefinition(title: "s1_def_two", path: "s1_def_two/", name: "s1 def two", type: "event", tags: ["ios", "iosonly"]),
]
let sectionTwo = TagSection(name: "section_two")
sectionTwo.definitions = [
getTagDefinition(title: "s2_def_one", path: "s2_def_one/", name: "s2 def one", type: "screen", tags: ["ios","iosonly"]),
getTagDefinition(title: "s2_def_two", path: "s2_def_two/", name: "s2 def two", type: "event", tags: ["droid","droidonly"]),
]
let sectionThree = TagSection(name: "section_three")
sectionThree.definitions = [
getTagDefinition(title: "s3_def_one", path: "s3_def_one/", name: "s3 def one", type: "screen", tags: ["droid","droidonly"]),
getTagDefinition(title: "s3_def_two", path: "s3_def_two/", name: "s3 def two", type: "event", tags: ["droid","droidonly"]),
]
// When
TagsGenerator.targets = [Tags.TargetType.matomo, Tags.TargetType.firebase]
let extensionContent = TagsGenerator.getExtensionContent(sections: [sectionOne, sectionTwo, sectionThree],
tags: ["ios", "iosonly"],
staticVar: false,
extensionName: "GenTags")
// Expect Tags
let expect = """
// Generated by ResgenSwift.Tags 1.2
import UIKit
import MatomoTracker
import Firebase
// MARK: - Protocol
protocol AnalyticsManagerProtocol {
func logScreen(name: String, path: String)
func logEvent(name: String)
}
// MARK: - Matomo
class MatomoAnalyticsManager: AnalyticsManagerProtocol {
// MARK: - Properties
private var tracker: MatomoTracker
// MARK: - Init
init(siteId: String, url: String) {
debugPrint("[Matomo service] Server URL: \\(url)")
debugPrint("[Matomo service] Site ID: \\(siteId)")
tracker = MatomoTracker(siteId: siteId, baseURL: URL(string: url)!)
#if DEBUG
tracker.dispatchInterval = 5
#endif
#if DEBUG
tracker.logger = DefaultLogger(minLevel: .verbose)
#endif
debugPrint("[Matomo service] Configured with content base: \\(tracker.contentBase?.absoluteString ?? "-")")
debugPrint("[Matomo service] Opt out: \\(tracker.isOptedOut)")
}
// MARK: - Methods
func logScreen(name: String, path: String) {
guard !tracker.isOptedOut else { return }
guard let trackerUrl = tracker.contentBase?.absoluteString else { return }
let urlString = URL(string: "\\(trackerUrl)" + "/" + "\\(path)" + "iOS")
tracker.track(
view: [name],
url: urlString
)
}
func logEvent(name: String) {
guard !tracker.isOptedOut else { return }
tracker.track(
eventWithCategory: "category",
action: "action",
name: name,
number: nil,
url: nil
)
}
}
// MARK: - Firebase
class FirebaseAnalyticsManager: AnalyticsManagerProtocol {
func logScreen(name: String, path: String) {
Analytics.logEvent(AnalyticsEventScreenView, parameters: [AnalyticsParameterScreenName: name])
}
func logEvent(name: String) {
var parameters = [
AnalyticsParameterValue: name
]
Analytics.logEvent(AnalyticsEventSelectContent, parameters: parameters)
}
}
// MARK: - Manager
class AnalyticsManager {
static var shared = AnalyticsManager()
// MARK: - Properties
var managers: [AnalyticsManagerProtocol] = []
private var isEnabled: Bool = true
// MARK: - Methods
func setAnalyticsEnabled(_ enable: Bool) { isEnabled = enable }
func configure(siteId: String, url: String) {
managers.append(MatomoAnalyticsManager(siteId: siteId, url: url))
managers.append(FirebaseAnalyticsManager())
}
private func logScreen(name: String, path: String) {
guard isEnabled else { return }
managers.forEach { manager in
manager.logScreen(name: name, path: path)
}
}
private func logEvent(name: String) {
guard isEnabled else { return }
managers.forEach { manager in
manager.logEvent(name: name)
}
}
// MARK: - section_one
func logScreenS1DefOne() {
logScreen(name: "s1 def one", path: "s1_def_one/")
}
func logEventS1DefTwo() {
logEvent(name: "s1 def two")
}
// MARK: - section_two
func logScreenS2DefOne() {
logScreen(name: "s2 def one", path: "s2_def_one/")
}
}
"""
if extensionContent != expect {
print(prettyFirstDifferenceBetweenStrings(s1: extensionContent, s2: expect))
}
XCTAssertEqual(extensionContent.adaptForXCTest(), expect.adaptForXCTest())
}
}