mvcgen 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +115 -0
- data/bin/mvcgen +9 -0
- data/lib/mvcgen.rb +6 -0
- data/lib/mvcgen/dirutils.rb +17 -0
- data/lib/mvcgen/filemanager.rb +51 -0
- data/lib/mvcgen/generator.rb +58 -0
- data/lib/mvcgen/mvcthor.rb +19 -0
- data/lib/mvcgen/templatemanager.rb +53 -0
- data/lib/mvcgen/version.rb +4 -0
- data/lib/templates/default/mvcspec.yml +4 -0
- data/lib/templates/default/objc/DataManager/VIPERDataManager.h +15 -0
- data/lib/templates/default/objc/DataManager/VIPERDataManager.m +11 -0
- data/lib/templates/default/objc/Interactor/VIPERInteractor.h +16 -0
- data/lib/templates/default/objc/Interactor/VIPERInteractor.m +10 -0
- data/lib/templates/default/objc/Presenter/VIPERPresenter.h +18 -0
- data/lib/templates/default/objc/Presenter/VIPERPresenter.m +11 -0
- data/lib/templates/default/objc/Protocols/VIPERProtocols.h +64 -0
- data/lib/templates/default/objc/ViewController/VIPERViewController.h +13 -0
- data/lib/templates/default/objc/ViewController/VIPERViewController.m +32 -0
- data/lib/templates/default/objc/WireFrame/VIPERWireFrame.h +19 -0
- data/lib/templates/default/objc/WireFrame/VIPERWireFrame.m +31 -0
- data/lib/templates/default/swift/Config/Config.plist +58 -0
- data/lib/templates/default/swift/Config/Config.swift +50 -0
- data/lib/templates/default/swift/Extensions/Buttons.swift +110 -0
- data/lib/templates/default/swift/Extensions/ColorHex.swift +32 -0
- data/lib/templates/default/swift/Helper/APIHelper.swift +98 -0
- data/lib/templates/default/swift/Helper/APIManager.swift +217 -0
- data/lib/templates/default/swift/Helper/APIRequestBody.swift +81 -0
- data/lib/templates/default/swift/Helper/AWSManager.swift +29 -0
- data/lib/templates/default/swift/Helper/FilesManager.swift +97 -0
- data/lib/templates/default/swift/Helper/S3Manager.swift +113 -0
- data/lib/templates/default/swift/Helper/Utils.swift +69 -0
- data/lib/templates/default/swift/Models/Managers/UserManager.swift +56 -0
- data/lib/templates/default/swift/Models/Responses/BaseResponse.swift +75 -0
- data/lib/templates/default/swift/Models/Responses/UserResponse.swift +30 -0
- data/lib/templates/default/swift/Models/Responses/UserSingupResponse.swift +27 -0
- data/lib/templates/default/swift/Models/User.swift +92 -0
- data/spec/mvcgen/mvcgen_spec.rb +131 -0
- data/spec/spec_helper.rb +4 -0
- metadata +159 -0
@@ -0,0 +1,69 @@
|
|
1
|
+
//
|
2
|
+
// Utils.swift
|
3
|
+
// MVCGEN
|
4
|
+
//
|
5
|
+
// Created by Daniel Martinez on 23/7/18.
|
6
|
+
// Copyright © 2018 DanielMartinez. All rights reserved.
|
7
|
+
//
|
8
|
+
|
9
|
+
import UIKit
|
10
|
+
|
11
|
+
// Helper to determine if we're running on simulator or device
|
12
|
+
struct PlatformUtils {
|
13
|
+
static let isSimulator: Bool = {
|
14
|
+
var isSim = false
|
15
|
+
#if arch(i386) || arch(x86_64)
|
16
|
+
isSim = true
|
17
|
+
#endif
|
18
|
+
return isSim
|
19
|
+
}()
|
20
|
+
}
|
21
|
+
|
22
|
+
struct UserDefaultsConstants {
|
23
|
+
static let savedUserKey = "savedUser"
|
24
|
+
static let userAuthTokenKey = "userAuthToken"
|
25
|
+
}
|
26
|
+
|
27
|
+
struct Endpoints {
|
28
|
+
static let login = "login"
|
29
|
+
static let fbLogin = "fb_login"
|
30
|
+
static let logout = "logout"
|
31
|
+
static let signup = "signup"
|
32
|
+
static let forgotPwd = "forgot_pwd"
|
33
|
+
}
|
34
|
+
|
35
|
+
struct Colors {
|
36
|
+
static let firstGradientColor = UIColor(hex: "71F0DF")
|
37
|
+
static let secondGradientColor = UIColor(hex: "397EB7")
|
38
|
+
static let thirdGradientColor = UIColor(hex: "425893")
|
39
|
+
static let firstWhite = UIColor(hex: "EDEFF4")
|
40
|
+
static let secondWhite = UIColor(hex: "EDEFF4")
|
41
|
+
static let thirdWhite = UIColor(hex: "D8D8D9")
|
42
|
+
static let textColor = UIColor(hex: "5DCBCF")
|
43
|
+
}
|
44
|
+
|
45
|
+
struct Fonts {
|
46
|
+
|
47
|
+
static func roboto(type : Int, fontSize: CGFloat) -> UIFont {
|
48
|
+
var fontName = "Roboto"
|
49
|
+
|
50
|
+
switch type {
|
51
|
+
case 1:
|
52
|
+
fontName += "-Thin"
|
53
|
+
case 2:
|
54
|
+
fontName += "-Light"
|
55
|
+
case 3:
|
56
|
+
fontName += "-Medium"
|
57
|
+
case 4:
|
58
|
+
fontName += "-Bold"
|
59
|
+
case 5:
|
60
|
+
fontName += "-Black"
|
61
|
+
default:
|
62
|
+
fontName += "-Regular"
|
63
|
+
}
|
64
|
+
|
65
|
+
guard let font = UIFont(name: fontName, size: fontSize) else { return UIFont.systemFont(ofSize: 17) }
|
66
|
+
|
67
|
+
return font
|
68
|
+
}
|
69
|
+
}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
//
|
2
|
+
// UserManager.swift
|
3
|
+
// MVCGEN
|
4
|
+
//
|
5
|
+
// Created by Daniel Martinez on 23/7/18.
|
6
|
+
// Copyright © 2018 DanielMartinez. All rights reserved.
|
7
|
+
//
|
8
|
+
|
9
|
+
import Foundation
|
10
|
+
|
11
|
+
class UserManager {
|
12
|
+
|
13
|
+
static let sharedInstance = UserManager()
|
14
|
+
|
15
|
+
var user: User?
|
16
|
+
|
17
|
+
func saveUser(newUser: User, withToken token: String) {
|
18
|
+
if let userJSON: Data = try? JSONEncoder().encode(newUser) {
|
19
|
+
self.user = newUser
|
20
|
+
UserDefaults.standard.set(userJSON, forKey: UserDefaultsConstants.savedUserKey)
|
21
|
+
UserDefaults.standard.set(token, forKey: UserDefaultsConstants.userAuthTokenKey)
|
22
|
+
UserDefaults.standard.synchronize()
|
23
|
+
}
|
24
|
+
|
25
|
+
}
|
26
|
+
|
27
|
+
func getUser() -> User? {
|
28
|
+
|
29
|
+
if let userJSON = UserDefaults.standard.data(forKey: UserDefaultsConstants.savedUserKey) {
|
30
|
+
|
31
|
+
if let user = try? JSONDecoder().decode(User.self, from: userJSON) {
|
32
|
+
self.user = user
|
33
|
+
return user
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
self.user = nil
|
38
|
+
return nil
|
39
|
+
}
|
40
|
+
|
41
|
+
func userLoggedIn() -> Bool{
|
42
|
+
guard self.user != nil else {
|
43
|
+
return false
|
44
|
+
}
|
45
|
+
return true
|
46
|
+
|
47
|
+
}
|
48
|
+
|
49
|
+
func removeUser() {
|
50
|
+
self.user = nil
|
51
|
+
UserDefaults.standard.removeObject(forKey: UserDefaultsConstants.savedUserKey)
|
52
|
+
UserDefaults.standard.removeObject(forKey: UserDefaultsConstants.userAuthTokenKey)
|
53
|
+
UserDefaults.standard.synchronize()
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
@@ -0,0 +1,75 @@
|
|
1
|
+
//
|
2
|
+
// BaseResponse.swift
|
3
|
+
// MVCGEN
|
4
|
+
//
|
5
|
+
// Created by Daniel Martinez on 23/7/18.
|
6
|
+
// Copyright © 2018 DanielMartinez. All rights reserved.
|
7
|
+
//
|
8
|
+
|
9
|
+
import ObjectMapper
|
10
|
+
|
11
|
+
class BaseResponse: Mappable {
|
12
|
+
|
13
|
+
var result: Bool = false
|
14
|
+
var needUpdate: Bool = false
|
15
|
+
var errorCode: Int = 0
|
16
|
+
var message: String = ""
|
17
|
+
var showMessage: String = ""
|
18
|
+
|
19
|
+
required init?(map: Map) {
|
20
|
+
|
21
|
+
}
|
22
|
+
|
23
|
+
func mapping(map: Map) {
|
24
|
+
if map.JSON["result"] != nil {
|
25
|
+
result <- map["result"]
|
26
|
+
needUpdate <- map["needUpdate"]
|
27
|
+
errorCode <- map["errorCode"]
|
28
|
+
message <- map["message"]
|
29
|
+
showMessage <- map["showMessage.\(self.getCurrentLocaleCode())"]
|
30
|
+
if showMessage == ""{
|
31
|
+
showMessage <- map["showMessage.EN"]
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
// By default show messages in English
|
37
|
+
func getCurrentLocaleCode() -> String {
|
38
|
+
var locale = "EN"
|
39
|
+
if let currentLocaleCode = NSLocale.current.languageCode {
|
40
|
+
locale = currentLocaleCode.uppercased()
|
41
|
+
}
|
42
|
+
return locale
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
//If codable:
|
47
|
+
|
48
|
+
// struct BaseResponse: Codable {
|
49
|
+
|
50
|
+
// var result: Bool = false
|
51
|
+
// var needUpdate: Bool = false
|
52
|
+
// var errorCode: Int = 0
|
53
|
+
// var message: String = ""
|
54
|
+
// var showMessage: String = ""
|
55
|
+
|
56
|
+
// enum CodingKeys: String, Int, Bool, CodingKey
|
57
|
+
// {
|
58
|
+
// //If you wish to rename a field key:
|
59
|
+
// //case id = "iD"
|
60
|
+
// case result
|
61
|
+
// case needUpdate
|
62
|
+
// case errorCode
|
63
|
+
// case message
|
64
|
+
// case showMessage = "showMessage.\(self.getCurrentLocaleCode())"
|
65
|
+
// }
|
66
|
+
|
67
|
+
// // By default show messages in English
|
68
|
+
// func getCurrentLocaleCode() -> String {
|
69
|
+
// var locale = "EN"
|
70
|
+
// if let currentLocaleCode = NSLocale.current.languageCode {
|
71
|
+
// locale = currentLocaleCode.uppercased()
|
72
|
+
// }
|
73
|
+
// return locale
|
74
|
+
// }
|
75
|
+
// }
|
@@ -0,0 +1,30 @@
|
|
1
|
+
//
|
2
|
+
// UserResponse.swift
|
3
|
+
// MVCGEN
|
4
|
+
//
|
5
|
+
// Created by Daniel Martinez on 23/7/18.
|
6
|
+
// Copyright © 2018 DanielMartinez. All rights reserved.
|
7
|
+
//
|
8
|
+
|
9
|
+
import ObjectMapper
|
10
|
+
|
11
|
+
class UserResponse: BaseResponse {
|
12
|
+
|
13
|
+
var user: User?
|
14
|
+
var token: String?
|
15
|
+
|
16
|
+
required init?(map: Map) {
|
17
|
+
super.init(map: map)
|
18
|
+
}
|
19
|
+
|
20
|
+
override func mapping(map: Map) {
|
21
|
+
super.mapping(map: map)
|
22
|
+
|
23
|
+
if map.JSON["data"] != nil {
|
24
|
+
// TODO: check how do you get user data
|
25
|
+
user <- map["data.user"]
|
26
|
+
token <- map["data.token"]
|
27
|
+
}
|
28
|
+
|
29
|
+
}
|
30
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
//
|
2
|
+
// UserSingupResponse.swift
|
3
|
+
// MVCGEN
|
4
|
+
//
|
5
|
+
// Created by Daniel Martinez on 23/7/18.
|
6
|
+
// Copyright © 2018 DanielMartinez. All rights reserved.
|
7
|
+
//
|
8
|
+
|
9
|
+
import ObjectMapper
|
10
|
+
|
11
|
+
class UserSignupResponse: BaseResponse {
|
12
|
+
|
13
|
+
var user: User?
|
14
|
+
|
15
|
+
required init?(map: Map) {
|
16
|
+
super.init(map: map)
|
17
|
+
}
|
18
|
+
|
19
|
+
override func mapping(map: Map) {
|
20
|
+
super.mapping(map: map)
|
21
|
+
// TODO: check how to get the data
|
22
|
+
if map.JSON["data"] != nil {
|
23
|
+
user <- map["data.user"]
|
24
|
+
}
|
25
|
+
|
26
|
+
}
|
27
|
+
}
|
@@ -0,0 +1,92 @@
|
|
1
|
+
//
|
2
|
+
// User.swift
|
3
|
+
// MVCGEN
|
4
|
+
//
|
5
|
+
// Created by Daniel Martinez on 23/7/18.
|
6
|
+
// Copyright © 2018 DanielMartinez. All rights reserved.
|
7
|
+
//
|
8
|
+
|
9
|
+
import Foundation
|
10
|
+
import ObjectMapper
|
11
|
+
|
12
|
+
class User: NSObject, Mappable, Codable {
|
13
|
+
|
14
|
+
var id: Int = 0
|
15
|
+
var email: String = ""
|
16
|
+
var phone: String = ""
|
17
|
+
var firstname: String = ""
|
18
|
+
var lastname: String = ""
|
19
|
+
|
20
|
+
override init() {
|
21
|
+
super.init()
|
22
|
+
}
|
23
|
+
|
24
|
+
convenience required init?(map: Map) {
|
25
|
+
self.init()
|
26
|
+
}
|
27
|
+
|
28
|
+
func mapping(map: Map) {
|
29
|
+
id <- map["id"]
|
30
|
+
email <- map["email"]
|
31
|
+
phone <- map["phone"]
|
32
|
+
firstname <- map["firstname"]
|
33
|
+
lastname <- map["lastname"]
|
34
|
+
lastname <- map["lastname"]
|
35
|
+
profilePic <- map["profilePic"]
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
//If codable:
|
40
|
+
|
41
|
+
// class User: Codable {
|
42
|
+
|
43
|
+
// var id: Int = 0
|
44
|
+
// var email: String = ""
|
45
|
+
// var phone: String = ""
|
46
|
+
// var firstname: String = ""
|
47
|
+
// var lastname: String = ""
|
48
|
+
|
49
|
+
// enum CodingKeys: String, CodingKey
|
50
|
+
// {
|
51
|
+
// //If you wish to rename a field key:
|
52
|
+
// //case id = "iD"
|
53
|
+
// case id
|
54
|
+
// case email
|
55
|
+
// case phone
|
56
|
+
// case firstname
|
57
|
+
// case lastname
|
58
|
+
// }
|
59
|
+
|
60
|
+
// // To Encode:
|
61
|
+
// // let encodedData = try? JSONEncoder().encode(userObject)
|
62
|
+
|
63
|
+
// // To Decode:
|
64
|
+
// if let jsonData = jsonString.data(using: .utf8)
|
65
|
+
// {
|
66
|
+
// let photoObject = try? JSONDecoder().decode(Photo.self, from: jsonData)
|
67
|
+
// }
|
68
|
+
|
69
|
+
|
70
|
+
// }
|
71
|
+
|
72
|
+
// If you want to customize use this and delete Codable extension from user
|
73
|
+
|
74
|
+
// extension User: Encodable
|
75
|
+
// {
|
76
|
+
// func encode(to encoder: Encoder) throws
|
77
|
+
// {
|
78
|
+
// var container = encoder.container(keyedBy: CodingKeys.self)
|
79
|
+
// try container.encode(firstname, forKey: .firstname)
|
80
|
+
// }
|
81
|
+
// }
|
82
|
+
|
83
|
+
// extension User: Decodable
|
84
|
+
// {
|
85
|
+
// init(from decoder: Decoder) throws
|
86
|
+
// {
|
87
|
+
// let values = try decoder.container(keyedBy: CodingKeys.self)
|
88
|
+
// firstname = try values.decode(String.self, forKey: .firstname)
|
89
|
+
// }
|
90
|
+
// }
|
91
|
+
|
92
|
+
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MVCgen do
|
4
|
+
context "when generating path" do
|
5
|
+
it "should return nil if no valid template" do
|
6
|
+
valid_template = MVCgen::FileManager.is_template_valid("asdgas")
|
7
|
+
expect(valid_template).to be(false)
|
8
|
+
end
|
9
|
+
it "should return nil if no valid language" do
|
10
|
+
valid_template = MVCgen::FileManager.is_template_valid("asdgas")
|
11
|
+
expect(valid_template).to be(false)
|
12
|
+
end
|
13
|
+
it "should return nil if no valid language when getting path" do
|
14
|
+
path = MVCgen::FileManager.path_from("default", "asgass")
|
15
|
+
expect(path).to be(nil)
|
16
|
+
end
|
17
|
+
it "should return nil if no valid template when getting path" do
|
18
|
+
path = MVCgen::FileManager.path_from("asga", "swift")
|
19
|
+
expect(path).to be(nil)
|
20
|
+
end
|
21
|
+
it "should append the name to the given user path" do
|
22
|
+
to_path = MVCgen::FileManager.destination_mvc_path("path/", "pepito")
|
23
|
+
expect(to_path).to eq(File.join(File.expand_path("path/"),"pepito"))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
context "copying a folder to a diferent place" do
|
27
|
+
before (:each) do
|
28
|
+
Dir.mkdir 'foo'
|
29
|
+
Dir.mkdir 'foo/subfoo'
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should copy a given folder properly" do
|
33
|
+
MVCgen::FileManager.copy('foo','test_foo')
|
34
|
+
expect(File.directory?('test_foo/subfoo')).to eq(true)
|
35
|
+
end
|
36
|
+
|
37
|
+
after (:each) do
|
38
|
+
FileUtils.rm_rf('foo')
|
39
|
+
FileUtils.rm_rf('test_foo')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe MVCgen::Generator do
|
45
|
+
context "when renaming file content" do
|
46
|
+
before (:each) do
|
47
|
+
File.open("test.txt", 'w') {|f| f.write("I'm a #{MVCgen::Generator::REPLACEMENT_KEY} file") }
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should rename every MVC word to the given name" do
|
51
|
+
MVCgen::Generator.rename_file_content("test.txt","RENAMED")
|
52
|
+
file = File.open("test.txt", "rb")
|
53
|
+
content = file.read
|
54
|
+
expect(content).to eq("I'm a RENAMED file")
|
55
|
+
end
|
56
|
+
|
57
|
+
after (:each) do
|
58
|
+
FileUtils.rm('test.txt')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when renaming file" do
|
63
|
+
before (:each) do
|
64
|
+
File.open("#{MVCgen::Generator::REPLACEMENT_KEY}test.txt", 'w') {|f| f.write("I'm a #{MVCgen::Generator::REPLACEMENT_KEY} file") }
|
65
|
+
end
|
66
|
+
|
67
|
+
it "every file should be renamed in rename_files" do
|
68
|
+
expect(MVCgen::Generator).to receive(:rename_file)
|
69
|
+
MVCgen::Generator.rename_files(["#{MVCgen::Generator::REPLACEMENT_KEY}file.txt"], "pepito")
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should raise a SyntaxError exeption if there's a file in the template without the proper name" do
|
73
|
+
expect{MVCgen::Generator.rename_files(["asgasgs.txt"], "pepito")}.to raise_error
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should rename the MVC in name to the given name" do
|
77
|
+
file = "#{MVCgen::Generator::REPLACEMENT_KEY}test.txt"
|
78
|
+
name = "RENAMED"
|
79
|
+
MVCgen::Generator.rename_file(file, name)
|
80
|
+
expect(File.exist? "RENAMEDtest.txt").to eq(true)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should rename the file content after the file name rename" do
|
84
|
+
file = "#{MVCgen::Generator::REPLACEMENT_KEY}test.txt"
|
85
|
+
name = "RENAMED"
|
86
|
+
expect(MVCgen::Generator).to receive(:rename_file_content)
|
87
|
+
MVCgen::Generator.rename_file(file, name)
|
88
|
+
end
|
89
|
+
|
90
|
+
after (:each) do
|
91
|
+
File.delete "#{MVCgen::Generator::REPLACEMENT_KEY}test.txt" if File.exist? "#{MVCgen::Generator::REPLACEMENT_KEY}test.txt"
|
92
|
+
File.delete "RENAMEDtest.txt" if File.exist? "RENAMEDtest.txt"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe MVCgen::DirUtils do
|
98
|
+
context "getting directories" do
|
99
|
+
before (:each) do
|
100
|
+
Dir.mkdir 'foo'
|
101
|
+
Dir.mkdir 'foo/subfoo'
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should return the directories inside a given one" do
|
105
|
+
expect(MVCgen::DirUtils.directories_in('foo').count).to eq(1)
|
106
|
+
end
|
107
|
+
|
108
|
+
after (:each) do
|
109
|
+
FileUtils.rm_rf('foo')
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe VipeMVCgenrgen::TemplateManager do
|
115
|
+
context "getting templates" do
|
116
|
+
before (:each) do
|
117
|
+
Dir.mkdir 'foo'
|
118
|
+
Dir.mkdir 'foo/subfoo'
|
119
|
+
Dir.mkdir 'foo/subfoo2'
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should return the proper templates in templates directory" do
|
123
|
+
MVCgen::TemplateManager.stub(:templates_dir).and_return('foo/')
|
124
|
+
expect(MVCgen::TemplateManager.templates_paths.count).to eq(2)
|
125
|
+
end
|
126
|
+
|
127
|
+
after (:each) do
|
128
|
+
FileUtils.rm_rf('foo')
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|