diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..a8aae6f
Binary files /dev/null and b/.DS_Store differ
diff --git a/elm-todo/Todo.elm b/elm-todo/Todo.elm
index 3a07b24..117a56e 100755
--- a/elm-todo/Todo.elm
+++ b/elm-todo/Todo.elm
@@ -45,7 +45,6 @@ type alias Model =
type alias Entry =
{ description : String
, completed : Bool
- , editing : Bool
, id : Int
}
@@ -62,7 +61,6 @@ newEntry : String -> Int -> Entry
newEntry desc id =
{ description = desc
, completed = False
- , editing = False
, id = id
}
@@ -76,8 +74,6 @@ to them.
-}
type Msg
= UpdateNewEntryField String
- | EditingEntry Int Bool
- | UpdateEntry Int String
| Add
| Delete Int
| DeleteAllCompleted
@@ -102,29 +98,6 @@ update msg model =
UpdateNewEntryField str ->
{ model | newEntryField = str }
- EditingEntry id isEditing ->
- let
- updateEntry t =
- if t.id == id then
- { t | editing = isEditing }
- else
- t
-
- focus =
- Dom.focus ("todo-" ++ toString id)
- in
- { model | entries = List.map updateEntry model.entries }
-
- UpdateEntry id task ->
- let
- updateEntry t =
- if t.id == id then
- { t | description = task }
- else
- t
- in
- { model | entries = List.map updateEntry model.entries }
-
Check id isCompleted ->
let
updateEntry t =
@@ -229,7 +202,7 @@ viewKeyedEntry todo =
viewEntry : Entry -> Html Msg
viewEntry todo =
li
- [ classList [ ( "completed", todo.completed ), ( "editing", todo.editing ) ] ]
+ [ classList [ ( "completed", todo.completed ) ] ]
[ div
[ class "view" ]
[ input
@@ -239,8 +212,7 @@ viewEntry todo =
, onClick (Check todo.id (not todo.completed))
]
[]
- , label
- [ onDoubleClick (EditingEntry todo.id True) ]
+ , label []
[ text todo.description ]
, button
[ class "destroy"
@@ -253,9 +225,6 @@ viewEntry todo =
, value todo.description
, name "title"
, id ("todo-" ++ toString todo.id)
- , onInput (UpdateEntry todo.id)
- , onBlur (EditingEntry todo.id False)
- , onEnter (EditingEntry todo.id False)
]
[]
]
@@ -313,8 +282,7 @@ viewControlsClear entriesCompleted =
infoFooter : Html msg
infoFooter =
footer [ class "info" ]
- [ p [] [ text "Double-click to edit a todo" ]
- , p []
+ [ p []
[ text "Written by "
, a [ href "https://github.com/evancz" ] [ text "Evan Czaplicki" ]
]
diff --git a/ruby-todo/.DS_Store b/ruby-todo/.DS_Store
new file mode 100644
index 0000000..f278239
Binary files /dev/null and b/ruby-todo/.DS_Store differ
diff --git a/ruby-todo/.idea/.rakeTasks b/ruby-todo/.idea/.rakeTasks
new file mode 100644
index 0000000..54e8039
--- /dev/null
+++ b/ruby-todo/.idea/.rakeTasks
@@ -0,0 +1,7 @@
+
+
diff --git a/ruby-todo/.idea/inspectionProfiles/Project_Default.xml b/ruby-todo/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..b0db9b0
--- /dev/null
+++ b/ruby-todo/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ruby-todo/.idea/misc.xml b/ruby-todo/.idea/misc.xml
new file mode 100644
index 0000000..42cb086
--- /dev/null
+++ b/ruby-todo/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/ruby-todo/.idea/modules.xml b/ruby-todo/.idea/modules.xml
new file mode 100644
index 0000000..f6178b4
--- /dev/null
+++ b/ruby-todo/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ruby-todo/.idea/ruby-todo.iml b/ruby-todo/.idea/ruby-todo.iml
new file mode 100644
index 0000000..6d597c0
--- /dev/null
+++ b/ruby-todo/.idea/ruby-todo.iml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ruby-todo/.idea/workspace.xml b/ruby-todo/.idea/workspace.xml
new file mode 100644
index 0000000..369bff1
--- /dev/null
+++ b/ruby-todo/.idea/workspace.xml
@@ -0,0 +1,430 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ skip
+
+
+
+
+
+
+
+
+ true
+ DEFINITION_ORDER
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1523471496929
+
+
+ 1523471496929
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ruby-todo/lib/engine.rb b/ruby-todo/lib/engine.rb
index a257c20..0c77cf6 100644
--- a/ruby-todo/lib/engine.rb
+++ b/ruby-todo/lib/engine.rb
@@ -4,9 +4,10 @@ def self.run(*args)
end
def self.run_with_history(model, messages)
+ # Messages are things like update, add, delete, check, delete all completed etc
+ # But model is composed of previous entries, an empty entry, and the next entry ID. While entires are ID, Description, Checked
messages.map do |msg|
- msg.apply_to(model)
- model
+ model = msg.apply_to(model)
end
end
end
diff --git a/ruby-todo/lib/messages.rb b/ruby-todo/lib/messages.rb
index abe85de..7447b38 100644
--- a/ruby-todo/lib/messages.rb
+++ b/ruby-todo/lib/messages.rb
@@ -2,13 +2,14 @@ module Msg
class Add
def apply_to(model)
+ new_entries = model.entries.dup
unless model.new_entry_field.blank?
- model.entries << Entry.new(
- description: model.new_entry_field,
- id: model.next_id)
+ new_entries << Entry.new(description: model.new_entry_field, id: model.next_id)
end
- model.next_id += 1
- model.new_entry_field = ""
+ next_id = model.next_id.dup #even need the dup?
+ next_id += 1
+ new_model = Model.new(entries: new_entries, new_entry_field: "", next_id: next_id)
+ return new_model
end
end
@@ -20,7 +21,11 @@ def initialize(str)
attr_reader :str
def apply_to(model)
- model.new_entry_field = str
+ new_entry_field = str
+ entries = model.entries
+ next_id = model.next_id
+ new_model = Model.new(entries: entries, new_entry_field: new_entry_field, next_id: next_id)
+ return new_model
end
end
@@ -32,11 +37,18 @@ def initialize(id, is_completed)
attr_reader :id, :is_completed
def apply_to(model)
- model.entries.each do |entry|
+ entries = model.entries.dup
+ new_entries = []
+ entries.each do |entry|
+ is_completed_val = entry.completed
if entry.id == id
- entry.completed = is_completed
+ is_completed_val = is_completed
end
+ new_entry = Entry.new(id: entry.id, description: entry.description, completed: is_completed_val)
+ new_entries << new_entry
end
+ new_model = Model.new(entries: new_entries, new_entry_field: model.new_entry_field, next_id: model.next_id)
+ return new_model
end
end
@@ -48,13 +60,19 @@ def initialize(id)
attr_reader :id
def apply_to(model)
- model.entries.reject! { |e| e.id == id }
+ entries = model.entries.dup
+ entries.reject! { |e| e.id == id }
+ new_model = Model.new(entries: entries, new_entry_field: model.new_entry_field, next_id: model.next_id)
+ return new_model
end
end
class DeleteAllCompleted
def apply_to(model)
- model.entries.reject!(&:completed)
+ entries = model.entries.dup
+ entries.reject!(&:completed)
+ new_model = Model.new(entries: entries, new_entry_field: model.new_entry_field, next_id: model.next_id)
+ return new_model
end
end
diff --git a/ruby-todo/lib/model.rb b/ruby-todo/lib/model.rb
index 75a6085..e64ca6a 100644
--- a/ruby-todo/lib/model.rb
+++ b/ruby-todo/lib/model.rb
@@ -5,7 +5,7 @@ def initialize(entries: [], new_entry_field: "", next_id: nil)
(entries.lazy.map(&:id).max || -1) + 1
end
- attr_accessor :entries, :new_entry_field, :next_id
+ attr_reader :entries, :new_entry_field, :next_id
def ==(other)
!other.nil? &&
@@ -20,7 +20,7 @@ def initialize(id:, description:, completed: false)
@description, @id, @completed = description, id, completed
end
- attr_accessor :description, :completed, :id
+ attr_reader :description, :completed, :id
def ==(other)
!other.nil? &&
diff --git a/ruby-todo/test/todo_test.rb b/ruby-todo/test/todo_test.rb
index f7436c7..9f07d6e 100644
--- a/ruby-todo/test/todo_test.rb
+++ b/ruby-todo/test/todo_test.rb
@@ -91,7 +91,7 @@
end
it "supports time travel" do
- skip "Mutable model does not support time travel"
+ "Mutable model does not support time travel"
actual_history = Engine.run_with_history(Model.new, [
Msg::UpdateNewEntryField.new("go forward in time"),
diff --git a/swift-todo/Sources/Todo/Engine.swift b/swift-todo/Sources/Todo/Engine.swift
index e3b14a7..49cbb22 100644
--- a/swift-todo/Sources/Todo/Engine.swift
+++ b/swift-todo/Sources/Todo/Engine.swift
@@ -13,9 +13,17 @@ struct Engine {
}
static func runWithHistory(on model: Model, applying messages: [Message]) -> [Model] {
- return messages.map { message in
- message.apply(to: model)
- return model
- }
+ var newModel = model
+// var modelHistory = [Model]()
+// for message in messages{
+// newModel = message.apply(to: newModel)
+// modelHistory.append(newModel)
+// }
+// return modelHistory
+ return messages.map({
+ (message: Message) -> Model in
+ newModel = message.apply(to: newModel)
+ return newModel
+ })
}
}
diff --git a/swift-todo/Sources/Todo/Message.swift b/swift-todo/Sources/Todo/Message.swift
index 92dd868..620a3c8 100644
--- a/swift-todo/Sources/Todo/Message.swift
+++ b/swift-todo/Sources/Todo/Message.swift
@@ -14,30 +14,42 @@ enum Message {
case delete(Int)
case deleteAllCompleted
- func apply(to model: Model) {
+ func apply(to model: Model) -> Model {
switch(self) {
case .add:
+ var entries = model.entries
+ let nextID = model.nextID + 1
if !model.newEntryField.isBlank() {
- model.entries.append(Entry(id: model.nextID, description: model.newEntryField))
+ entries.append(Entry(id: model.nextID, description: model.newEntryField))
}
- model.nextID += 1
- model.newEntryField = ""
-
+ return Model(nextID: nextID, newEntryField: "", entries: entries)
+
case .updateNewEntryField(let str):
- model.newEntryField = str
+ return Model(nextID: model.nextID, newEntryField: str, entries: model.entries)
case .check(let id, let isCompleted):
+ var entries = [Entry]()
for entry in model.entries {
if(entry.id == id) {
- entry.completed = isCompleted
+ entries.append(Entry(id: entry.id, description: entry.description, completed: isCompleted))
+ }
+ else{
+ entries.append(entry)
}
}
-
+ return Model(nextID: model.nextID, newEntryField: model.newEntryField, entries: entries)
+
case .delete(let id):
- model.entries.remove { $0.id == id }
-
+ var newEntries = model.entries
+ newEntries.remove { $0.id == id }
+ return Model(nextID: model.nextID, newEntryField: model.newEntryField, entries: newEntries)
+
case .deleteAllCompleted:
- model.entries.remove { $0.completed }
+ var newEntries = model.entries
+ newEntries.remove{$0.completed}
+ return Model(nextID: model.nextID, newEntryField: model.newEntryField, entries: newEntries)
}
+ // if we do literally nothing, just return the model since nothing should have changed
+ return model
}
}
diff --git a/swift-todo/Sources/Todo/Model.swift b/swift-todo/Sources/Todo/Model.swift
index 1cca801..d50d863 100644
--- a/swift-todo/Sources/Todo/Model.swift
+++ b/swift-todo/Sources/Todo/Model.swift
@@ -1,4 +1,4 @@
-class Model {
+struct Model {
var entries: [Entry]
var newEntryField: String
var nextID: Int
@@ -11,7 +11,7 @@ class Model {
}
}
-class Entry {
+struct Entry {
var id: Int
var description: String
var completed: Bool
diff --git a/swift-todo/Tests/TodoTests/TodoTests.swift b/swift-todo/Tests/TodoTests/TodoTests.swift
index 9220517..194cf56 100644
--- a/swift-todo/Tests/TodoTests/TodoTests.swift
+++ b/swift-todo/Tests/TodoTests/TodoTests.swift
@@ -77,7 +77,7 @@ class TodoTests: XCTestCase {
XCTAssertEqual([11], newModel.entries.map { $0.id })
}
-/*
+
func testTimeTravel() {
let actualHistory = Engine.runWithHistory(on: Model(), applying: [
.updateNewEntryField("go forward in time"),
@@ -145,6 +145,5 @@ class TodoTests: XCTestCase {
XCTAssertEqual(expected, actual, "History mismatch at step \(index)")
}
}
-*/
}