Render data count with closest unit
Set a 10% boundary (e.g. 100MB = 0.1GB).
This commit is contained in:
parent
2e142680c3
commit
921e57557d
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// UtilsTests.swift
|
||||
// Passepartout-CoreTests
|
||||
//
|
||||
// Created by Davide De Rosa on 3/30/19.
|
||||
// Copyright (c) 2019 Davide De Rosa. All rights reserved.
|
||||
//
|
||||
// https://github.com/passepartoutvpn
|
||||
//
|
||||
// This file is part of Passepartout.
|
||||
//
|
||||
// Passepartout is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Passepartout is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import Passepartout_Core
|
||||
|
||||
class UtilsTests: XCTestCase {
|
||||
override func setUp() {
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
func testDataUnitDescription() {
|
||||
XCTAssertEqual(0.dataUnitDescription, "0B")
|
||||
XCTAssertEqual(1.dataUnitDescription, "1B")
|
||||
XCTAssertEqual(1024.dataUnitDescription, "1kB")
|
||||
XCTAssertEqual(1025.dataUnitDescription, "1kB")
|
||||
XCTAssertEqual(548575.dataUnitDescription, "0.52MB")
|
||||
XCTAssertEqual(1048575.dataUnitDescription, "1.00MB")
|
||||
XCTAssertEqual(1048576.dataUnitDescription, "1.00MB")
|
||||
XCTAssertEqual(1048577.dataUnitDescription, "1.00MB")
|
||||
XCTAssertEqual(600000000.dataUnitDescription, "0.56GB")
|
||||
XCTAssertEqual(1073741823.dataUnitDescription, "1.00GB")
|
||||
XCTAssertEqual(1073741824.dataUnitDescription, "1.00GB")
|
||||
XCTAssertEqual(1073741825.dataUnitDescription, "1.00GB")
|
||||
}
|
||||
}
|
|
@ -758,7 +758,7 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
|
|||
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
|
||||
cell.leftText = L10n.Service.Cells.DataCount.caption
|
||||
if let count = currentDataCount, vpn.status == .connected {
|
||||
cell.rightText = "\(count.0)/\(count.1)"
|
||||
cell.rightText = L10n.Service.Cells.DataCount.value(count.0.dataUnitDescription, count.1.dataUnitDescription)
|
||||
} else {
|
||||
cell.rightText = nil
|
||||
}
|
||||
|
|
|
@ -82,6 +82,8 @@
|
|||
0EB60FDA2111136E00AD27F3 /* UITextView+Search.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB60FD92111136E00AD27F3 /* UITextView+Search.swift */; };
|
||||
0EB67D6B2184581E00BA6200 /* ImportedHostsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB67D6A2184581E00BA6200 /* ImportedHostsViewController.swift */; };
|
||||
0EBE3A79213C4E5500BFA2F5 /* OrganizerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EBE3A78213C4E5400BFA2F5 /* OrganizerViewController.swift */; };
|
||||
0ECEB10A224FECEA00E9E551 /* DataUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ECEB109224FECEA00E9E551 /* DataUnit.swift */; };
|
||||
0ECEB10C224FEF9B00E9E551 /* UtilsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ECEB10B224FEF9B00E9E551 /* UtilsTests.swift */; };
|
||||
0ECEE44E20E1122200A6BB43 /* TableModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ECEE44D20E1122200A6BB43 /* TableModel.swift */; };
|
||||
0ECEE45020E1182E00A6BB43 /* Theme+Cells.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ECEE44F20E1182E00A6BB43 /* Theme+Cells.swift */; };
|
||||
0ED31C2920CF2A340027975F /* AccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED31C2820CF2A340027975F /* AccountViewController.swift */; };
|
||||
|
@ -226,6 +228,8 @@
|
|||
0ECEB106224FE51400E9E551 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Organizer.storyboard; sourceTree = "<group>"; };
|
||||
0ECEB107224FE51400E9E551 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Shortcuts.storyboard; sourceTree = "<group>"; };
|
||||
0ECEB108224FE51400E9E551 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
0ECEB109224FECEA00E9E551 /* DataUnit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataUnit.swift; sourceTree = "<group>"; };
|
||||
0ECEB10B224FEF9B00E9E551 /* UtilsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UtilsTests.swift; sourceTree = "<group>"; };
|
||||
0ECEE44D20E1122200A6BB43 /* TableModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableModel.swift; sourceTree = "<group>"; };
|
||||
0ECEE44F20E1182E00A6BB43 /* Theme+Cells.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Theme+Cells.swift"; sourceTree = "<group>"; };
|
||||
0ED31C0F20CF09A30027975F /* Pool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Pool.swift; sourceTree = "<group>"; };
|
||||
|
@ -338,6 +342,7 @@
|
|||
0EBBE8F121822B4D00106008 /* ConnectionService.json */,
|
||||
0EBBE8F021822B4D00106008 /* ConnectionServiceTests.swift */,
|
||||
0ED31C2620CF257C0027975F /* InfrastructureTests.swift */,
|
||||
0ECEB10B224FEF9B00E9E551 /* UtilsTests.swift */,
|
||||
0E3152AC223F9EF500F61841 /* Info.plist */,
|
||||
);
|
||||
path = "Passepartout-CoreTests";
|
||||
|
@ -456,6 +461,7 @@
|
|||
0E2D11B9217DBEDE0096822C /* ConnectionService+Configurations.swift */,
|
||||
0EBBE8F42182361700106008 /* ConnectionService+Migration.swift */,
|
||||
0EDE8DE620C93945004C739C /* Credentials.swift */,
|
||||
0ECEB109224FECEA00E9E551 /* DataUnit.swift */,
|
||||
0EC7F20420E24308004EA58E /* DebugLog.swift */,
|
||||
0ED38AE621404F100004D387 /* EndpointDataSource.swift */,
|
||||
0E89DFC4213DF7AE00741BA1 /* Preferences.swift */,
|
||||
|
@ -942,6 +948,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0E3152BD223FA03D00F61841 /* GroupConstants.swift in Sources */,
|
||||
0ECEB10A224FECEA00E9E551 /* DataUnit.swift in Sources */,
|
||||
0E3152C2223FA04800F61841 /* MockVPNProvider.swift in Sources */,
|
||||
0E3152D2223FA05400F61841 /* DebugLog.swift in Sources */,
|
||||
0E3152C4223FA04800F61841 /* VPN.swift in Sources */,
|
||||
|
@ -986,6 +993,7 @@
|
|||
files = (
|
||||
0E3152BA223F9F3D00F61841 /* InfrastructureTests.swift in Sources */,
|
||||
0E3152B9223F9F3B00F61841 /* ConnectionServiceTests.swift in Sources */,
|
||||
0ECEB10C224FEF9B00E9E551 /* UtilsTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -108,6 +108,7 @@
|
|||
"service.cells.trusted_policy.caption" = "Trust disables VPN";
|
||||
"service.cells.test_connectivity.caption" = "Test connectivity";
|
||||
"service.cells.data_count.caption" = "Exchanged data count";
|
||||
"service.cells.data_count.value" = "%@ / %@";
|
||||
"service.cells.debug_log.caption" = "Debug log";
|
||||
"service.cells.masks_private_data.caption" = "Mask network data";
|
||||
"service.cells.report_issue.caption" = "Report connectivity issue";
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
//
|
||||
// DataUnit.swift
|
||||
// Passepartout
|
||||
//
|
||||
// Created by Davide De Rosa on 3/30/18.
|
||||
// Copyright (c) 2019 Davide De Rosa. All rights reserved.
|
||||
//
|
||||
// https://github.com/passepartoutvpn
|
||||
//
|
||||
// This file is part of Passepartout.
|
||||
//
|
||||
// Passepartout is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Passepartout is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public enum DataUnit: Int, CustomStringConvertible {
|
||||
case byte = 1
|
||||
|
||||
case kilobyte = 1024
|
||||
|
||||
case megabyte = 1048576
|
||||
|
||||
case gigabyte = 1073741824
|
||||
|
||||
fileprivate var showsDecimals: Bool {
|
||||
switch self {
|
||||
case .byte, .kilobyte:
|
||||
return false
|
||||
|
||||
case .megabyte, .gigabyte:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate var boundary: Int {
|
||||
return Int(0.1 * Double(rawValue))
|
||||
}
|
||||
|
||||
// MARK: CustomStringConvertible
|
||||
|
||||
public var description: String {
|
||||
switch self {
|
||||
case .byte:
|
||||
return "B"
|
||||
|
||||
case .kilobyte:
|
||||
return "kB"
|
||||
|
||||
case .megabyte:
|
||||
return "MB"
|
||||
|
||||
case .gigabyte:
|
||||
return "GB"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public extension Int {
|
||||
private static let allUnits: [DataUnit] = [
|
||||
.gigabyte,
|
||||
.megabyte,
|
||||
.kilobyte,
|
||||
.byte
|
||||
]
|
||||
|
||||
var dataUnitDescription: String {
|
||||
if self == 0 {
|
||||
return "0B"
|
||||
}
|
||||
for u in Int.allUnits {
|
||||
if self >= u.boundary {
|
||||
if !u.showsDecimals {
|
||||
return "\(self / u.rawValue)\(u)"
|
||||
}
|
||||
let count = Double(self) / Double(u.rawValue)
|
||||
return String(format: "%.2f%@", count, u.description)
|
||||
}
|
||||
}
|
||||
fatalError("Number is negative")
|
||||
}
|
||||
}
|
|
@ -543,6 +543,10 @@ public enum L10n {
|
|||
public enum DataCount {
|
||||
/// Exchanged data count
|
||||
public static let caption = L10n.tr("Localizable", "service.cells.data_count.caption")
|
||||
/// %@ / %@
|
||||
public static func value(_ p1: String, _ p2: String) -> String {
|
||||
return L10n.tr("Localizable", "service.cells.data_count.value", p1, p2)
|
||||
}
|
||||
}
|
||||
public enum DebugLog {
|
||||
/// Debug log
|
||||
|
|
Loading…
Reference in New Issue