diff --git a/RxExample/RxExample/Examples/Calculator/CalculatorViewController.swift b/RxExample/RxExample/Examples/Calculator/CalculatorViewController.swift index 5b363db2..e5125b79 100644 --- a/RxExample/RxExample/Examples/Calculator/CalculatorViewController.swift +++ b/RxExample/RxExample/Examples/Calculator/CalculatorViewController.swift @@ -1,8 +1,8 @@ // -// Calculator.swift +// CalculatorViewController.swift // RxExample // -// Created by carlos on 4/8/15. +// Created by Carlos GarcĂ­a on 4/8/15. // Copyright (c) 2015 Krunoslav Zaher. All rights reserved. // @@ -14,13 +14,38 @@ import RxCocoa class CalculatorViewController: ViewController { + enum Operator { + case Addition + case Subtraction + case Multiplication + case Division + } + + enum Action { + case Clear + case ChangeSign + case Percent + case Operation(Operator) + case Equal + case AddNumber(Character) + case AddDot + } + + struct CalState { + let previousNumber: String! + let action: Action + let currentNumber: String! + let inScreen: String + let replace: Bool + } + @IBOutlet weak var lastSignLabel: UILabel! @IBOutlet weak var resultLabel: UILabel! @IBOutlet weak var allClearButton: UIButton! @IBOutlet weak var changeSignButton: UIButton! - @IBOutlet weak var moduleButton: UIButton! - + @IBOutlet weak var percentButton: UIButton! + @IBOutlet weak var divideButton: UIButton! @IBOutlet weak var multiplyButton: UIButton! @IBOutlet weak var minusButton: UIButton! @@ -40,33 +65,162 @@ class CalculatorViewController: ViewController { @IBOutlet weak var eightButton: UIButton! @IBOutlet weak var nineButton: UIButton! + let CLEAR_STATE = CalState(previousNumber: nil, action: .Clear, currentNumber: "0", inScreen: "0", replace: true) + + let diposeBag = DisposeBag() + override func viewDidLoad() { - let allClearButtonOble = allClearButton.rx_tap - let changeSignButtonOble = changeSignButton.rx_tap - let moduleButtonOble = moduleButton.rx_tap - - let divideButtonOble = divideButton.rx_tap - let multiplyButtonOble = multiplyButton.rx_tap - let minusButtonOble = minusButton.rx_tap - let plusButtonOble = plusButton.rx_tap - let equalButtonOble = equalButton.rx_tap - - let dotButtonOble = dotButton.rx_tap - - let zeroButtonOble = zeroButton.rx_tap - let oneButtonOble = oneButton.rx_tap - let twoButtonOble = twoButton.rx_tap - let threeButtonOble = threeButton.rx_tap - let fourButtonOble = fourButton.rx_tap - let fiveButtonOble = fiveButton.rx_tap - let sixButtonOble = sixButton.rx_tap - let sevenButtonOble = sevenButton.rx_tap - let eightButtonOble = eightButton.rx_tap - let nineButtonOble = nineButton.rx_tap + let commands: [Observable] = [ + allClearButton.rx_tap >- map { _ in .Clear }, + + changeSignButton.rx_tap >- map { _ in .ChangeSign }, + percentButton.rx_tap >- map { _ in .Percent }, + + divideButton.rx_tap >- map { _ in .Operation(.Division) }, + multiplyButton.rx_tap >- map { _ in .Operation(.Multiplication) }, + minusButton.rx_tap >- map { _ in .Operation(.Subtraction) }, + plusButton.rx_tap >- map { _ in .Operation(.Addition) }, + + equalButton.rx_tap >- map { _ in .Equal }, + + dotButton.rx_tap >- map { _ in .AddDot }, + + zeroButton.rx_tap >- map { _ in .AddNumber("0") }, + oneButton.rx_tap >- map { _ in .AddNumber("1") }, + twoButton.rx_tap >- map { _ in .AddNumber("2") }, + threeButton.rx_tap >- map { _ in .AddNumber("3") }, + fourButton.rx_tap >- map { _ in .AddNumber("4") }, + fiveButton.rx_tap >- map { _ in .AddNumber("5") }, + sixButton.rx_tap >- map { _ in .AddNumber("6") }, + sevenButton.rx_tap >- map { _ in .AddNumber("7") }, + eightButton.rx_tap >- map { _ in .AddNumber("8") }, + nineButton.rx_tap >- map { _ in .AddNumber("9") } + ] + merge(from(commands)) + >- scan(CLEAR_STATE) { a, x in + return self.tranformState(a, x) + } + >- debug("debugging") + >- subscribeNext { [weak self] calState in + self?.resultLabel.text = self?.prettyFormat(calState.inScreen) + switch calState.action { + case .Operation(let operation): + switch operation { + case .Addition: + self?.lastSignLabel.text = "+" + case .Subtraction: + self?.lastSignLabel.text = "-" + case .Multiplication: + self?.lastSignLabel.text = "x" + case .Division: + self?.lastSignLabel.text = "/" + } + default: + self?.lastSignLabel.text = "" + } + } >- diposeBag.addDisposable + } + + func tranformState(a: CalState, _ x: Action) -> CalState { + switch x { + case .Clear: + return CLEAR_STATE + case .AddNumber(let c): + return addNumber(a, c) + case .AddDot: + return addDot(a) + case .ChangeSign: + let d = "\(-a.inScreen.toDouble()!)" + return CalState(previousNumber: a.previousNumber, action: a.action, currentNumber: d, inScreen: d, replace: true) + case .Percent: + let d = "\(a.inScreen.toDouble()!/100)" + return CalState(previousNumber: a.previousNumber, action: a.action, currentNumber: d, inScreen: d, replace: true) + case .Operation(let o): + return performOperation(a, o) + case .Equal: + return performEqual(a) + } + } + + func addNumber(a: CalState, _ char: Character) -> CalState { + let cn = a.currentNumber == nil || a.replace ? String(char) : a.inScreen + String(char) + return CalState(previousNumber: a.previousNumber, action: a.action, currentNumber: cn, inScreen: cn, replace: false) + } + + func addDot(a: CalState) -> CalState { + let cn = a.inScreen.rangeOfString(".") == nil ? a.currentNumber + "." : a.currentNumber + return CalState(previousNumber: a.previousNumber, action: a.action, currentNumber: cn, inScreen: cn, replace: false) + } + + func performOperation(a: CalState, _ o: Operator) -> CalState { + + if a.previousNumber == nil { + return CalState(previousNumber: a.currentNumber, action: .Operation(o), currentNumber: nil, inScreen: a.currentNumber, replace: true) + } + else { + let previous = a.previousNumber.toDouble()! + let current = a.inScreen.toDouble()! + + switch a.action { + case .Operation(let op): + switch op { + case .Addition: + let result = "\(previous + current)" + return CalState(previousNumber: result, action: .Operation(o), currentNumber: nil, inScreen: result, replace: true) + case .Subtraction: + let result = "\(previous - current)" + return CalState(previousNumber: result, action: .Operation(o), currentNumber: nil, inScreen: result, replace: true) + case .Multiplication: + let result = "\(previous * current)" + return CalState(previousNumber: result, action: .Operation(o), currentNumber: nil, inScreen: result, replace: true) + case .Division: + let result = "\(previous / current)" + return CalState(previousNumber: result, action: .Operation(o), currentNumber: nil, inScreen: result, replace: true) + } + default: + return CalState(previousNumber: nil, action: .Operation(o), currentNumber: a.currentNumber, inScreen: a.inScreen, replace: true) + } + + } } + func performEqual(a: CalState) -> CalState { + let previous = (a.previousNumber ?? "0").toDouble() + let current = a.inScreen.toDouble()! + + switch a.action { + case .Operation(let op): + switch op { + case .Addition: + let result = "\(previous! + current)" + return CalState(previousNumber: nil, action: .Clear, currentNumber: result, inScreen: result, replace: true) + case .Subtraction: + let result = "\(previous! - current)" + return CalState(previousNumber: nil, action: .Clear, currentNumber: result, inScreen: result, replace: true) + case .Multiplication: + let result = "\(previous! * current)" + return CalState(previousNumber: nil, action: .Clear, currentNumber: result, inScreen: result, replace: true) + case .Division: + let result = previous! / current + let resultText = result == Double.infinity ? "0" : "\(result)" + return CalState(previousNumber: nil, action: .Clear, currentNumber: resultText, inScreen: resultText, replace: true) + } + default: + return CalState(previousNumber: nil, action: .Clear, currentNumber: a.currentNumber, inScreen: a.inScreen, replace: true) + } + } + + + func prettyFormat(str: String) -> String { + if str.hasSuffix(".0") { + return str.substringToIndex(str.endIndex.predecessor().predecessor()) + } + return str + } } + + diff --git a/RxExample/RxExample/iOS/Main.storyboard b/RxExample/RxExample/iOS/Main.storyboard index 21a256ae..de1ce440 100644 --- a/RxExample/RxExample/iOS/Main.storyboard +++ b/RxExample/RxExample/iOS/Main.storyboard @@ -1,5 +1,5 @@ - + @@ -67,7 +67,7 @@ - + @@ -124,7 +124,7 @@ - + @@ -338,7 +338,7 @@ - + @@ -374,29 +374,6 @@ - - - - - - - - - - - - - @@ -443,6 +420,29 @@ + + + + + + + + + + + + + @@ -560,7 +560,7 @@ This is only showcase app, not intended for production purposes. - + @@ -668,7 +668,7 @@ This is only showcase app, not intended for production purposes. - + @@ -1008,10 +1008,10 @@ This is only showcase app, not intended for production purposes. - + @@ -1023,7 +1023,7 @@ This is only showcase app, not intended for production purposes. - + diff --git a/scripts/automation-tests/01_githubSignUp.js b/scripts/automation-tests/01_githubSignUp.js index 83374dd4..b6f5d848 100644 --- a/scripts/automation-tests/01_githubSignUp.js +++ b/scripts/automation-tests/01_githubSignUp.js @@ -10,7 +10,7 @@ test("----- githubSignUp -----", function (check, pass) { return false; } - UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[0].tapWithOptions({tapOffset:{x:0.24, y:0.20}}); + UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[0].tap(); UIATarget.localTarget().frontMostApp().mainWindow().textFields()[0].tap(); writeInElement(UIATarget.localTarget().frontMostApp().mainWindow().textFields()[0], "rxrevolution") diff --git a/scripts/automation-tests/02_searchWikipedia.js b/scripts/automation-tests/02_searchWikipedia.js index 381300f4..95aed62c 100644 --- a/scripts/automation-tests/02_searchWikipedia.js +++ b/scripts/automation-tests/02_searchWikipedia.js @@ -4,7 +4,7 @@ test("----- searchWikipedia -----", function (check, pass) { var width = UIATarget.localTarget().frontMostApp().mainWindow().rect().size.width - UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[1].tap(); + UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[3].tap(); UIATarget.localTarget().frontMostApp().mainWindow().searchBars()[0].searchBars()[0].tap(); writeInElement(UIATarget.localTarget().frontMostApp().mainWindow().searchBars()[0].searchBars()[0], "banana") diff --git a/scripts/automation-tests/03_masterDetail.js b/scripts/automation-tests/03_masterDetail.js index e8a07772..b2b8f0a6 100644 --- a/scripts/automation-tests/03_masterDetail.js +++ b/scripts/automation-tests/03_masterDetail.js @@ -7,7 +7,7 @@ test("----- masterDetail -----", function (check, pass) { } - UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[2].tapWithOptions({tapOffset:{x:0.24, y:0.20}}); + UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[1].tap(); UIATarget.localTarget().frontMostApp().navigationBar().rightButton().tap(); UIATarget.localTarget().frontMostApp().mainWindow().dragInsideWithOptions({startOffset:{x:0.93, y:yOffset(300)}, endOffset:{x:0.95, y:yOffset(200)}, duration:1.5}); UIATarget.localTarget().frontMostApp().mainWindow().dragInsideWithOptions({startOffset:{x:0.93, y:yOffset(300)}, endOffset:{x:0.95, y:yOffset(100)}, duration:1.5}); diff --git a/scripts/automation-tests/04_controlsTests.js b/scripts/automation-tests/04_controlsTests.js index f03306fc..5e82e0dd 100644 --- a/scripts/automation-tests/04_controlsTests.js +++ b/scripts/automation-tests/04_controlsTests.js @@ -5,7 +5,7 @@ test("----- UIBarButtonItem tap -----", function (check, pass) { - UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[3].tapWithOptions({tapOffset:{x:0.24, y:0.20}}); + UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[4](); UIATarget.localTarget().frontMostApp().navigationBar().rightButton().tap(); @@ -21,7 +21,7 @@ test("----- UIBarButtonItem tap -----", function (check, pass) { test("----- UIBarButtonItem tap -----", function (check, pass) { - UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[3].tapWithOptions({tapOffset:{x:0.24, y:0.20}}); + UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[4](); UIATarget.localTarget().frontMostApp().mainWindow().buttons()["TapMe"].tap(); @@ -39,7 +39,7 @@ test("----- UIBarButtonItem tap -----", function (check, pass) { test("----- UISegmentedControl tap -----", function (check, pass) { - UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[3].tapWithOptions({tapOffset:{x:0.24, y:0.20}}); + UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[4](); UIATarget.localTarget().frontMostApp().mainWindow().segmentedControls()[0].buttons()["Second"].tap(); @@ -63,7 +63,7 @@ test("----- UISegmentedControl tap -----", function (check, pass) { test("----- UISwitch tap -----", function (check, pass) { - UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[3].tapWithOptions({tapOffset:{x:0.24, y:0.20}}); + UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[4](); UIATarget.localTarget().frontMostApp().mainWindow().switches()[0].setValue(0); @@ -87,7 +87,7 @@ test("----- UISwitch tap -----", function (check, pass) { test("----- UITextField text -----", function (check, pass) { - UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[3].tapWithOptions({tapOffset:{x:0.24, y:0.20}}); + UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[4](); UIATarget.localTarget().frontMostApp().mainWindow().textFields()[0].textFields()[0].tap(); // UIATarget.localTarget().frontMostApp().keyboard().typeString("t");// fails if software keyboard is disabled @@ -107,7 +107,7 @@ test("----- UITextField text -----", function (check, pass) { test("----- UISlider value -----", function (check, pass) { - UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[3].tapWithOptions({tapOffset:{x:0.24, y:0.20}}); + UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[4](); UIATarget.localTarget().frontMostApp().mainWindow().sliders()[0].dragToValue(0.00); @@ -124,7 +124,7 @@ test("----- UISlider value -----", function (check, pass) { test("----- UIDatePicker date -----", function (check, pass) { - UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[3].tapWithOptions({tapOffset:{x:0.24, y:0.20}}); + UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[4](); UIATarget.localTarget().frontMostApp().mainWindow().pickers()[0].wheels()[0].tapWithOptions({tapOffset:{x:0.49, y:0.65}}); UIATarget.localTarget().frontMostApp().mainWindow().pickers()[0].wheels()[1].tapWithOptions({tapOffset:{x:0.35, y:0.64}}); @@ -143,7 +143,7 @@ test("----- UIDatePicker date -----", function (check, pass) { test("----- UIActionSheet tap -----", function (check, pass) { - UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[3].tapWithOptions({tapOffset:{x:0.24, y:0.20}}); + UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[4](); UIATarget.localTarget().frontMostApp().mainWindow().buttons()["Open ActionSheet"].tap(); UIATarget.localTarget().frontMostApp().actionSheet().collectionViews()[0].cells()["OK"].buttons()["OK"].tap(); @@ -161,7 +161,7 @@ test("----- UIActionSheet tap -----", function (check, pass) { test("----- UIAlertView tap -----", function (check, pass) { - UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[3].tapWithOptions({tapOffset:{x:0.24, y:0.20}}); + UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[4](); UIATarget.localTarget().onAlert = function(alert){ UIATarget.localTarget().onAlert = null diff --git a/scripts/automation-tests/05_reactivePartialUpdates.js b/scripts/automation-tests/05_reactivePartialUpdates.js index e7da2c19..1186165c 100644 --- a/scripts/automation-tests/05_reactivePartialUpdates.js +++ b/scripts/automation-tests/05_reactivePartialUpdates.js @@ -2,7 +2,7 @@ test("----- reactivePartialUpdates -----", function (check, pass) { - UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[4].tapWithOptions({tapOffset:{x:0.24, y:0.20}}); + UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[5].tap(); UIATarget.localTarget().frontMostApp().navigationBar().rightButton().tap(); UIATarget.localTarget().frontMostApp().navigationBar().rightButton().tap(); UIATarget.localTarget().frontMostApp().navigationBar().rightButton().tap();